From 741d2fe9efff6529eda0f516754639edcf4a7a35 Mon Sep 17 00:00:00 2001 From: roen-odoo Date: Wed, 9 Mar 2022 08:43:25 +0000 Subject: [PATCH] [FIX] mrp, sale_mrp: Avoid merging stock move different bom_line_id Current behavior: When using a product kit that have a product kit in his BoM some move line where merging when they shouldn't. Because of this the delivered count wasn't correctly updated in any sale order using this product Steps to reproduce: - Create product B to manufacture with a BoM (type Kit) using component A and component B - Create product A to manufacture with a BoM (type Kit) using product B and component A - Create a sale order with product A - Confirm the sale order and validate the delivery - The delivered count of product A on the sale order stays at 0 opw-2777810 closes odoo/odoo#87000 X-original-commit: 0e6480811e2144a1034f1347a816a0bd052c4516 Signed-off-by: Tiffany Chang Signed-off-by: Engels Robin (roen) --- addons/mrp/models/stock_move.py | 2 +- .../sale_mrp/tests/test_sale_mrp_kit_bom.py | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index d4e0ca36d5b..88ed820261a 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -438,7 +438,7 @@ class StockMove(models.Model): @api.model def _prepare_merge_moves_distinct_fields(self): - return super()._prepare_merge_moves_distinct_fields() + ['created_production_id', 'cost_share'] + return super()._prepare_merge_moves_distinct_fields() + ['created_production_id', 'cost_share', 'bom_line_id'] @api.model def _prepare_merge_negative_moves_excluded_distinct_fields(self): diff --git a/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py b/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py index b09c0d6a829..cfa1486c3ef 100644 --- a/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py +++ b/addons/sale_mrp/tests/test_sale_mrp_kit_bom.py @@ -344,3 +344,69 @@ class TestSaleMrpKitBom(TransactionCase): # Checks the delivery amount (must be 10). self.assertEqual(so.order_line.qty_delivered, 10) + + def test_qty_delivered_with_bom_using_kit(self): + """Check the quantity delivered, when one product is a kit + and his bom uses another product that is also a kit""" + + self.kitA = self._create_product('Kit A', 'consu', 0.00) + self.kitB = self._create_product('Kit B', 'consu', 0.00) + self.compA = self._create_product('ComponentA', 'consu', 0.00) + self.compB = self._create_product('ComponentB', 'consu', 0.00) + + # Create BoM for KitB + bom_product_formA = Form(self.env['mrp.bom']) + bom_product_formA.product_id = self.kitB + bom_product_formA.product_tmpl_id = self.kitB.product_tmpl_id + bom_product_formA.product_qty = 1.0 + bom_product_formA.type = 'phantom' + with bom_product_formA.bom_line_ids.new() as bom_line: + bom_line.product_id = self.compA + bom_line.product_qty = 1 + with bom_product_formA.bom_line_ids.new() as bom_line: + bom_line.product_id = self.compB + bom_line.product_qty = 1 + self.bomA = bom_product_formA.save() + + # Create BoM for KitA + bom_product_formB = Form(self.env['mrp.bom']) + bom_product_formB.product_id = self.kitA + bom_product_formB.product_tmpl_id = self.kitA.product_tmpl_id + bom_product_formB.product_qty = 1.0 + bom_product_formB.type = 'phantom' + with bom_product_formB.bom_line_ids.new() as bom_line: + bom_line.product_id = self.compA + bom_line.product_qty = 1 + with bom_product_formB.bom_line_ids.new() as bom_line: + bom_line.product_id = self.kitB + bom_line.product_qty = 1 + self.bomB = bom_product_formB.save() + + self.customer = self.env['res.partner'].create({ + 'name': 'customer', + }) + + so = self.env['sale.order'].create({ + 'partner_id': self.customer.id, + 'order_line': [ + (0, 0, { + 'name': self.kitA.name, + 'product_id': self.kitA.id, + 'product_uom_qty': 1.0, + 'product_uom': self.kitA.uom_id.id, + 'price_unit': 1, + 'tax_id': False, + })], + }) + so.action_confirm() + + self.assertTrue(so.picking_ids) + self.assertEqual(so.order_line.qty_delivered, 0) + + picking = so.picking_ids + action = picking.button_validate() + wizard = Form(self.env[action['res_model']].with_context(action['context'])).save() + wizard.process() + + # Checks the delivery amount (must be 1). + self.assertEqual(so.order_line.qty_delivered, 1)