Changes in function for Invoice State and Start & End Dates
[odoo/odoo.git] / addons / product_margin / product_margin.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 # Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
5 #
6 # $Id: partner.py 1007 2005-07-25 13:18:09Z kayhman $
7 #
8 # WARNING: This program as such is intended to be used by professional
9 # programmers who take the whole responsability of assessing all potential
10 # consequences resulting from its eventual inadequacies and bugs
11 # End users who are looking for a ready-to-use solution with commercial
12 # garantees and support are strongly adviced to contract a Free Software
13 # Service Company
14 #
15 # This program is Free Software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public License
17 # as published by the Free Software Foundation; either version 2
18 # of the License, or (at your option) any later version.
19 #
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28 #
29 ##############################################################################
30
31 from osv import fields,osv
32 import pooler
33 from tools import config
34 import time
35
36 class product_product(osv.osv):
37     _inherit = "product.product"
38     
39     def _get_date(self, cr, uid, ids, field_names, arg, context):
40         res = {}
41         mapping = {
42                    'date_start' : '%Y-01-01',
43                    'date_stop' : '%Y-12-31',
44                    }
45         for val in self.browse(cr, uid, ids):
46             res[val.id] = {}
47             fmt = ' , '.join(map(lambda x: mapping[x], field_names))
48             date = context.get(field_names[0],time.strftime(fmt))
49             res[val.id][field_names[0]] = date
50         return res
51
52
53     def _get_invoice_state(self, cr, uid, ids, field_names, arg, context):
54         res = {}
55         state=  context.get('invoice_state', 'open')
56         for val in self.browse(cr, uid, ids):
57             res[val.id] = state
58         return res
59
60     def get_avg_price_margin(self, cr, uid, ids, field_names, arg, context):
61         res = {}
62         mapping = {
63                    'sale_avg_price' : 'out_invoice',
64                    'purchase_avg_price' : 'in_invoice',
65                    }
66         for val in self.browse(cr, uid, ids):
67             res[val.id] = {}
68             map_val = ' , '.join(map(lambda x: mapping[x], field_names))
69             avg=0.0
70             cr.execute("select avg(l.price_unit) from account_invoice_line l left join account_invoice i on (l.invoice_id = i.id) where l.product_id = %s AND i.type= %s" , (val.id,map_val,))
71             avg = cr.fetchall()[0][0]
72             if not avg:
73                 avg=0.0
74             res[val.id][field_names[0]] = avg
75         return res
76     
77     def _get_num_invoiced(self, cr, uid, ids, field_names, arg, context):
78         res = {}
79         mapping = {
80                    'sale_num_invoiced' : 'out_invoice',
81                    'purchase_num_invoiced' : 'in_invoice',
82                    }
83         for val in self.browse(cr, uid, ids):
84             res[val.id] = {}
85             map_val = ' , '.join(map(lambda x: mapping[x], field_names))
86             avg=0.0
87             cr.execute("select sum(l.quantity) from account_invoice_line l left join account_invoice i on (l.invoice_id = i.id) where l.product_id = %s AND i.state not in ('draft','cancel') AND i.type= %s" , (val.id,map_val,))
88             avg = cr.fetchall()[0][0]
89             res[val.id][field_names[0]] = avg
90         return res
91     
92     def _get_expected(self, cr, uid, ids, field_names, arg, context):
93         res = {}
94         mapping = {
95                    'sale_expected' : 'sale_order_line',
96                    'normal_cost' : 'purchase_order_line',
97                    }
98         mapping1 = {
99                    'sale_expected' : 'product_uom_qty',
100                    'normal_cost' : 'product_qty',
101                    }
102         
103         for val in self.browse(cr, uid, ids):
104             res[val.id] = {}
105             map_val = ' , '.join(map(lambda x: mapping1[x], field_names))
106             cr.execute("select sum(l."+map_val +" * l.price_unit) from " +\
107             ' , '.join(map(lambda x: mapping[x], field_names)) + " l where l.product_id = %s " , (val.id,))
108             ret = cr.fetchall()[0][0]
109             if not ret:
110                 ret=0.0
111             res[val.id][field_names[0]] = ret
112         return res
113     
114     
115     def _get_turnover(self, cr, uid, ids, field_names, arg, context):
116         res = {}
117         mapping = {
118                    'turnover' : 'out_invoice',
119                    'total_cost' : 'in_invoice',
120                    }
121         for val in self.browse(cr, uid, ids):
122             res[val.id] = {}
123             map_val = ' , '.join(map(lambda x: mapping[x], field_names))
124             cr.execute("select sum(l.quantity * l.price_unit) from account_invoice_line l left join account_invoice i on (l.invoice_id = i.id) where l.product_id = %s AND i.state not in ('draft','cancel') AND i.type= %s " , (val.id,map_val))
125             turnover = cr.fetchall()[0][0]
126             res[val.id][field_names[0]]= turnover
127         return res
128     
129     def _get_gap(self, cr, uid, ids, field_names, arg, context):
130         res = {}
131         for val in self.browse(cr, uid, ids):
132             res[val.id] = {}
133             if field_names[0] == 'sales_gap' :
134                 res[val.id][field_names[0]] = val.sale_expected - val.turnover
135             elif field_names[0] == 'purchase_gap' :
136                 res[val.id][field_names[0]] = val.normal_cost - val.total_cost
137         return res
138     
139     
140     def _get_total_margin(self, cr, uid, ids, field_names, arg, context):
141         res = {}
142         for val in self.browse(cr, uid, ids):
143             mapping = {
144                    'total_margin' : val.turnover - val.total_cost,
145                    'expected_margin' : val.sale_expected - val.normal_cost,
146                    }
147             res[val.id] = {}
148             res[val.id][field_names[0]] = mapping[field_names[0]]
149         return res
150     
151     def _get_total_margin_rate(self, cr, uid, ids, field_names, arg, context):
152         res = {}
153         for val in self.browse(cr, uid, ids):
154             if not val.turnover:
155                 val.turnover = 1
156             if not val.sale_expected: 
157                 val.sale_expected=1
158             mapping = {
159                    'total_margin_rate' : (val.total_margin * 100 ) / val.turnover ,
160                    'expected_margin_rate' : (val.expected_margin * 100 ) / val.sale_expected,
161                    }
162             res[val.id] = {}
163             res[val.id][field_names[0]] = mapping[field_names[0]]
164         return res
165     
166     _columns = {
167         'date_start': fields.function(_get_date, method=True, type='date', string='Start Date', multi='date_start'),
168         'date_stop': fields.function(_get_date, method=True, type='date', string='Stop Date', multi='date_stop'),
169         'invoice_state': fields.function(_get_invoice_state, method=True, type='char', string='Invoice State'),
170 #        'invoice_state': fields.selection(_get_invoice_state, string= 'Invoice State'),# readonly=True),
171         'sale_avg_price' : fields.function(get_avg_price_margin, method=True, type='float', string='Avg. Unit Price', multi='sale_avg_price'),
172         'purchase_avg_price' : fields.function(get_avg_price_margin, method=True, type='float', string='Avg. Unit Price', multi='purchase_avg_price'),
173         'sale_num_invoiced' : fields.function(_get_num_invoiced, method=True, type='float', string='# Invoiced', multi='sale_num_invoiced'),
174         'purchase_num_invoiced' : fields.function(_get_num_invoiced, method=True, type='float', string='# Invoiced', multi='purchase_num_invoiced'),
175         'sales_gap' : fields.function(_get_gap, method=True, type='float', string='Sales Gap', multi='sales_gap'),
176         'purchase_gap' : fields.function(_get_gap, method=True, type='float', string='Purchase Gap', multi='purchase_gap'),
177         'turnover' : fields.function(_get_turnover, method=True, type='float', string='Turnover' ,multi='turnover'),
178         'total_cost'  : fields.function(_get_turnover, method=True, type='float', string='Total Cost', multi='total_cost'),
179         'sale_expected' :  fields.function(_get_expected, method=True, type='float', string='Expected Sale', multi='sale_expected'),
180         'normal_cost'  : fields.function(_get_expected, method=True, type='float', string='Normal Cost', multi='normal_cost'),
181         'total_margin' : fields.function(_get_total_margin, method=True, type='float', string='Total Margin', multi='total_margin'),
182         'expected_margin' : fields.function(_get_total_margin, method=True, type='float', string='Expected Margin', multi='expected_margin'),
183         'total_margin_rate' : fields.function(_get_total_margin_rate, method=True, type='float', string='Total Margin (%)', multi='total_margin_rate'),
184         'expected_margin_rate' : fields.function(_get_total_margin_rate, method=True, type='float', string='Expected Margin (%)', multi='expected_margin_rate'),
185     }
186     
187 product_product()
188
189
190 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
191