From ec0d5b488245642a9771cf2db0097cfe594d35fc Mon Sep 17 00:00:00 2001 From: William Henrotin Date: Wed, 29 Jan 2020 16:16:40 +0000 Subject: [PATCH] [IMP] mrp: choose operation to consume new product This commit adds the possibility to choose in which operation a new product will be consumed. New product can be added to the production once the manufacturing order is in state draft. Before this commit, the new product was consumed automatically in the last workorder. Task: 2121714 --- addons/mrp/models/mrp_production.py | 18 ++++++++--- addons/mrp/models/stock_move.py | 4 ++- addons/mrp/tests/test_workorder_operation.py | 33 ++++++++++++++++++++ addons/mrp/views/stock_move_views.xml | 3 ++ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 18055c8481d..2387ebc26a6 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -699,12 +699,14 @@ class MrpProduction(models.Model): # one opeation in the routing then it will need all BoM lines. bom_line_ids = self.env['mrp.bom.line'] if len(self.routing_id.operation_ids) == 1: - bom_line_ids = self.bom_id.bom_line_ids + moves_in_first_operation = self.move_raw_ids else: - bom_line_ids = self.bom_id.bom_line_ids.filtered(lambda bl: bl.operation_id == first_operation) - bom_line_ids = bom_line_ids.filtered(lambda bl: not bl._skip_bom_line(self.product_id)) + moves_in_first_operation = self.move_raw_ids.filtered(lambda move: move.operation_id == first_operation) + moves_in_first_operation = moves_in_first_operation.filtered( + lambda move: move.bom_line_id and + not move.bom_line_id._skip_bom_line(self.product_id) + ) - moves_in_first_operation = self.move_raw_ids.filtered(lambda m: m.bom_line_id in bom_line_ids) if all(move.state == 'assigned' for move in moves_in_first_operation): return 'assigned' return 'confirmed' @@ -918,7 +920,13 @@ class MrpProduction(models.Model): workorders[-1]._start_nextworkorder() workorders += workorder - moves_raw = self.move_raw_ids.filtered(lambda move: move.operation_id == operation and move.bom_line_id.bom_id.routing_id == bom.routing_id) + # get the raw moves to attach to this operation + moves_raw = self.env['stock.move'] + for move in self.move_raw_ids: + if move.operation_id == operation and move.bom_line_id.bom_id.routing_id == bom.routing_id: + moves_raw |= move + if move.operation_id == operation and not move.bom_line_id: + moves_raw |= move moves_finished = self.move_finished_ids.filtered(lambda move: move.operation_id == operation) # - Raw moves from a BoM where a routing was set but no operation was precised should diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index 499135b2d4a..d0d9082db22 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -79,7 +79,9 @@ class StockMove(models.Model): consume_unbuild_id = fields.Many2one( 'mrp.unbuild', 'Consumed Disassembly Order', check_company=True) operation_id = fields.Many2one( - 'mrp.routing.workcenter', 'Operation To Consume', check_company=True) # TDE FIXME: naming + 'mrp.routing.workcenter', 'Operation To Consume', check_company=True, + domain="[('routing_id', '=', routing_id), '|', ('company_id', '=', company_id), ('company_id', '=', False)]") + routing_id = fields.Many2one(related='raw_material_production_id.routing_id') workorder_id = fields.Many2one( 'mrp.workorder', 'Work Order To Consume', check_company=True) # Quantities to process, in normalized UoMs diff --git a/addons/mrp/tests/test_workorder_operation.py b/addons/mrp/tests/test_workorder_operation.py index 3f4359e2f0b..a40de34a204 100644 --- a/addons/mrp/tests/test_workorder_operation.py +++ b/addons/mrp/tests/test_workorder_operation.py @@ -1758,3 +1758,36 @@ class TestRoutingAndKits(SavepointCase): wo2.button_start() self.assertEqual(wo2.qty_producing, 10) self.assertEqual(wo2.finished_lot_id, lot1) + + def test_add_move(self): + """ Make a production using multi step routing. Add an additional move + on a specific operation and check that the produce is consumed into the + right workorder. """ + self.bom_finished1.consumption = 'flexible' + add_product = self.env['product.product'].create({ + 'name': 'Additional', + }) + mo_form = Form(self.env['mrp.production']) + mo_form.product_id = self.finished1 + mo_form.bom_id = self.bom_finished1 + mo_form.product_qty = 10.0 + mo = mo_form.save() + + mo_form = Form(mo) + with mo_form.move_raw_ids.new() as move: + move.name = mo.name + move.product_id = add_product + move.product_uom = add_product.uom_id + move.location_id = mo.location_src_id + move.location_dest_id = mo.production_location_id + move.product_uom_qty = 2 + move.operation_id = mo.routing_id.operation_ids[0] + mo = mo_form.save() + self.assertEqual(len(mo.move_raw_ids), 3) + mo.action_confirm() + self.assertEqual(mo.move_raw_ids.mapped('state'), ['confirmed'] * 3) + mo.button_plan() + self.assertEqual(len(mo.workorder_ids), 3) + wo1 = mo.workorder_ids[0] + lines = wo1.raw_workorder_line_ids + self.assertEqual(lines.product_id, add_product) diff --git a/addons/mrp/views/stock_move_views.xml b/addons/mrp/views/stock_move_views.xml index bca9db193e5..db9a89e4461 100644 --- a/addons/mrp/views/stock_move_views.xml +++ b/addons/mrp/views/stock_move_views.xml @@ -29,6 +29,9 @@ / + + +