From 20a82cf35a2eebdbd8f324c161fbe47d484b67a8 Mon Sep 17 00:00:00 2001 From: "Guillaume (guva)" Date: Tue, 6 Jul 2021 07:44:22 +0000 Subject: [PATCH] [FIX] mrp : MO set to close before finished Step to reproduce : - Create a Manufacturing Order for several pieces of a product with a work center routing - Open the Work Order which has been created - The Manufacturing Order is set to 'to close', instead of 'in progess' Cause of the issue The state of the MO was never computed based on WO status. Solution The state of a MO is set to 'to close' when a WO is set as 'done' or 'cancel' opw-2584446 closes odoo/odoo#74411 X-original-commit: c237c9c3214b58d303a8597df2c836872c5e522c Signed-off-by: Simon Goffin (sig) Signed-off-by: guva-odoo --- addons/mrp/models/mrp_production.py | 4 +- addons/mrp/tests/test_order.py | 135 ++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 294db037e37..0d99e4c4ee7 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -441,7 +441,9 @@ class MrpProduction(models.Model): production.state = 'cancel' elif production.state == 'done' or (production.move_raw_ids and all(move.state in ('cancel', 'done') for move in production.move_raw_ids)): production.state = 'done' - elif production.qty_producing >= production.product_qty: + elif production.workorder_ids and all(wo_state in ('done', 'cancel') for wo_state in production.workorder_ids.mapped('state')): + production.state = 'to_close' + elif not production.workorder_ids and production.qty_producing >= production.product_qty: production.state = 'to_close' elif any(wo_state in ('progress', 'done') for wo_state in production.workorder_ids.mapped('state')): production.state = 'progress' diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 959adaae46c..69025da0e64 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -1994,3 +1994,138 @@ class TestMrpOrder(TestMrpCommon): self.assertEqual(len(move_lines_1), 2) self.assertEqual(len(move_lines_2), 2) self.assertEqual(len(move_lines_3), 2) + + def test_manufacturing_order_with_work_orders(self): + """Test the behavior of a manufacturing order when opening the workorder related to it, + as well as the behavior when a backorder is created + """ + + # create a few work centers + + work_center_1 = self.env['mrp.workcenter'].create({"name": "WC1"}) + + work_center_2 = self.env['mrp.workcenter'].create({"name": "WC2"}) + + work_center_3 = self.env['mrp.workcenter'].create({"name": "WC3"}) + + # create a product, a bom related to it with 3 components and 3 operations + + product = self.env['product.template'].create({"name": "Product"}) + + component_1 = self.env['product.template'].create({"name": "Component 1", "type": "product"}) + + self.env['stock.quant'].create({ + "product_id": component_1.product_variant_id.id, + "location_id": 8, + "quantity": 100 + }) + + component_2 = self.env['product.template'].create({"name": "Component 2", "type": "product"}) + + self.env['stock.quant'].create({ + "product_id": component_2.product_variant_id.id, + "location_id": 8, + "quantity": 100 + }) + + component_3 = self.env['product.template'].create({"name": "Component 3", "type": "product"}) + + self.env['stock.quant'].create({ + "product_id": component_3.product_variant_id.id, + "location_id": 8, + "quantity": 100 + }) + + self.env['mrp.bom'].create({ + "product_tmpl_id": product.id, + "product_id": False, + "product_qty": 1, + "bom_line_ids": [ + [0, 0, {"product_id": component_1.product_variant_id.id, "product_qty": 1}], + [0, 0, {"product_id": component_2.product_variant_id.id, "product_qty": 1}], + [0, 0, {"product_id": component_3.product_variant_id.id, "product_qty": 1}] + ], + "operation_ids": [ + [0, 0, {"name": "Operation 1", "workcenter_id": work_center_1.id}], + [0, 0, {"name": "Operation 2", "workcenter_id": work_center_2.id}], + [0, 0, {"name": "Operation 3", "workcenter_id": work_center_3.id}] + ] + }) + + # create a manufacturing order with 10 product to produce + + mo_form = Form(self.env['mrp.production']) + mo_form.product_id = product.product_variant_id + mo_form.product_qty = 10 + mo = mo_form.save() + + self.assertEqual(mo.state, 'draft') + + mo.action_confirm() + + wo_1 = mo.workorder_ids[0] + wo_2 = mo.workorder_ids[1] + wo_3 = mo.workorder_ids[2] + + self.assertEqual(mo.state, 'confirmed') + self.assertEqual(wo_1.state, 'ready') + + wo_1.button_start() + + self.assertEqual(mo.state, 'progress') + + wo_1.button_finish() + + wo_2.button_start() + + wo_2.qty_producing = 8 + + wo_2.button_finish() + + wo_3.button_start() + + wo_3.qty_producing = 8 + + wo_3.button_finish() + + self.assertEqual(mo.state, 'to_close') + + mo.button_mark_done() + + bo = self.env['mrp.production.backorder'].create({ + "mrp_production_backorder_line_ids": [ + [0, 0, {"mrp_production_id": mo.id, "to_backorder": True}] + ] + }) + + bo.action_backorder() + + self.assertEqual(mo.state, 'done') + + mo_2 = self.env['mrp.production'].browse(mo.id + 1) + + self.assertEqual(mo_2.state, 'progress') + + wo_4, wo_5, wo_6 = mo_2.workorder_ids + + self.assertEqual(wo_4.state, 'ready') + + wo_4.button_start() + + wo_4.button_finish() + + wo_5.button_start() + + self.assertEqual(mo_2.state, 'progress') + + wo_5.button_finish() + + wo_6.button_start() + + wo_6.button_finish() + + self.assertEqual(mo_2.state, 'to_close') + + mo_2.button_mark_done() + + self.assertEqual(mo_2.state, 'done')