Permalink
Browse files

[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
  • Loading branch information...
amoyaux committed Oct 18, 2018
1 parent 6c42ca8 commit c80fa71b00a870894a770fd3185881dc7fb7c66d
Showing with 44 additions and 2 deletions.
  1. +2 −2 addons/stock/models/stock_move_line.py
  2. +42 −0 addons/stock/tests/test_move.py
@@ -510,15 +510,15 @@ def _free_reservation(self, product_id, location_id, quantity, lot_id=None, pack
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(
candidate.product_qty - quantity,
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()
@@ -1854,6 +1854,48 @@ def test_link_assign_10(self):
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.

0 comments on commit c80fa71

Please sign in to comment.