From 78991b1c80e97ed2f8e0ab138257635fd47dd89d Mon Sep 17 00:00:00 2001 From: Michele Date: Thu, 27 Apr 2023 14:35:31 +0000 Subject: [PATCH] [IMP] stock: unreserve only quantity required if available quantity is less than quantity required when action_done on stock move. Example: Now there is this behaviour Inventory quantity 4 Reserved quantity 3 Available quantity 1 If i do a stock move of 2 pieces, it will unreserve ALL the stock move of the product. With this PR it will unreserve only the pieces that are required minus the available quantity not reserved , in this case 2 (new stock move) - 1 (available quantity) = 1 closes odoo/odoo#121724 X-original-commit: 999c2045236161cc8d8a76ab6a33c17d1b124f25 Signed-off-by: William Henrotin (whe) --- addons/stock/models/stock_move_line.py | 1 + addons/stock/tests/test_move2.py | 37 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py index f3f4b943b88..866be0ae0b2 100644 --- a/addons/stock/models/stock_move_line.py +++ b/addons/stock/models/stock_move_line.py @@ -724,6 +724,7 @@ class StockMoveLine(models.Model): product_id, location_id, lot_id=lot_id, package_id=package_id, owner_id=owner_id, strict=True ) if quantity > available_quantity: + quantity = quantity - available_quantity # We now have to find the move lines that reserved our now unavailable quantity. We # take care to exclude ourselves and the move lines were work had already been done. outdated_move_lines_domain = [ diff --git a/addons/stock/tests/test_move2.py b/addons/stock/tests/test_move2.py index 2b26eb9dbc5..6f36a7ecaf6 100644 --- a/addons/stock/tests/test_move2.py +++ b/addons/stock/tests/test_move2.py @@ -114,6 +114,43 @@ class TestPickShip(TestStockCommon): }) return picking_pick, picking_pack, picking_ship + def test_unreserve_only_required_quantity(self): + product_unreserve = self.env['product.product'].create({ + 'name': 'product unreserve', + 'type': 'product', + 'categ_id': self.env.ref('product.product_category_all').id, + }) + stock_location = self.env['stock.location'].browse(self.stock_location) + self.env['stock.quant']._update_available_quantity(product_unreserve, stock_location, 4.0) + quants = self.env['stock.quant']._gather(product_unreserve, stock_location, strict=True) + self.assertEqual(quants[0].reserved_quantity, 0) + move = self.MoveObj.create({ + 'name': product_unreserve.name, + 'product_id': product_unreserve.id, + 'product_uom_qty': 3, + 'product_uom': product_unreserve.uom_id.id, + 'state': 'confirmed', + 'location_id': self.stock_location, + 'location_dest_id': self.customer_location, + }) + move._action_assign() + self.assertEqual(quants[0].reserved_quantity, 3) + move_2 = self.MoveObj.create({ + 'name': product_unreserve.name, + 'product_id': product_unreserve.id, + 'product_uom_qty': 2, + 'quantity_done':2, + 'product_uom': product_unreserve.uom_id.id, + 'state': 'confirmed', + 'location_id': self.stock_location, + 'location_dest_id': self.customer_location, + }) + move_2._action_assign() + move_2._action_done() + quants = self.env['stock.quant']._gather(product_unreserve, stock_location, strict=True) + self.assertEqual(quants[0].reserved_quantity, 2) + + def test_mto_moves(self): """ 10 in stock, do pick->ship and check ship is assigned when pick is done, then backorder of ship