From 97f92890583f0adbc1e6dfde26683c240f7eb199 Mon Sep 17 00:00:00 2001 From: "Touati Djamel (otd)" Date: Mon, 27 Mar 2023 13:16:16 +0000 Subject: [PATCH] [FIX] mrp: wrong BoM from orderpoint in 3 steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: - Go to the warehouse settings: - enable “3 steps for manufacturing” - Create a storable product “P1” with 2 BoM - Create an orderpoint: - Preferred route: Manufacturing - Product: “P1” - BoM: select the second BoM - To order: 1 - Click on the “Order once” button Problem: The manufacturing order is created with the first BoM instead of the second. As we are in 3 steps, the “run_pull” function is triggered first, with values prepared from the orderpoint so the bom is well set: https://github.com/odoo/odoo/blob/16.0/addons/stock/models/stock_orderpoint.py#L515-L523 Then the “run_manufacture” function is triggered but with vals prepared from the move, not from the orderpoint, so we lose the BoM information that the user has selected: https://github.com/odoo/odoo/blob/16.0/addons/stock/models/stock_move.py#L1334-L1340 opw-3217945 closes odoo/odoo#117732 X-original-commit: 2371cd29e1c0cfa54b682b2100b9db7f5633a7b4 Signed-off-by: Djamel Touati (otd) Signed-off-by: Tiffany Chang --- addons/mrp/models/stock_rule.py | 2 + .../test_warehouse_multistep_manufacturing.py | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/addons/mrp/models/stock_rule.py b/addons/mrp/models/stock_rule.py index 50d70b9b491..b3651ec1292 100644 --- a/addons/mrp/models/stock_rule.py +++ b/addons/mrp/models/stock_rule.py @@ -141,6 +141,8 @@ class StockRule(models.Model): def _get_matching_bom(self, product_id, company_id, values): if values.get('bom_id', False): return values['bom_id'] + if values.get('orderpoint_id', False) and values['orderpoint_id'].bom_id: + return values['orderpoint_id'].bom_id return self.env['mrp.bom']._bom_find(product_id, picking_type=self.picking_type_id, bom_type='normal', company_id=company_id.id)[product_id] def _prepare_mo_vals(self, product_id, product_qty, product_uom, location_dest_id, name, origin, company_id, values, bom): diff --git a/addons/mrp/tests/test_warehouse_multistep_manufacturing.py b/addons/mrp/tests/test_warehouse_multistep_manufacturing.py index 4abcd0382dd..62f6ef8b904 100644 --- a/addons/mrp/tests/test_warehouse_multistep_manufacturing.py +++ b/addons/mrp/tests/test_warehouse_multistep_manufacturing.py @@ -654,3 +654,45 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon): "The default source location of the merged mo should be the same as the 1st of the original MOs") self.assertEqual(picking_type, mo.picking_type_id, "The operation type of the merged mo should be the same as the 1st of the original MOs") + + def test_manufacturing_bom_from_reordering_rules(self): + """ + Check that the manufacturing order is created with the BoM set in the reording rule: + - Create a product with 2 bill of materials, + - Create an orderpoint for this product specifying the 2nd BoM that must be used, + - Check that the MO has been created with the 2nd BoM + """ + manufacturing_route = self.env['stock.rule'].search([ + ('action', '=', 'manufacture')]).route_id + with Form(self.warehouse) as warehouse: + warehouse.manufacture_steps = 'pbm_sam' + finished_product = self.env['product.product'].create({ + 'name': 'Product', + 'type': 'product', + 'route_ids': manufacturing_route, + }) + self.env['mrp.bom'].create({ + 'product_tmpl_id': finished_product.product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': finished_product.uom_id.id, + 'type': 'normal', + }) + bom_2 = self.env['mrp.bom'].create({ + 'product_tmpl_id': finished_product.product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': finished_product.uom_id.id, + 'type': 'normal', + }) + self.env['stock.warehouse.orderpoint'].create({ + 'name': 'Orderpoint for P1', + 'product_id': self.finished_product.id, + 'product_min_qty': 1, + 'product_max_qty': 1, + 'route_id': manufacturing_route.id, + 'bom_id': bom_2.id, + }) + self.env['procurement.group'].run_scheduler() + mo = self.env['mrp.production'].search([('product_id', '=', self.finished_product.id)]) + self.assertEqual(len(mo), 1) + self.assertEqual(mo.product_qty, 1.0) + self.assertEqual(mo.bom_id, bom_2)