From c8b919c0c23aec0691e5b65fd4b2b9c1d26a982d Mon Sep 17 00:00:00 2001 From: "Touati Djamel (otd)" Date: Wed, 6 Sep 2023 15:49:24 +0000 Subject: [PATCH] [FIX] mrp: ignore verification for tracked product with 0 to consume qty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: - Create a storable product “P1” with BoM: - Add a tracked component - Add another component (no tracked) - Create a MO to produce 1 unit of the product "P1": - Confirm - Unlock the MO - Set the "to consume" quantity of the tracked component to 0. - Try to validate the MO Problem: A user error is triggered: “You need to supply Lot/Serial Number for products:” Solution: If the quantity to consume is 0, ignore the serial number verification for this move. opw-3471256 closes odoo/odoo#135657 X-original-commit: 5e591cf36cdc6dcbdb8a5ee3753247578a771e9f Signed-off-by: William Henrotin (whe) Signed-off-by: Djamel Touati (otd) --- addons/mrp/models/mrp_production.py | 4 ++- addons/mrp/tests/test_order.py | 41 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index c1fe1320412..4ca19d3b9d3 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -2505,7 +2505,9 @@ class MrpProduction(models.Model): self.qty_producing = self.product_qty - self.qty_produced self._set_qty_producing() - for move in self.move_raw_ids.filtered(lambda m: m.state not in ['done', 'cancel']): + for move in self.move_raw_ids: + if move.state in ('done', 'cancel') or not move.product_uom_qty: + continue rounding = move.product_uom.rounding if move.manual_consumption: if move.has_tracking in ('serial', 'lot') and float_is_zero(move.quantity_done, precision_rounding=rounding): diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index f2ef137d62e..c4bd05fdc7f 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -3441,3 +3441,44 @@ class TestMrpOrder(TestMrpCommon): p03_raws = mo.move_raw_ids.filtered(lambda m: m.product_id == product03) self.assertEqual(sum(p02_raws.mapped('quantity_done')), 1.5) self.assertEqual(sum(p03_raws.mapped('quantity_done')), 2) + + def test_validation_mo_with_tracked_component(self): + """ + check that the verification of SN for tracked component is ignored when the quantity to consume is 0. + """ + self.product_2.tracking = 'serial' + bom = self.env["mrp.bom"].create({ + 'product_tmpl_id': self.product_4.product_tmpl_id.id, + 'product_qty': 1.0, + 'bom_line_ids': [(0, 0, { + 'product_id': self.product_2.id, + 'product_qty': 1.0, + }), (0, 0, { + 'product_id': self.product_3.id, + 'product_qty': 1.0, + })] + }) + # create the MO and confirm it + mo = self.env['mrp.production'].create({ + 'product_id': self.product_4.id, + 'bom_id': bom.id, + 'product_qty': 1.0, + }) + mo.action_confirm() + self.assertEqual(mo.state, 'confirmed') + # set the qty to consume of the tracked product to 0 + mo.move_raw_ids[0].write({ + 'product_uom_qty': 0, + 'quantity_done': 0, + }) + mo.action_assign() + # Set MO Done and create backorder + action = mo.button_mark_done() + consumption_warning = Form(self.env['mrp.consumption.warning'].with_context(**action['context'])).save() + + self.assertEqual(len(consumption_warning.mrp_consumption_warning_line_ids), 1) + self.assertEqual(consumption_warning.mrp_consumption_warning_line_ids[0].product_consumed_qty_uom, 0) + self.assertEqual(consumption_warning.mrp_consumption_warning_line_ids[0].product_expected_qty_uom, 1) + # Force the warning + consumption_warning.action_confirm() + self.assertEqual(mo.state, 'done')