From 231090c0e6080f5e4eebe97c947bbc4e64041bd8 Mon Sep 17 00:00:00 2001 From: Pierre Masereel Date: Mon, 7 Nov 2016 17:15:19 +0100 Subject: [PATCH] [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) --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index beac1dcaf3b..0cc4fb637e4 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -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.