[FIX] stock: compare quantities with different uom

Usecase to reproduce:
- Create a receipt for 1 dozen.
- Mark as todo
- Unlock and update initial demand to 3 dozen.
The reserved quantity on move line is 36 dozen.

It happens because reserved_availability and product_qty are
compare. However reserved_availability is in move UoM and product_qty
is in move's product UoM.

This commit clean the code in order to compare field that use the same
UoM.

Close #26504
This commit is contained in:
Arnold Moyaux
2018-08-22 15:44:54 +02:00
parent fbfb91799e
commit be4651cda3
2 changed files with 27 additions and 4 deletions
+6 -4
View File
@@ -897,11 +897,13 @@ class StockMove(models.Model):
assigned_moves = self.env['stock.move']
partially_available_moves = self.env['stock.move']
for move in self.filtered(lambda m: m.state in ['confirmed', 'waiting', 'partially_available']):
missing_reserved_uom_quantity = move.product_uom_qty - move.reserved_availability
missing_reserved_quantity = move.product_uom._compute_quantity(missing_reserved_uom_quantity, move.product_id.uom_id, rounding_method='HALF-UP')
if move.location_id.should_bypass_reservation()\
or move.product_id.type == 'consu':
# create the move line(s) but do not impact quants
if move.product_id.tracking == 'serial' and (move.picking_type_id.use_create_lots or move.picking_type_id.use_existing_lots):
for i in range(0, int(move.product_qty - move.reserved_availability)):
for i in range(0, int(missing_reserved_quantity)):
self.env['stock.move.line'].create(move._prepare_move_line_vals(quantity=1))
else:
to_update = move.move_line_ids.filtered(lambda ml: ml.product_uom_id == move.product_uom and
@@ -912,16 +914,16 @@ class StockMove(models.Model):
not ml.package_id and
not ml.owner_id)
if to_update:
to_update[0].product_uom_qty += move.product_qty - move.reserved_availability
to_update[0].product_uom_qty += missing_reserved_uom_quantity
else:
self.env['stock.move.line'].create(move._prepare_move_line_vals(quantity=move.product_qty - move.reserved_availability))
self.env['stock.move.line'].create(move._prepare_move_line_vals(quantity=missing_reserved_quantity))
assigned_moves |= move
else:
if not move.move_orig_ids:
if move.procure_method == 'make_to_order':
continue
# If we don't need any quantity, consider the move assigned.
need = move.product_qty - move.reserved_availability
need = missing_reserved_quantity
if float_is_zero(need, precision_rounding=move.product_id.uom_id.rounding):
assigned_moves |= move
continue
+21
View File
@@ -950,6 +950,27 @@ class StockMove(TransactionCase):
move_partial._action_assign()
self.assertEqual(move_partial.state, 'assigned')
def test_availability_9(self):
""" Test the assignment mechanism when the product quantity is increase
on a receipt move.
"""
move_receipt = self.env['stock.move'].create({
'name': 'test_receipt_edit',
'location_id': self.supplier_location.id,
'location_dest_id': self.stock_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_dozen.id,
'product_uom_qty': 1.0,
})
move_receipt._action_confirm()
move_receipt._action_assign()
self.assertEqual(move_receipt.state, 'assigned')
move_receipt.product_uom_qty = 3.0
move_receipt._action_assign()
self.assertEqual(move_receipt.state, 'assigned')
self.assertEqual(move_receipt.move_line_ids.product_uom_qty, 3)
def test_unreserve_1(self):
""" Check that unreserving a stock move sets the products reserved as available and
set the state back to confirmed.