diff --git a/addons/product_margin/models/product_product.py b/addons/product_margin/models/product_product.py index 7c62a8a97aa..59127738157 100644 --- a/addons/product_margin/models/product_product.py +++ b/addons/product_margin/models/product_product.py @@ -3,19 +3,54 @@ import time -from openerp.osv import fields, osv +from odoo import api, fields, models - -class product_product(osv.osv): +class ProductProduct(models.Model): _inherit = "product.product" - def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True): + date_from = fields.Date(compute='_compute_product_margin_fields_values', string='Margin Date From') + date_to = fields.Date(compute='_compute_product_margin_fields_values', string='Margin Date To') + invoice_state = fields.Selection(compute='_compute_product_margin_fields_values', + selection=[ + ('paid', 'Paid'), + ('open_paid', 'Open and Paid'), + ('draft_open_paid', 'Draft, Open and Paid') + ], string='Invoice State', readonly=True) + sale_avg_price = fields.Float(compute='_compute_product_margin_fields_values', string='Avg. Unit Price', + help="Avg. Price in Customer Invoices.") + purchase_avg_price = fields.Float(compute='_compute_product_margin_fields_values', string='Avg. Unit Price', + help="Avg. Price in Vendor Bills ") + sale_num_invoiced = fields.Float(compute='_compute_product_margin_fields_values', string='# Invoiced in Sale', + help="Sum of Quantity in Customer Invoices") + purchase_num_invoiced = fields.Float(compute='_compute_product_margin_fields_values', string='# Invoiced in Purchase', + help="Sum of Quantity in Vendor Bills") + sales_gap = fields.Float(compute='_compute_product_margin_fields_values', string='Sales Gap', + help="Expected Sale - Turn Over") + purchase_gap = fields.Float(compute='_compute_product_margin_fields_values', string='Purchase Gap', + help="Normal Cost - Total Cost") + turnover = fields.Float(compute='_compute_product_margin_fields_values', string='Turnover', + help="Sum of Multiplication of Invoice price and quantity of Customer Invoices") + total_cost = fields.Float(compute='_compute_product_margin_fields_values', string='Total Cost', + help="Sum of Multiplication of Invoice price and quantity of Vendor Bills ") + sale_expected = fields.Float(compute='_compute_product_margin_fields_values', string='Expected Sale', + help="Sum of Multiplication of Sale Catalog price and quantity of Customer Invoices") + normal_cost = fields.Float(compute='_compute_product_margin_fields_values', string='Normal Cost', + help="Sum of Multiplication of Cost price and quantity of Vendor Bills") + total_margin = fields.Float(compute='_compute_product_margin_fields_values', string='Total Margin', + help="Turnover - Standard price") + expected_margin = fields.Float(compute='_compute_product_margin_fields_values', string='Expected Margin', + help="Expected Sale - Normal Cost") + total_margin_rate = fields.Float(compute='_compute_product_margin_fields_values', string='Total Margin Rate(%)', + help="Total margin * 100 / Turnover") + expected_margin_rate = fields.Float(compute='_compute_product_margin_fields_values', string='Expected Margin (%)', + help="Expected margin * 100 / Expected Sale") + + @api.model + def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True): """ Inherit read_group to calculate the sum of the non-stored fields, as it is not automatically done anymore through the XML. """ - res = super(product_product, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby, lazy=lazy) - if context is None: - context = {} + res = super(ProductProduct, self).read_group(fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy) fields_list = ['turnover', 'sale_avg_price', 'sale_purchase_price', 'sale_num_invoiced', 'purchase_num_invoiced', 'sales_gap', 'purchase_gap', 'total_cost', 'sale_expected', 'normal_cost', 'total_margin', 'expected_margin', 'total_margin_rate', 'expected_margin_rate'] @@ -23,16 +58,15 @@ class product_product(osv.osv): # Calculate first for every product in which line it needs to be applied re_ind = 0 prod_re = {} - tot_products = [] + tot_products = self.browse([]) for re in res: if re.get('__domain'): - products = self.search(cr, uid, re['__domain'], context=context) - tot_products += products + products = self.search(re['__domain']) + tot_products |= products for prod in products: prod_re[prod] = re_ind re_ind += 1 - - res_val = self._product_margin(cr, uid, tot_products, [x for x in fields if fields in fields_list], '', context=context) + res_val = tot_products._compute_product_margin_fields_values([x for x in fields if fields in fields_list], '') for key in res_val.keys(): for l in res_val[key].keys(): re = res[prod_re[key]] @@ -42,16 +76,15 @@ class product_product(osv.osv): re[l] = res_val[key][l] return res - def _product_margin(self, cr, uid, ids, field_names, arg, context=None): + def _compute_product_margin_fields_values(self, field_names=None): res = {} - if context is None: - context = {} - - for val in self.browse(cr, uid, ids, context=context): + if field_names is None: + field_names = [] + for val in self: res[val.id] = {} - date_from = context.get('date_from', time.strftime('%Y-01-01')) - date_to = context.get('date_to', time.strftime('%Y-12-31')) - invoice_state = context.get('invoice_state', 'open_paid') + date_from = self.env.context.get('date_from', time.strftime('%Y-01-01')) + date_to = self.env.context.get('date_to', time.strftime('%Y-12-31')) + invoice_state = self.env.context.get('invoice_state', 'open_paid') if 'date_from' in field_names: res[val.id]['date_from'] = date_from if 'date_to' in field_names: @@ -66,13 +99,14 @@ class product_product(osv.osv): states = ('open', 'paid') elif invoice_state == 'draft_open_paid': states = ('draft', 'open', 'paid') - if "force_company" in context: - company_id = context['force_company'] + if "force_company" in self.env.context: + company_id = self.env.context['force_company'] else: - company_id = self.pool.get("res.users").browse(cr, uid, uid, context=context).company_id.id + company_id = self.env.user.company_id.id #Cost price is calculated afterwards as it is a property - sqlstr="""select + sqlstr = """ + select sum(l.price_unit * l.quantity)/sum(nullif(l.quantity,0)) as avg_unit_price, sum(l.quantity) as num_qty, sum(l.quantity * (l.price_subtotal/(nullif(l.quantity,0)))) as total, @@ -84,24 +118,22 @@ class product_product(osv.osv): where l.product_id = %s and i.state in %s and i.type IN %s and (i.date_invoice IS NULL or (i.date_invoice>=%s and i.date_invoice<=%s and i.company_id=%s)) """ invoice_types = ('out_invoice', 'in_refund') - cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to, company_id)) - result = cr.fetchall()[0] + self.env.cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to, company_id)) + result = self.env.cr.fetchall()[0] res[val.id]['sale_avg_price'] = result[0] and result[0] or 0.0 res[val.id]['sale_num_invoiced'] = result[1] and result[1] or 0.0 res[val.id]['turnover'] = result[2] and result[2] or 0.0 res[val.id]['sale_expected'] = result[3] and result[3] or 0.0 - res[val.id]['sales_gap'] = res[val.id]['sale_expected']-res[val.id]['turnover'] - prod_obj = self.pool.get("product.product") - ctx = context.copy() + res[val.id]['sales_gap'] = res[val.id]['sale_expected'] - res[val.id]['turnover'] + ctx = self.env.context.copy() ctx['force_company'] = company_id - prod = prod_obj.browse(cr, uid, val.id, context=ctx) invoice_types = ('in_invoice', 'out_refund') - cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to, company_id)) - result = cr.fetchall()[0] + self.env.cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to, company_id)) + result = self.env.cr.fetchall()[0] res[val.id]['purchase_avg_price'] = result[0] and result[0] or 0.0 res[val.id]['purchase_num_invoiced'] = result[1] and result[1] or 0.0 res[val.id]['total_cost'] = result[2] and result[2] or 0.0 - res[val.id]['normal_cost'] = prod.standard_price * res[val.id]['purchase_num_invoiced'] + res[val.id]['normal_cost'] = val.standard_price * res[val.id]['purchase_num_invoiced'] res[val.id]['purchase_gap'] = res[val.id]['normal_cost'] - res[val.id]['total_cost'] if 'total_margin' in field_names: @@ -113,39 +145,3 @@ class product_product(osv.osv): if 'expected_margin_rate' in field_names: res[val.id]['expected_margin_rate'] = res[val.id]['sale_expected'] and res[val.id]['expected_margin'] * 100 / res[val.id]['sale_expected'] or 0.0 return res - - _columns = { - 'date_from': fields.function(_product_margin, type='date', string='Margin Date From', multi='product_margin'), - 'date_to': fields.function(_product_margin, type='date', string='Margin Date To', multi='product_margin'), - 'invoice_state': fields.function(_product_margin, type='selection', selection=[ - ('paid','Paid'),('open_paid','Open and Paid'),('draft_open_paid','Draft, Open and Paid') - ], string='Invoice State',multi='product_margin', readonly=True), - 'sale_avg_price' : fields.function(_product_margin, type='float', string='Avg. Unit Price', multi='product_margin', - help="Avg. Price in Customer Invoices."), - 'purchase_avg_price' : fields.function(_product_margin, type='float', string='Avg. Unit Price', multi='product_margin', - help="Avg. Price in Vendor Bills "), - 'sale_num_invoiced' : fields.function(_product_margin, type='float', string='# Invoiced in Sale', multi='product_margin', - help="Sum of Quantity in Customer Invoices"), - 'purchase_num_invoiced' : fields.function(_product_margin, type='float', string='# Invoiced in Purchase', multi='product_margin', - help="Sum of Quantity in Vendor Bills"), - 'sales_gap' : fields.function(_product_margin, type='float', string='Sales Gap', multi='product_margin', - help="Expected Sale - Turn Over"), - 'purchase_gap' : fields.function(_product_margin, type='float', string='Purchase Gap', multi='product_margin', - help="Normal Cost - Total Cost"), - 'turnover' : fields.function(_product_margin, type='float', string='Turnover' ,multi='product_margin', - help="Sum of Multiplication of Invoice price and quantity of Customer Invoices"), - 'total_cost' : fields.function(_product_margin, type='float', string='Total Cost', multi='product_margin', - help="Sum of Multiplication of Invoice price and quantity of Vendor Bills "), - 'sale_expected' : fields.function(_product_margin, type='float', string='Expected Sale', multi='product_margin', - help="Sum of Multiplication of Sale Catalog price and quantity of Customer Invoices"), - 'normal_cost' : fields.function(_product_margin, type='float', string='Normal Cost', multi='product_margin', - help="Sum of Multiplication of Cost price and quantity of Vendor Bills"), - 'total_margin' : fields.function(_product_margin, type='float', string='Total Margin', multi='product_margin', - help="Turnover - Standard price"), - 'expected_margin' : fields.function(_product_margin, type='float', string='Expected Margin', multi='product_margin', - help="Expected Sale - Normal Cost"), - 'total_margin_rate' : fields.function(_product_margin, type='float', string='Total Margin Rate(%)', multi='product_margin', - help="Total margin * 100 / Turnover"), - 'expected_margin_rate' : fields.function(_product_margin, type='float', string='Expected Margin (%)', multi='product_margin', - help="Expected margin * 100 / Expected Sale"), - } diff --git a/addons/product_margin/views/product_product_views.xml b/addons/product_margin/views/product_product_views.xml index 9b4eede75a4..74fee03222a 100644 --- a/addons/product_margin/views/product_product_views.xml +++ b/addons/product_margin/views/product_product_views.xml @@ -1,6 +1,5 @@ - - + product.margin.graph product.product @@ -88,5 +87,4 @@ - - + diff --git a/addons/product_margin/wizard/product_margin.py b/addons/product_margin/wizard/product_margin.py index 0372b704f30..dba552e6a32 100644 --- a/addons/product_margin/wizard/product_margin.py +++ b/addons/product_margin/wizard/product_margin.py @@ -3,59 +3,43 @@ import time -from openerp.osv import fields, osv +from odoo import api, fields, models from openerp.tools.translate import _ -class product_margin(osv.osv_memory): +class ProductMargin(models.TransientModel): _name = 'product.margin' _description = 'Product Margin' - _columns = { - 'from_date': fields.date('From'), - 'to_date': fields.date('To'), - 'invoice_state': fields.selection([ - ('paid', 'Paid'), - ('open_paid', 'Open and Paid'), - ('draft_open_paid', 'Draft, Open and Paid'), - ], 'Invoice State', select=True, required=True), - } - _defaults = { - 'from_date': time.strftime('%Y-01-01'), - 'to_date': time.strftime('%Y-12-31'), - 'invoice_state': "open_paid", - } + from_date = fields.Date('From', default=time.strftime('%Y-01-01')) + to_date = fields.Date('To', default=time.strftime('%Y-12-31')) + invoice_state = fields.Selection([ + ('paid', 'Paid'), + ('open_paid', 'Open and Paid'), + ('draft_open_paid', 'Draft, Open and Paid'), + ], 'Invoice State', index=True, required=True, default="open_paid") - def action_open_window(self, cr, uid, ids, context=None): - """ - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: the ID or list of IDs if we want more than one - - @return: - """ - context = dict(context or {}) + @api.multi + def action_open_window(self): + self.ensure_one() + context = dict(self.env.context or {}) def ref(module, xml_id): - proxy = self.pool.get('ir.model.data') - return proxy.get_object_reference(cr, uid, module, xml_id) + proxy = self.env['ir.model.data'] + return proxy.get_object_reference(module, xml_id) model, search_view_id = ref('product', 'product_search_form_view') model, graph_view_id = ref('product_margin', 'view_product_margin_graph') model, form_view_id = ref('product_margin', 'view_product_margin_form') model, tree_view_id = ref('product_margin', 'view_product_margin_tree') - #get the current product.margin object to obtain the values from it - records = self.browse(cr, uid, ids, context=context) - record = records[0] + context.update(invoice_state=self.invoice_state) - context.update(invoice_state=record.invoice_state) + if self.from_date: + context.update(date_from=self.from_date) - if record.from_date: - context.update(date_from=record.from_date) - - if record.to_date: - context.update(date_to=record.to_date) + if self.to_date: + context.update(date_to=self.to_date) views = [ (tree_view_id, 'tree'), diff --git a/addons/product_margin/wizard/product_margin_view.xml b/addons/product_margin/wizard/product_margin_view.xml index ecdc36352e6..689021f99fa 100644 --- a/addons/product_margin/wizard/product_margin_view.xml +++ b/addons/product_margin/wizard/product_margin_view.xml @@ -1,6 +1,5 @@ - - + product.margin.form product.margin @@ -27,5 +26,4 @@ key2="client_action_multi" id="product_margin_act_window"/> - - +