[FIX] stock: free reservation over reserve

Usecase to reproduce:
- 6 units in stock
- reserve 3 units on a move
- reserve 3 units on another move
- validate a third move with 1 unit

It raise the error could not reserve more than you have in stock.
It happens because when free reservation stole reservation from
an exisiting move with too much quantity available, it continues the
loop instead of stopping.

This commit stop the loop once we have enough quantity taken.

opw-1895578

closes odoo/odoo#27935
This commit is contained in:
Arnold Moyaux
2018-10-18 13:49:57 +00:00
parent e648f5fbe4
commit 433666b2d9
2 changed files with 44 additions and 2 deletions
+2 -2
View File
@@ -510,6 +510,8 @@ class StockMoveLine(models.Model):
candidate.product_uom_qty = 0.0
else:
candidate.unlink()
if float_is_zero(quantity, precision_rounding=rounding):
break
else:
# split this move line and assign the new part to our extra move
quantity_split = float_round(
@@ -517,8 +519,6 @@ class StockMoveLine(models.Model):
precision_rounding=self.product_uom_id.rounding,
rounding_method='UP')
candidate.product_uom_qty = self.product_id.uom_id._compute_quantity(quantity_split, candidate.product_uom_id, rounding_method='HALF-UP')
quantity -= quantity_split
move_to_recompute_state |= candidate.move_id
if quantity == 0.0:
break
move_to_recompute_state._recompute_state()
+42
View File
@@ -1854,6 +1854,48 @@ class StockMove(TransactionCase):
self.assertAlmostEqual(move_pack_cust.reserved_availability, 1.0)
self.assertEqual(move_pack_cust.state, 'partially_available')
def test_use_reserved_move_line_1(self):
""" Test that _free_reservation work when quantity is only available on
reserved move lines.
"""
self.env['stock.quant']._update_available_quantity(self.product1, self.stock_location, 10.0)
move1 = self.env['stock.move'].create({
'name': 'test_use_unreserved_move_line_1_1',
'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': 5.0,
})
move2 = self.env['stock.move'].create({
'name': 'test_use_unreserved_move_line_1_1',
'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': 5.0,
})
move1._action_confirm()
move1._action_assign()
move2._action_confirm()
move2._action_assign()
move3 = self.env['stock.move'].create({
'name': 'test_use_unreserved_move_line_1_1',
'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': 0.0,
'quantity_done': 1.0,
})
move3._action_confirm()
move3._action_assign()
move3._action_done()
self.assertEqual(move3.state, 'done')
quant = self.env['stock.quant']._gather(self.product1, self.stock_location)
self.assertEqual(quant.quantity, 9.0)
self.assertEqual(quant.reserved_quantity, 9.0)
def test_use_unreserved_move_line_1(self):
""" Test that validating a stock move linked to an untracked product reserved by another one
correctly unreserves the other one.