1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2013 Mentis d.o.o. (<http://www.mentis.si/openerp>)
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU Affero General Public License as
9
# published by the Free Software Foundation, either version 3 of the
10
# License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Affero General Public License for more details.
17
# You should have received a copy of the GNU Affero General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
##############################################################################
22
from osv import fields, osv
23
from tools.translate import _
24
from datetime import datetime
26
import openerp.addons.decimal_precision as dp
28
class account_product_cost_recalculation(osv.osv_memory):
29
_name="account.product.cost.recalculation"
30
_description="Recalculate Product Costs"
33
'calculation_type': fields.selection([('average','Average Price'),('weighted','Weighted Average Price')], 'Calculation Type', required=True,
34
help="Average price: The cost is recomputed accoring to each incoming shipment. \nWeighted Average Price: The cost price is recalculated for whole period."),
35
'period_id': fields.many2one('account.period', "Period", required=False,
36
help="Period for which recalculation will be done. If not set recalculation will be done for whole fiscal year."),
37
'product_id': fields.many2one('product.product', "Product", domain=[('cost_method','=','average')], required=False,
38
help="Product for which recalculation will be done. If not set recalculation will be done for all products with cost method set 'Average Price'"),
39
'method': fields.selection([('cr','SQL statements'),('orm','ORM methods')], 'Calculation Method', required=True)
42
'calculation_type': 'weighted',
48
def _do_recalculation(self, cr, uid, ids, context=None):
51
_recalc_id = self.browse(cr, uid, ids[0], context)
55
# najdem ustrezna obdobja
56
if _recalc_id.period_id:
57
_period_id = _recalc_id.period_id
59
_period_obj = self.pool.get('account.period').find(cr, uid)
61
_period_id = self.pool.get('account.period').browse(cr, uid, _period_obj[0])
64
raise osv.except_osv(_('Error!'), _('Cannot find suitable dates for recalculation.'))
66
_year_start = _period_id.fiscalyear_id.date_start
67
_date_from = _period_id.date_start
68
_date_to = _period_id.date_stop
70
# najdem ustrezne izdelke
73
if _recalc_id.product_id:
74
_product_ids.append(_recalc_id.product_id.id)
76
cr.execute("""SELECT sm.product_id AS id
78
INNER JOIN product_template AS pt ON pt.id = sm.product_id
79
AND pt.cost_method = 'average'
80
INNER JOIN stock_location AS sl_src ON sl_src.id = sm.location_id
81
AND sl_src.usage = 'internal'
82
INNER JOIN stock_location AS sl_dest ON sl_dest.id = sm.location_dest_id
83
AND sl_dest.usage <> 'internal'
86
GROUP BY sm.product_id
87
ORDER BY sm.product_id""", (_date_from, _date_to))
88
_products_tup = cr.fetchall()
89
for _tup in _products_tup:
90
_product_ids.append(_tup[0])
92
# preračunam posamezen izdelek
93
_products = self.pool.get('product.product').browse(cr, uid, _product_ids, context)
94
for _product in _products:
96
# izračunam začetno zalogo in ceno
97
_dates['date_from'] = _year_start
98
_dates['date_to'] = _date_from
99
_start_stock, _start_cost = _product._get_stock_and_cost(_dates)
100
if _start_stock == 0.0:
103
# izračunam povprečno ceno za obdobje
104
_dates['date_from'] = _date_from
105
_dates['date_to'] = _date_to
106
_period_stock, _period_cost = _product._get_purchase_amount_and_cost(_dates)
108
# izračunam skupno vrednost zaloge konec obdobja
109
_end_period_stock = _start_stock + _period_stock
110
_end_period_cost = (_start_stock * _start_cost) + _period_cost
112
# izračunam povprečno ceno za obdobje
113
_period_average = False
114
if _end_period_stock and _end_period_stock <> 0:
115
_period_average = _end_period_cost / _end_period_stock
117
# posodobim vrednosti prodaje na povprečno ceno za obdobje
118
if _period_average and _period_average <> 0:
119
if _recalc_id.method == 'orm':
120
_product._set_period_cost_orm(_dates, _period_average)
122
_product._set_period_cost_cr(_dates, _period_average)
128
def execute(self, cr, uid, ids, context=None):
131
if self._do_recalculation(cr, uid, ids, context):
132
return {'type': 'ir.actions.act_window_close'}
137
account_product_cost_recalculation()
b'\\ No newline at end of file'