diff options
| author | Pierre Masereel <pim@odoo.com> | 2017-07-26 12:18:33 +0200 |
|---|---|---|
| committer | Simon Lejeune <sle@openerp.com> | 2017-07-26 17:23:55 +0200 |
| commit | 8a497cdd5ff4cf93067d0519a9839ea6ec9adc21 (patch) | |
| tree | eef4e9c4bfd4caf8381d38d122e08502cfc8ff76 | |
| parent | 2a0b158d4490817388da7de94969447d02744386 (diff) | |
[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.
| -rw-r--r-- | addons/stock/models/stock_quant.py | 18 | ||||
| -rw-r--r-- | addons/stock/tests/test_move.py | 39 |
2 files changed, 49 insertions, 8 deletions
diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py index 15084292a5e..641e3e3f5b4 100644 --- a/addons/stock/models/stock_quant.py +++ b/addons/stock/models/stock_quant.py @@ -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 diff --git a/addons/stock/tests/test_move.py b/addons/stock/tests/test_move.py index 597945466f4..c08a63a2f8c 100644 --- a/addons/stock/tests/test_move.py +++ b/addons/stock/tests/test_move.py @@ -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. |
