[FIX] stock: lot in multiple locations

- Activate:
  'Track lots or serial numbers'
  'Manage several Warehouses, each one composed by several stock locations'
  'Advanced routing of products using rules'
- In the main warehouse, activate Pick + Ship
- In Stock Locations, create 'WH/Stock/Shelf 3' and 'WH/Stock/Shelf 4'
  (1 and 2 already exist, use the same config)
- Create a new product 'Foo', activate Tracking By Lots
- On Foo, use 4 times the "Update Qty on Hand" (order is important):
  Add 1 on Shelf 2, create a lot
  Add 1 on Shelf 1, use the same lot
  Add 3 on Shelf 4, use the same lot
  Add 1 on Shelf 3, use the same lot
- Create a SO, set a partner
- Ensure that YourCompany is used as warehouse
- Add several SO lines (order is important)
  a line with 1 product Foo
  a second line with 1 product Foo
  a third line with 4 products Foo
- Confirm the SO, you now have 2 deliveries, 1 Pick, 1 Out
- Open the Pick, all moves should be available, you should have:
  4 operations:
    Shelf 2, quantity 1
    Shelf 4, quantity 3
    Shelf 1, quantity 1
    Shelf 3, quantity 1
  3 moves:
    A, quantity 1
    B, quantity 1
    C, quantity 4
- On each operation, select the lot created before and set the quantity
  to be fully done
- Validate the Pick

The moves end up like this:
- Move A with qty 1: is done and linked with a quant of 1
- Move B with qty 1: is done and linked with no quant
- Move C with qty 4: is done and linked with a quant of 1, a quant of 3,
  a quant of 1 (sum is 5)

In the Out picking, the move linked with the source move (B) with no
quant stays in "Waiting another move" even if the source move is done.
This outgoing move will never be available.

In the method `recompute_remaining_qty`, we loop on operations, and
match them wih the moves. However, the operation with the largest
quantity (Shelf 4, quantity 3) is processed before the move with the
highest quantity (C, quantity 4). Therefore, when we later loop on move
C, `qty_assign_cmp` is larger than zero, which sets `need_rereserve` and
ultimately triggers `rereserve_quants` in `do_transfer`.

A first part of the fix is to check for the location of the quants when
matching moves and operations. This fixes the original issue, but
inconsistencies can still arise since a quant which is taken partially.
therefore, we make sure to never take more than the quantity on the
link.

opw-1932624

closes odoo/odoo#30857
This commit is contained in:
Josse Colpaert
2019-02-06 08:55:56 +00:00
committed by Nicolas Martinelli
parent c7c938996f
commit 845a6a9e08
2 changed files with 9 additions and 7 deletions
+8 -6
View File
@@ -868,13 +868,15 @@ class StockMove(models.Model):
false_quants += [reserved_quant]
elif float_compare(lot_quantities.get(reserved_quant.lot_id.id, 0), 0, precision_rounding=rounding) > 0:
if float_compare(lot_quantities[reserved_quant.lot_id.id], reserved_quant.qty, precision_rounding=rounding) >= 0:
lot_quantities[reserved_quant.lot_id.id] -= reserved_quant.qty
quants_taken += [(reserved_quant, reserved_quant.qty)]
qty_on_link -= reserved_quant.qty
qty_taken = min(reserved_quant.qty, qty_on_link)
lot_quantities[reserved_quant.lot_id.id] -= qty_taken
quants_taken += [(reserved_quant, qty_taken)]
qty_on_link -= qty_taken
else:
quants_taken += [(reserved_quant, lot_quantities[reserved_quant.lot_id.id])]
lot_quantities[reserved_quant.lot_id.id] = 0
qty_on_link -= lot_quantities[reserved_quant.lot_id.id]
qty_taken = min(qty_on_link, lot_quantities[reserved_quant.lot_id.id])
quants_taken += [(reserved_quant, qty_taken)]
lot_quantities[reserved_quant.lot_id.id] -= qty_taken
qty_on_link -= qty_taken
lot_move_qty[move.id] = qty_on_link
remaining_move_qty[move.id] -= prout_move_qty[move]
+1 -1
View File
@@ -737,7 +737,7 @@ class Picking(models.Model):
flag = quant.package_id == ops.package_id
else:
flag = not quant.package_id.id
flag = flag and (ops.owner_id.id == quant.owner_id.id)
flag = flag and (ops.owner_id.id == quant.owner_id.id) and (ops.location_id.id == quant.location_id.id)
if flag:
if not lot_qty:
max_qty_on_link = min(quant.qty, qty_to_assign)