[FIX] stock: '_move_quants_by_lot' bad 'false_quants' values

Hypothesis:
 - We have a product 'pa' managed by lot.
 - We don't create lots, when we receive products.
 - We create lots when we deliver products.
 - We don't have any units of product 'pa' in stock.
 - We recieve 4 units of product 'pa' in one picking.
 - We create a picking to deliver 3 products 'pa' (stock.move).
 - We actually deliver 4 units of product 'pa' (1 in 'LOT1', 1 in 'LOT2' and 2 in 'LOT3').
 - The problem also occurs when you just have 2 products in and 2 out in
   different lots, but we based the example on the tests defined in
   'test_stock_flow.py'

Thesis:
 - We don't have anymore quants of product 'pa' in stock after delivering the 4 units

Problem:
 - We actually have 3 quants of product 'pa' in stock, two having the 'lot_id' corresponding
   to 'LOT3' and 'qty=-1', and one having no 'lot_id' and 'qty=2'.

Origin:
 - This problem is caused by a bad condition in the function '_move_quants_by_lot' defined
   in the model 'stock.move'.

Explanation:

When we reserve the 3 units of product 'pa' in the picking out, the quant in stock having
'qty=4' is splitted in 2 quants, one having 'qty=3' and a 'reservation_id' equals to the id
of the move in the picking out. And one with 'qty=1', having not reservation id.

So once the products are reserved, we will complete the pack operation present in the picking.
We will add 4 units of product 'pa' dispatched in Lot as 1 in 'LOT1', 1 in 'LOT2' and 2 in 'LOT3'
to the pack operation.

Then when we validate the picking, the quants with references to 'lot_id' must be created, and
then moved to the client.
Because we have set 4 units of the product 'pa' in the pack operation, an extra move of 1 unit of
product 'pa' is added to the picking to have a total of 4 untis of 'pa' moved to the customer
location.

When the function '_move_quants_by_lot' is called, it gets in parameter 'false_quants' which contains
the quant reserved by the first move, it means the quant in stock with the reservation_id to the first
move, and 'qty=3'.

The function, will now split this quant in 2 different quants:
 - one with 'lot_id' corresponding to 'LOT1' and moved to customer location.
 - one with no 'lot_id' staying in stock location still reserved to the first move.

Then, the function should reset the 'false_quants' with the quant containing the 2 last units reserved
in the quant from the last split in order to complete the next operation (create a quant with lot_id 'LOT2').

But the condition to find this new reserved quant contains (x.package_id.id != ops.package_id.id) where x is
a quant which is wrong, because when we don't manage package, x.package_id.id is 'False' and ops.package_id.id
is 'False' too. So it doesn't find the remaining quant.

So to fix it, we changed this part of the condition as the quant package_id should be equal to the pack operation
package_id (if no packages, False = False)
This commit is contained in:
Pierre Masereel
2016-11-08 17:14:38 +01:00
parent f8c8715188
commit 231090c0e6
+1 -1
View File
@@ -2633,7 +2633,7 @@ class stock_move(osv.osv):
if redo_false_quants:
move_rec = self.pool['stock.move'].browse(cr, uid, move, context=context)
false_quants_move = [x for x in move_rec.reserved_quant_ids if (not x.lot_id) and (x.owner_id.id == ops.owner_id.id) \
and (x.location_id.id == ops.location_id.id) and (x.package_id.id != ops.package_id.id)]
and (x.location_id.id == ops.location_id.id) and (x.package_id.id == ops.package_id.id)]
def action_done(self, cr, uid, ids, context=None):
""" Process completely the moves given as ids and if all moves are done, it will finish the picking.