diff --git a/addons/sale/models/sale_order_line.py b/addons/sale/models/sale_order_line.py index 806e3eeb42eff976a1d32029d014b5137c871549..936f3e4715894da44cf6cd18e67373e540398605 100644 --- a/addons/sale/models/sale_order_line.py +++ b/addons/sale/models/sale_order_line.py @@ -993,7 +993,13 @@ class SaleOrderLine(models.Model): % '\n'.join(fields.mapped('field_description')) ) - return super().write(values) + result = super().write(values) + + # Don't recompute the package_id if we are setting the quantity of the items and the quantity of packages + if 'product_uom_qty' in values and 'product_packaging_qty' in values and 'product_packaging_id' not in values: + self.env.remove_to_compute(self._fields['product_packaging_id'], self) + + return result def _get_protected_fields(self): """ Give the fields that should not be modified on a locked SO. diff --git a/addons/sale/tests/test_sale_order.py b/addons/sale/tests/test_sale_order.py index 13a6fce0822658f2257bd8692e3e3daabc2758cf..5a7442859c6599be166e7d1bedf74fd50c4aada2 100644 --- a/addons/sale/tests/test_sale_order.py +++ b/addons/sale/tests/test_sale_order.py @@ -205,6 +205,47 @@ class TestSaleOrder(SaleCommon): so_form.save() self.assertEqual(so.order_line.product_uom_qty, 12) + packaging_pack_of_10 = self.env['product.packaging'].create({ + 'name': "PackOf10", + 'product_id': self.product.id, + 'qty': 10.0, + }) + packaging_pack_of_20 = self.env['product.packaging'].create({ + 'name': "PackOf20", + 'product_id': self.product.id, + 'qty': 20.0, + }) + + so2 = self.env['sale.order'].create({ + 'partner_id': self.partner.id, + }) + so2_form = Form(so2) + with so2_form.order_line.new() as line: + line.product_id = self.product + line.product_uom_qty = 10 + so2_form.save() + self.assertEqual(so2.order_line.product_packaging_id.id, packaging_pack_of_10.id) + self.assertEqual(so2.order_line.product_packaging_qty, 1.0) + + with so2_form.order_line.edit(0) as line: + line.product_packaging_qty = 2 + so2_form.save() + self.assertEqual(so2.order_line.product_uom_qty, 20) + # we should have 2 pack of 10, as we've set the package_qty manually, + # we shouldn't recompute the packaging_id, since the package_qty is protected, + # therefor cannot be recomputed during the same transaction, which could lead + # to an incorrect line like (qty=20,pack_qty=2,pack_id=PackOf20) + self.assertEqual(so2.order_line.product_packaging_qty, 2) + self.assertEqual(so2.order_line.product_packaging_id.id, packaging_pack_of_10.id) + + with so2_form.order_line.edit(0) as line: + line.product_packaging_id = packaging_pack_of_20 + so2_form.save() + self.assertEqual(so2.order_line.product_uom_qty, 20) + # we should have 1 pack of 20, as we've set the package type manually + self.assertEqual(so2.order_line.product_packaging_qty, 1) + self.assertEqual(so2.order_line.product_packaging_id.id, packaging_pack_of_20.id) + def _create_sale_order(self): """Create dummy sale order (without lines)""" return self.env['sale.order'].with_context(