From 60572d6597941a2cb88f916a0c8be38323cc9237 Mon Sep 17 00:00:00 2001 From: IEL Date: Thu, 8 Oct 2020 13:10:16 +0000 Subject: [PATCH] [FIX] stock: keep previously set result package in pickings Steps to reproduce: * In Inventory, activate multiple warehouses and storage locations, multi-step routes, Delivery packages * On the main warehouse, activate 3 steps delivery * Create a stockable product A * Update quantity on hand: 100 units in a package PACK1 in Stock/Shelf 1 * Create a new Pick transfer with one move: 120 product A * Set the transfer as todo and check availability: a move line for the 100 units from PACK1 is created * Edit the move line: set a destination location, **change the result package to PACK2** and set a qty_done * On product A, update the quantity on hand: add a *new* package PACK3 of 20 in Stock/Shelf 1 * On the transfer, click on check availability Current behavior: * A new move line is created for the 20 units from PACK3 to PACK3: ok * The move line edited before for the 100 units has its result package **reset to PACK1** Expected behavior: * A new move line is created for the 20 units from PACK3 to PACK3: ok * The move line edited before for the 100 units has its result package kept to **PACK2 as edited by the user** who decided to open the package already Short analysis: At the end of `StockMove._action_assign()`, the method `StockPicking._check_entire_pack()` is called. For each package moved by a move line, this method checks if the package is entirely moved (sum of quants == sum of move lines). The check is done by `StockPicking._check_move_lines_map_quant_package`. When the sums match, the package level of the move lines is created or updated. When it happens, it writes the package in the `result_package_id` of the related lines. It should not change the result_package_id if it was already set. Thinking further, maybe it should not consider lines with a `qty_done` in `_check_move_lines_map_quant_package`: users already picked these lines, if they decided to empty or change the `result_package_id`, a new check of availability for the remaining quantities should not change these lines. opw-2346608 Fixes #58491 closes odoo/odoo#60025 X-original-commit: db262912eb716aed1c42be8a9d59c25bdfa400e0 Signed-off-by: Nicolas Martinelli (nim) --- addons/stock/models/stock_picking.py | 2 +- addons/stock/tests/test_packing.py | 64 ++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index b90dee3750c..b8f356613db 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -833,7 +833,7 @@ class Picking(models.Model): for pack in origin_packages: if picking._check_move_lines_map_quant_package(pack): package_level_ids = picking.package_level_ids.filtered(lambda pl: pl.package_id == pack) - move_lines_to_pack = picking.move_line_ids.filtered(lambda ml: ml.package_id == pack) + move_lines_to_pack = picking.move_line_ids.filtered(lambda ml: ml.package_id == pack and not ml.result_package_id) if not package_level_ids: self.env['stock.package_level'].create({ 'picking_id': picking.id, diff --git a/addons/stock/tests/test_packing.py b/addons/stock/tests/test_packing.py index 758107101c5..1e03411041b 100644 --- a/addons/stock/tests/test_packing.py +++ b/addons/stock/tests/test_packing.py @@ -666,3 +666,67 @@ class TestPacking(TestPackingCommon): pick_picking.move_line_ids.qty_done = 3 first_pack = pick_picking.action_put_in_pack() + + def test_action_assign_package_level(self): + """calling _action_assign on move does not erase lines' "result_package_id" + At the end of the method ``StockMove._action_assign()``, the method + ``StockPicking._check_entire_pack()`` is called. This method compares + the move lines with the quants of their source package, and if the entire + package is moved at once in the same transfer, a ``stock.package_level`` is + created. On creation of a ``stock.package_level``, the result package of + the move lines is directly updated with the entire package. + This is good on the first assign of the move, but when we call assign for + the second time on a move, for instance because it was made partially available + and we want to assign the remaining, it can override the result package we + selected before. + An override of ``StockPicking._check_move_lines_map_quant_package()`` ensures + that we ignore: + * picked lines (qty_done > 0) + * lines with a different result package already + """ + package = self.env["stock.quant.package"].create({"name": "Src Pack"}) + dest_package1 = self.env["stock.quant.package"].create({"name": "Dest Pack1"}) + + # Create new picking: 120 productA + picking_form = Form(self.env['stock.picking']) + picking_form.picking_type_id = self.warehouse.pick_type_id + with picking_form.move_ids_without_package.new() as move_line: + move_line.product_id = self.productA + move_line.product_uom_qty = 120 + picking = picking_form.save() + + # mark as TO-DO + picking.action_confirm() + + # Update quantity on hand: 100 units in package + self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 100, package_id=package) + + # Check Availability + picking.action_assign() + + self.assertEqual(picking.state, "assigned") + self.assertEqual(picking.package_level_ids.package_id, package) + + move = picking.move_lines + line = move.move_line_ids + + # change the result package and set a qty_done + line.qty_done = 100 + line.result_package_id = dest_package1 + + # Update quantity on hand: 20 units in new_package + new_package = self.env["stock.quant.package"].create({"name": "New Pack"}) + self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 20, package_id=new_package) + + # Check Availability + picking.action_assign() + + # Check that result package is not changed on first line + new_line = move.move_line_ids - line + self.assertRecordValues( + line + new_line, + [ + {"qty_done": 100, "result_package_id": dest_package1.id}, + {"qty_done": 0, "result_package_id": new_package.id}, + ], + )