From a61332e251d8896fc8cc0959b080757d584dcb79 Mon Sep 17 00:00:00 2001 From: svs-odoo Date: Fri, 24 Jan 2020 13:00:23 +0000 Subject: [PATCH] [FIX] stock: recompute move state Before this commit, a move can be 'assigned' even if it has no reserved quantity. How to reproduce: - For a tracked product, add some quantities for a LN/SN. Create an another LN/SN with no quantity; - Create a delivery for this product; - Confirm it and check availability; - On the move line, change the SN/LN for the one without quantity. --> The move has no reserved quantity but is still marked as `assigned`. task-2171546 closes odoo/odoo#44145 X-original-commit: d5e70fa9778240b23515cea6ab1a3d0a674ac940 Signed-off-by: Simon Lejeune (sle) Co-authored-by: sle-odoo --- addons/stock/models/stock_move_line.py | 6 ++++++ addons/stock/tests/test_move.py | 2 ++ 2 files changed, 8 insertions(+) diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py index 42a65359c10..64c484b9977 100644 --- a/addons/stock/models/stock_move_line.py +++ b/addons/stock/models/stock_move_line.py @@ -227,6 +227,7 @@ class StockMoveLine(models.Model): if 'product_id' in vals and any(vals.get('state', ml.state) != 'draft' and vals['product_id'] != ml.product_id.id for ml in self): raise UserError(_("Changing the product is only allowed in 'Draft' state.")) + moves_to_recompute_state = self.env['stock.move'] Quant = self.env['stock.quant'] precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') # We forbid to change the reserved quantity in the interace, but it is needed in the @@ -285,6 +286,7 @@ class StockMoveLine(models.Model): pass if new_product_qty != ml.product_qty: new_product_uom_qty = ml.product_id.uom_id._compute_quantity(new_product_qty, ml.product_uom_id, rounding_method='HALF-UP') + moves_to_recompute_state |= ml.move_id ml.with_context(bypass_reservation_update=True).product_uom_qty = new_product_uom_qty # When editing a done move line, the reserved availability of a potential chained move is impacted. Take care of running again `_action_assign` on the concerned moves. @@ -350,6 +352,10 @@ class StockMoveLine(models.Model): move.product_uom_qty = move.quantity_done next_moves._do_unreserve() next_moves._action_assign() + + if moves_to_recompute_state: + moves_to_recompute_state._recompute_state() + return res def unlink(self): diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py index 238b4a388d6..571538e16dd 100644 --- a/addons/stock/tests/test_move.py +++ b/addons/stock/tests/test_move.py @@ -2610,12 +2610,14 @@ class StockMove(SavepointCase): move1._action_confirm() move1._action_assign() + self.assertEqual(move1.move_line_ids.state, 'assigned') self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product, shelf1_location), 0.0) self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product, shelf2_location), 0.0) self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product, self.stock_location), 0.0) move1.move_line_ids.location_id = shelf2_location.id + self.assertEqual(move1.move_line_ids.state, 'confirmed') self.assertEqual(move1.reserved_availability, 0.0) self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product, self.stock_location), 1.0) self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product, shelf1_location), 1.0)