[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) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
Adrien Widart
2022-09-23 00:38:52 +02:00
parent 7971b4ed4d
commit cb6e651081
2 changed files with 28 additions and 0 deletions
+2
View File
@@ -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:
+26
View File
@@ -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