~matjaz-6/openerpsl/openerpsl_01_25

« back to all changes in this revision

Viewing changes to purchase_recalculation/wizard/account_product_cost_recalculation.py

  • Committer: Aleksander Dirntiš
  • Date: 2013-09-26 08:37:54 UTC
  • mto: This revision was merged to the branch mainline in revision 141.
  • Revision ID: sandi.dirntis@mentis.si-20130926083754-9xyz03rbypbtrhgd
[MOD] Module purchase_recalculation: added wizard for cost price recalculation

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2013 Mentis d.o.o. (<http://www.mentis.si/openerp>)
 
6
#
 
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.
 
11
#
 
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.
 
16
#
 
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/>.
 
19
#
 
20
##############################################################################
 
21
 
 
22
from osv import fields, osv
 
23
from tools.translate import _
 
24
from datetime import datetime
 
25
import time
 
26
import openerp.addons.decimal_precision as dp
 
27
 
 
28
class account_product_cost_recalculation(osv.osv_memory):
 
29
    _name="account.product.cost.recalculation"
 
30
    _description="Recalculate Product Costs"
 
31
    
 
32
    _columns={
 
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)
 
40
    }
 
41
    _defaults={
 
42
        'calculation_type': 'weighted',
 
43
        'period_id': False,
 
44
        'product_id': False,
 
45
        'method': 'cr'
 
46
    }
 
47
    
 
48
    def _do_recalculation(self, cr, uid, ids, context=None):
 
49
        print datetime.now()
 
50
        
 
51
        _recalc_id = self.browse(cr, uid, ids[0], context)
 
52
        _period_id = False
 
53
        _dates = {}
 
54
 
 
55
        # najdem ustrezna obdobja
 
56
        if _recalc_id.period_id:
 
57
            _period_id = _recalc_id.period_id
 
58
        else:
 
59
            _period_obj = self.pool.get('account.period').find(cr, uid)
 
60
            if _period_obj:
 
61
                _period_id = self.pool.get('account.period').browse(cr, uid, _period_obj[0])
 
62
 
 
63
        if not _period_id:
 
64
            raise osv.except_osv(_('Error!'), _('Cannot find suitable dates for recalculation.'))
 
65
        
 
66
        _year_start = _period_id.fiscalyear_id.date_start
 
67
        _date_from = _period_id.date_start
 
68
        _date_to = _period_id.date_stop
 
69
            
 
70
        # najdem ustrezne izdelke
 
71
        _product_ids = []
 
72
        
 
73
        if _recalc_id.product_id:
 
74
            _product_ids.append(_recalc_id.product_id.id)
 
75
        else:
 
76
            cr.execute("""SELECT sm.product_id AS id
 
77
                            FROM stock_move AS sm
 
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'
 
84
                           WHERE sm.date >= %s 
 
85
                                 AND sm.date <= %s
 
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])
 
91
 
 
92
        # preračunam posamezen izdelek
 
93
        _products = self.pool.get('product.product').browse(cr, uid, _product_ids, context)
 
94
        for _product in _products:
 
95
            
 
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:
 
101
                _start_cost = 0.0
 
102
 
 
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)
 
107
 
 
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
 
111
 
 
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
 
116
 
 
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)
 
121
                else:
 
122
                    _product._set_period_cost_cr(_dates, _period_average)
 
123
 
 
124
        print datetime.now()
 
125
 
 
126
        return True
 
127
    
 
128
    def execute(self, cr, uid, ids, context=None):
 
129
        if context is None:
 
130
            context = {}
 
131
        if self._do_recalculation(cr, uid, ids, context):
 
132
            return {'type': 'ir.actions.act_window_close'}
 
133
        else:
 
134
            return False
 
135
 
 
136
 
 
137
account_product_cost_recalculation()
 
 
b'\\ No newline at end of file'