From 16f698f6be1e9d20b8232900a8990f5383875c8b Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Thu, 25 Feb 2016 13:44:25 +0100 Subject: [PATCH] [FIX] sale_margin, delivery: margin at creation The `purchase_price` is filled in automatically thanks to the onchange method `product_id_change_margin`. However, when a SO is created programatically, it is necessary to call manually the method in order to fill in the field. This is not convenient since the module sale_margin might not be installed, and crappy workaround (such as the use of `hasattr`) are necessary. To avoid this, this fix automatically computes the purchase price at creation if no value is provided. --- addons/delivery/models/sale_order.py | 5 --- addons/sale_margin/sale_margin.py | 39 +++++++++++++++------- addons/sale_mrp/tests/test_move_explode.py | 4 +-- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py index 233723ce712..dd9459b38bf 100644 --- a/addons/delivery/models/sale_order.py +++ b/addons/delivery/models/sale_order.py @@ -93,11 +93,6 @@ class SaleOrder(models.Model): if self.order_line: values['sequence'] = self.order_line[-1].sequence + 1 sol = SaleOrderLine.create(values) - if hasattr(sol, 'product_id_change_margin'): - # if `sale_margin` module is installed, force computation of field `purchase_price` - # As there is not dependency between modules (nor a bridge module), this is the only - # place we can get the value for this field - sol.product_id_change_margin() return sol diff --git a/addons/sale_margin/sale_margin.py b/addons/sale_margin/sale_margin.py index 12398dce41e..a585821a32d 100644 --- a/addons/sale_margin/sale_margin.py +++ b/addons/sale_margin/sale_margin.py @@ -7,20 +7,35 @@ import openerp.addons.decimal_precision as dp class sale_order_line(osv.osv): _inherit = "sale.order.line" - @api.multi + def _compute_margin(self, order_id, product_id, product_uom_id): + frm_cur = self.env.user.company_id.currency_id + to_cur = order_id.pricelist_id.currency_id + purchase_price = product_id.standard_price + if product_uom_id != product_id.uom_id: + purchase_price = self.env['product.uom']._compute_price(product_id.uom_id.id, purchase_price, to_uom_id=product_uom_id.id) + ctx = self.env.context.copy() + ctx['date'] = order_id.date_order + price = frm_cur.with_context(ctx).compute(purchase_price, to_cur, round=False) + return price + @api.onchange('product_id', 'product_uom') def product_id_change_margin(self): - for line in self: - if line.order_id.pricelist_id: - frm_cur = self.env.user.company_id.currency_id - to_cur = line.order_id.pricelist_id.currency_id - purchase_price = line.product_id.standard_price - if line.product_uom != line.product_id.uom_id: - purchase_price = self.env['product.uom']._compute_price(line.product_id.uom_id.id, purchase_price, to_uom_id=line.product_uom.id) - ctx = self.env.context.copy() - ctx['date'] = line.order_id.date_order - price = frm_cur.with_context(ctx).compute(purchase_price, to_cur, round=False) - line.purchase_price = price + if not self.order_id.pricelist_id or not self.product_id or not self.product_uom: + return + self.purchase_price = self._compute_margin(self.order_id, self.product_id, self.product_uom) + + @api.model + def create(self, vals): + # Calculation of the margin for programmatic creation of a SO line. It is therefore not + # necessary to call product_id_change_margin manually + if 'purchase_price' not in vals: + order_id = self.env['sale.order'].browse(vals['order_id']) + product_id = self.env['product.product'].browse(vals['product_id']) + product_uom_id = self.env['product.uom'].browse(vals['product_uom']) + + vals['purchase_price'] = self._compute_margin(order_id, product_id, product_uom_id) + + return super(sale_order_line, self).create(vals) def _product_margin(self, cr, uid, ids, field_name, arg, context=None): cur_obj = self.pool.get('res.currency') diff --git a/addons/sale_mrp/tests/test_move_explode.py b/addons/sale_mrp/tests/test_move_explode.py index a7e3bdea946..84a13aff959 100644 --- a/addons/sale_mrp/tests/test_move_explode.py +++ b/addons/sale_mrp/tests/test_move_explode.py @@ -48,7 +48,7 @@ class TestMoveExplode(common.TransactionCase): 'partner_shipping_id': self.partner.id, 'pricelist_id': self.pricelist.id, } - self.so = self.SaleOrder.create(vals=so_vals) + self.so = self.SaleOrder.create(so_vals) sol_vals = { 'order_id': self.so.id, 'name': self.product_bom.name, @@ -56,7 +56,7 @@ class TestMoveExplode(common.TransactionCase): 'product_uom': self.product_bom.uom_id.id, 'product_uom_qty': 1.0, } - self.SaleOrderLine.create(values=sol_vals) + self.SaleOrderLine.create(sol_vals) #confirm sale order self.so.action_confirm() #get all move associated to that sale_order