diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 17e6188d200..897c945c42e 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -1426,7 +1426,8 @@ class MrpProduction(models.Model): moves_to_confirm._action_confirm(merge=False) workorder_to_confirm._action_confirm() # run scheduler for moves forecasted to not have enough in stock - self.move_raw_ids._trigger_scheduler() + ignored_mo_ids = self.env.context.get('ignore_mo_ids', []) + self.move_raw_ids.with_context(ignore_mo_ids=ignored_mo_ids + self.ids)._trigger_scheduler() self.picking_ids.filtered( lambda p: p.state not in ['cancel', 'done']).action_confirm() # Force confirm state only for draft production not for more advanced state like diff --git a/addons/mrp/models/stock_orderpoint.py b/addons/mrp/models/stock_orderpoint.py index 911df09ab21..add2fab48f3 100644 --- a/addons/mrp/models/stock_orderpoint.py +++ b/addons/mrp/models/stock_orderpoint.py @@ -104,7 +104,12 @@ class StockWarehouseOrderpoint(models.Model): bom_manufacture = self.env['mrp.bom']._bom_find(orderpoints_without_kit.product_id, bom_type='normal') bom_manufacture = self.env['mrp.bom'].concat(*bom_manufacture.values()) productions_group = self.env['mrp.production']._read_group( - [('bom_id', 'in', bom_manufacture.ids), ('state', '=', 'draft'), ('orderpoint_id', 'in', orderpoints_without_kit.ids)], + [ + ('bom_id', 'in', bom_manufacture.ids), + ('state', '=', 'draft'), + ('orderpoint_id', 'in', orderpoints_without_kit.ids), + ('id', 'not in', self.env.context.get('ignore_mo_ids', [])), + ], ['orderpoint_id', 'product_uom_id'], ['product_qty:sum']) for orderpoint, uom, product_qty_sum in productions_group: diff --git a/addons/mrp/tests/test_warehouse_multistep_manufacturing.py b/addons/mrp/tests/test_warehouse_multistep_manufacturing.py index 78dc3381cfb..5aac529c194 100644 --- a/addons/mrp/tests/test_warehouse_multistep_manufacturing.py +++ b/addons/mrp/tests/test_warehouse_multistep_manufacturing.py @@ -3,6 +3,7 @@ from odoo.tests import Form, tagged from odoo.addons.mrp.tests.common import TestMrpCommon +from odoo import Command @tagged('post_install', '-at_install') @@ -699,3 +700,113 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon): self.assertEqual(len(mo), 1) self.assertEqual(mo.product_qty, 1.0) self.assertEqual(mo.bom_id, bom_2) + + def test_manufacturing_bom_with_repetitions(self): + """ + Checks that manufacturing orders created to manufacture the components of a BOM + are set with the correct quantities when products appear with repetitions. + - Create 5 products: product 1,2,3,4 (P1,P2,P3 and P4) and a final product (FP) + - Set routes to manifacture on each product + - For P1, P2, P3, P4 add a 0:0 reordering rule. + - Add a BOM for P2 with 1 unit of P1 as components + - Add a BOM for P3 with 1 unit of P2 as components + - Add a BOM for P4 with 1 unit of P3 as components + - Add a BOM for FP with 3 unit of P4 and 2 units of P3 as components + """ + manufacturing_route = self.env['stock.rule'].search([ + ('action', '=', 'manufacture')]).route_id + products = self.env['product.product'].create([ + { + 'name': 'FP', + 'type': 'product', + 'route_ids': manufacturing_route, + }, + { + 'name': 'P1', + 'type': 'product', + 'route_ids': manufacturing_route, + }, + { + 'name': 'P2', + 'type': 'product', + 'route_ids': manufacturing_route, + }, + { + 'name': 'P3', + 'type': 'product', + 'route_ids': manufacturing_route, + }, + { + 'name': 'P4', + 'type': 'product', + 'route_ids': manufacturing_route, + }, + + ]) + self.env['stock.warehouse.orderpoint'].create([ + { + 'name': 'My orderpoint', + 'product_id': i, + 'product_min_qty': 0, + 'product_max_qty': 0, + } for i in products.ids[1:] + ]) + self.env['mrp.bom'].create([ + { + 'product_tmpl_id': products[2].product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': products[2].uom_id.id, + 'type': 'normal', + 'bom_line_ids': [ + Command.create({ + 'product_id': products[1].id, + 'product_qty': 1, + }) + ]}, + { + 'product_tmpl_id': products[3].product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': products[3].uom_id.id, + 'type': 'normal', + 'bom_line_ids': [ + Command.create({ + 'product_id': products[2].id, + 'product_qty': 1, + }) + ]}, + { + 'product_tmpl_id': products[4].product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': products[4].uom_id.id, + 'type': 'normal', + 'bom_line_ids': [ + Command.create({ + 'product_id': products[3].id, + 'product_qty': 1, + }) + ]}, + { + 'product_tmpl_id': products[0].product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': products[0].uom_id.id, + 'type': 'normal', + 'bom_line_ids': [ + Command.create({ + 'product_id': products[4].id, + 'product_qty': 3, + }), + Command.create({ + 'product_id': products[2].id, + 'product_qty': 2, + }), + ]}, + ]) + mo = self.env['mrp.production'].create({ + 'product_id': products[0].id, + 'product_uom_qty': 1, + }) + mo.action_confirm() + mo_P1 = self.env['mrp.production'].search([('product_id', '=', products[1].id)]) + mo_P2 = self.env['mrp.production'].search([('product_id', '=', products[2].id)]) + self.assertEqual(mo_P1.product_uom_qty, 5.0) + self.assertEqual(mo_P2.product_uom_qty, 5.0)