diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py index ba9383473ef..d2025ebe373 100644 --- a/addons/stock/models/stock_move_line.py +++ b/addons/stock/models/stock_move_line.py @@ -473,7 +473,6 @@ class StockMoveLine(models.Model): ('owner_id', '=', owner_id.id if owner_id else False), ('package_id', '=', package_id.id if package_id else False), ('product_qty', '>', 0.0), - ('qty_done', '=', 0.0), ('id', '!=', self.id), ] oudated_candidates = self.env['stock.move.line'].search(oudated_move_lines_domain) @@ -487,7 +486,10 @@ class StockMoveLine(models.Model): if float_compare(candidate.product_qty, quantity, precision_rounding=rounding) <= 0: quantity -= candidate.product_qty move_to_recompute_state |= candidate.move_id - candidate.unlink() + if candidate.qty_done: + candidate.product_uom_qty = 0.0 + else: + candidate.unlink() else: # split this move line and assign the new part to our extra move quantity_split = float_round( diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py index 9fd8088ca38..39394a749fa 100644 --- a/addons/stock/tests/test_move.py +++ b/addons/stock/tests/test_move.py @@ -714,6 +714,48 @@ class StockMove(TransactionCase): self.assertEqual(move1.state, 'assigned') self.assertEqual(move1.reserved_availability, 1.0) + def test_availability_4(self): + self.env['stock.quant']._update_available_quantity(self.product1, self.stock_location, 30.0) + move1 = self.env['stock.move'].create({ + 'name': 'test_availability_4', + 'location_id': self.stock_location.id, + 'location_dest_id': self.customer_location.id, + 'product_id': self.product1.id, + 'product_uom': self.uom_unit.id, + 'product_uom_qty': 15.0, + }) + move1._action_confirm() + move1._action_assign() + self.assertEqual(move1.state, 'assigned') + + move2 = self.env['stock.move'].create({ + 'name': 'test_availability_4', + 'location_id': self.stock_location.id, + 'location_dest_id': self.customer_location.id, + 'product_id': self.product1.id, + 'product_uom': self.uom_unit.id, + 'product_uom_qty': 15.0, + }) + move2._action_confirm() + move2._action_assign() + + # set 15 as quantity done for the first and 30 as the second + move1.move_line_ids.qty_done = 15 + move2.move_line_ids.qty_done = 30 + + # validate the second, the first should be unreserved + move2._action_done() + + self.assertEqual(move1.state, 'confirmed') + self.assertEqual(move1.move_line_ids.qty_done, 15) + self.assertEqual(move2.state, 'done') + + stock_quants = self.env['stock.quant']._gather(self.product1, self.stock_location) + self.assertEqual(len(stock_quants), 0) + customer_quants = self.env['stock.quant']._gather(self.product1, self.customer_location) + self.assertEqual(customer_quants.quantity, 30) + self.assertEqual(customer_quants.reserved_quantity, 0) + def test_unreserve_1(self): """ Check that unreserving a stock move sets the products reserved as available and set the state back to confirmed.