From cb6e6510819fca933659d2fcbb5c83e0933fc821 Mon Sep 17 00:00:00 2001 From: Adrien Widart Date: Wed, 14 Sep 2022 09:46:34 +0000 Subject: [PATCH] [FIX] stock: edit reserved qty on SML Suppose a product P with an available quantity equal to 1. Suppose a user writes on an existing SML for that product and sets the reserved quantity to 2. When writing on such a field, `StockMoveLine.write` tries to reserve the same quantity on the quants. If it fails (which would be the case here because there is only one P available), the reserved quantity of the SML is reset to 0 (and so does the reserved quantity of the quant). https://github.com/odoo/odoo/blob/b8423ba218e0736593c3329d7438ca09112a735f/addons/stock/models/stock_move_line.py#L301-L313 However, there is an issue: the incorrect reserved quantity is still in `vals`. As a result, later on in the method, this incorrect value is written on the SML: https://github.com/odoo/odoo/blob/b8423ba218e0736593c3329d7438ca09112a735f/addons/stock/models/stock_move_line.py#L362 This creates an inconsistency: a SML affirms that 2 x P are reserved while the reserved quantity of the quant is 0. Moreover, when marking the SML as done, it will lead to a "unreserve more than..." issue. OPW-2936689 closes odoo/odoo#100858 X-original-commit: 2ea52bbcdbc2beaac916fa5f127ffc0ab2650708 Signed-off-by: Arnold Moyaux (arm) Signed-off-by: Adrien Widart --- addons/stock/models/stock_move_line.py | 2 ++ addons/stock/tests/test_move.py | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py index 9b07d7e75ef..55e0e88c1b7 100644 --- a/addons/stock/models/stock_move_line.py +++ b/addons/stock/models/stock_move_line.py @@ -405,6 +405,8 @@ class StockMoveLine(models.Model): new_reserved_uom_qty = ml.product_id.uom_id._compute_quantity(reserved_qty, ml.product_uom_id, rounding_method='HALF-UP') moves_to_recompute_state |= ml.move_id ml.with_context(bypass_reservation_update=True).reserved_uom_qty = new_reserved_uom_qty + # we don't want to override the new reserved quantity + vals.pop('reserved_uom_qty', None) # 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. if updates or 'qty_done' in vals: diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py index 43c4e7e670b..be23b6735a3 100644 --- a/addons/stock/tests/test_move.py +++ b/addons/stock/tests/test_move.py @@ -3470,6 +3470,32 @@ class StockMove(TransactionCase): self.assertEqual(len(self.gather_relevant(self.product_lot, self.stock_location, lot_id=lot1, strict=True)), 0.0) self.assertEqual(len(self.gather_relevant(self.product_lot, self.stock_location, lot_id=lot2, strict=True)), 0.0) + def test_edit_reserved_move_line_9(self): + """ + When writing on the reserved quantity on the SML, a process tries to + reserve the quants with that new quantity. If it fails (for instance + because the written quantity is more than actually available), this + quantity should be reset to 0. + """ + self.env['stock.quant']._update_available_quantity(self.product, self.stock_location, 1.0) + + out_move = self.env['stock.move'].create({ + 'name': self.product.name, + 'location_id': self.stock_location.id, + 'location_dest_id': self.customer_location.id, + 'product_id': self.product.id, + 'product_uom_qty': 1, + 'product_uom': self.product.uom_id.id, + }) + out_move._action_confirm() + out_move._action_assign() + + # try to manually assign more than available + out_move.move_line_ids.reserved_uom_qty = 2 + + self.assertTrue(out_move.move_line_ids) + self.assertEqual(out_move.move_line_ids.reserved_uom_qty, 0, "The reserved quantity should be cancelled") + def test_edit_done_move_line_1(self): """ Test that editing a done stock move line linked to an untracked product correctly and directly adapts the transfer. In this case, we edit the sublocation where we take the