[FIX] stock: quant: _update_reserved_quantity and negative quantity
If we have multiple quants returned when we want to decrease the reservation of a move line, the min function will always return the quantity passed in argument because 'reserved_quantity' is always a positive number and quantity a negative one. This can lead to negative reserved quantity on a quant, if the quantity to reserve on the first quant is lower than the absolute value of the quantity to decrease. To fix this, we correctly separate the behaviors for decrease and increase. We add a test that show the, now fixed, bug.
This commit is contained in:
committed by
Simon Lejeune
parent
2a0b158d44
commit
8a497cdd5f
@@ -183,15 +183,17 @@ class StockQuant(models.Model):
|
||||
max_quantity_on_quant = quant.quantity - quant.reserved_quantity
|
||||
if max_quantity_on_quant <= 0:
|
||||
continue
|
||||
max_quantity_on_quant = min(max_quantity_on_quant, quantity)
|
||||
quant.reserved_quantity += max_quantity_on_quant
|
||||
reserved_quants.append((quant, max_quantity_on_quant))
|
||||
quantity -= max_quantity_on_quant
|
||||
available_quantity -= max_quantity_on_quant
|
||||
else:
|
||||
max_quantity_on_quant = quant.reserved_quantity
|
||||
max_quantity_on_quant = min(max_quantity_on_quant, quantity)
|
||||
|
||||
quant.reserved_quantity += max_quantity_on_quant
|
||||
reserved_quants.append((quant, max_quantity_on_quant))
|
||||
|
||||
quantity -= max_quantity_on_quant
|
||||
available_quantity -= max_quantity_on_quant
|
||||
max_quantity_on_quant = min(quant.reserved_quantity, abs(quantity))
|
||||
quant.reserved_quantity -= max_quantity_on_quant
|
||||
reserved_quants.append((quant, -max_quantity_on_quant))
|
||||
quantity += max_quantity_on_quant
|
||||
available_quantity += max_quantity_on_quant
|
||||
|
||||
if quantity == 0 or available_quantity == 0:
|
||||
break
|
||||
|
||||
@@ -831,6 +831,45 @@ class StockMove(TransactionCase):
|
||||
self.assertEqual(quants.reserved_quantity, 0.0)
|
||||
self.assertEqual(len(move1.move_line_ids), 0.0)
|
||||
|
||||
def test_unreserve_5(self):
|
||||
""" Check the unreservation of a stock move reserved on multiple quants.
|
||||
"""
|
||||
# make some stock
|
||||
self.env['stock.quant']._update_available_quantity(self.product1, self.stock_location, 3)
|
||||
self.env['stock.quant'].create({
|
||||
'product_id': self.product1.id,
|
||||
'location_id': self.stock_location.id,
|
||||
'quantity': 2,
|
||||
})
|
||||
self.assertEqual(len(self.env['stock.quant']._gather(self.product1, self.stock_location)), 2)
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product1, self.stock_location), 5)
|
||||
|
||||
# creation
|
||||
move1 = self.env['stock.move'].create({
|
||||
'name': 'test_unreserve_5',
|
||||
'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,
|
||||
})
|
||||
self.assertEqual(move1.state, 'draft')
|
||||
|
||||
# confirmation
|
||||
move1.action_confirm()
|
||||
self.assertEqual(move1.state, 'confirmed')
|
||||
|
||||
# assignment
|
||||
move1.action_assign()
|
||||
self.assertEqual(move1.state, 'assigned')
|
||||
self.assertEqual(len(move1.move_line_ids), 1)
|
||||
move1.do_unreserve()
|
||||
|
||||
quants = self.env['stock.quant']._gather(self.product1, self.stock_location)
|
||||
self.assertEqual(len(quants), 2.0)
|
||||
for quant in quants:
|
||||
self.assertEqual(quant.reserved_quantity, 0)
|
||||
|
||||
def test_link_assign_1(self):
|
||||
""" Test the assignment mechanism when two chained stock moves try to move one unit of an
|
||||
untracked product.
|
||||
|
||||
Reference in New Issue
Block a user