diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 21238bfe978..786d7c7b951 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -1202,7 +1202,7 @@ class PurchaseOrderLine(models.Model): @api.depends('product_qty', 'product_uom') def _compute_price_unit_and_date_planned_and_name(self): for line in self: - if not line.product_id: + if not line.product_id or line.invoice_lines: continue params = {'order_id': line.order_id} seller = line.product_id._select_seller( diff --git a/addons/purchase/tests/test_purchase_invoice.py b/addons/purchase/tests/test_purchase_invoice.py index c28901d111a..e10c82da363 100644 --- a/addons/purchase/tests/test_purchase_invoice.py +++ b/addons/purchase/tests/test_purchase_invoice.py @@ -457,3 +457,57 @@ class TestPurchaseToInvoice(AccountTestInvoicingCommon): self.assertEqual(line.qty_invoiced, 10) line.qty_received = 15 self.assertEqual(line.qty_invoiced, 10) + + def test_on_change_quantity_price_unit(self): + """ When a user changes the quantity of a product in a purchase order it + should only update the unit price if PO line has no invoice line. """ + + supplierinfo_vals = { + 'partner_id': self.partner_a.id, + 'price': 10.0, + 'min_qty': 1, + "product_id": self.product_order.id, + "product_tmpl_id": self.product_order.product_tmpl_id.id, + } + + supplierinfo = self.env["product.supplierinfo"].create(supplierinfo_vals) + po_form = Form(self.env['purchase.order']) + po_form.partner_id = self.partner_a + with po_form.order_line.new() as po_line_form: + po_line_form.product_id = self.product_order + po_line_form.product_qty = 1 + po = po_form.save() + po_line = po.order_line[0] + + self.assertEqual(10.0, po_line.price_unit, "Unit price should be set to 10.0 for 1 quantity") + + # Ensure price unit is updated when changing quantity on a un-confirmed PO + supplierinfo.write({'min_qty': 2, 'price': 20.0}) + po_line.write({'product_qty': 2}) + self.assertEqual(20.0, po_line.price_unit, "Unit price should be set to 20.0 for 2 quantity") + + po.button_confirm() + + # Ensure price unit is updated when changing quantity on a confirmed PO + supplierinfo.write({'min_qty': 3, 'price': 30.0}) + po_line.write({'product_qty': 3}) + self.assertEqual(30.0, po_line.price_unit, "Unit price should be set to 30.0 for 3 quantity") + + po.action_create_invoice() + + # Ensure price unit is NOT updated when changing quantity on PO confirmed and line linked to an invoice line + supplierinfo.write({'min_qty': 4, 'price': 40.0}) + po_line.write({'product_qty': 4}) + self.assertEqual(30.0, po_line.price_unit, "Unit price should be set to 30.0 for 3 quantity") + + with po_form.order_line.new() as po_line_form: + po_line_form.product_id = self.product_order + po_line_form.product_qty = 1 + po = po_form.save() + po_line = po.order_line[1] + + self.assertEqual(235.0, po_line.price_unit, "Unit price should be reset to 235.0 since the supplier supplies minimum of 4 quantities") + + # Ensure price unit is updated when changing quantity on PO confirmed and line NOT linked to an invoice line + po_line.write({'product_qty': 4}) + self.assertEqual(40.0, po_line.price_unit, "Unit price should be set to 40.0 for 4 quantity")