From a5a206f8a8452bd2a2d3e647bd559208df3647e9 Mon Sep 17 00:00:00 2001 From: "Andrea Grazioso (agr-odoo)" Date: Wed, 20 Mar 2024 14:38:34 +0000 Subject: [PATCH] [FIX] stock: lost history after unpack In Inventory Settings activate packages and storage locations. Create a storable product [TEST] with tracking by lot Create a PO for [TEST] with a [QTY] larger than one. Receive the products (lot [A]) and put them in a package [PKG]. Create and process an internal transfer of the whole package [PKG] from the input location to any location. Unpack [PKG]. Go to Stock > Reporting > Locations Locate the received product, hit 'History' Issue: traceability is empty. This occurs because the 'unpack' operation clean the information relative to the package from the stock quant. When accessing the history, the system lookup for move lines having the same package (none in this case), so nothing is found opw-3769752 closes odoo/odoo#158949 X-original-commit: 314d44b400717f392bfbb70f66ef9605c1f31041 Signed-off-by: William Henrotin (whe) Signed-off-by: Andrea Grazioso (agr) --- addons/stock/models/stock_quant.py | 9 +++-- addons/stock/tests/test_quant.py | 56 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py index f6f177d01f7..733c8dd5926 100644 --- a/addons/stock/models/stock_quant.py +++ b/addons/stock/models/stock_quant.py @@ -354,10 +354,13 @@ class StockQuant(models.Model): ('location_id', '=', self.location_id.id), ('location_dest_id', '=', self.location_id.id), ('lot_id', '=', self.lot_id.id), - '|', - ('package_id', '=', self.package_id.id), - ('result_package_id', '=', self.package_id.id), ] + if self.package_id: + action['domain'] += [ + '|', + ('package_id', '=', self.package_id.id), + ('result_package_id', '=', self.package_id.id), + ] action['context'] = literal_eval(action.get('context')) action['context']['search_default_product_id'] = self.product_id.id return action diff --git a/addons/stock/tests/test_quant.py b/addons/stock/tests/test_quant.py index 45de1de1bae..d73f473dd37 100644 --- a/addons/stock/tests/test_quant.py +++ b/addons/stock/tests/test_quant.py @@ -1061,6 +1061,62 @@ class StockQuant(TransactionCase): self.assertEqual(destruction_move_line.location_dest_id.id, creation_move_line.location_id.id) self.assertEqual(dummy_quant.quantity, 0) + def test_unpack_and_quants_history(self): + """ + Test that after unpacking the quant history is preserved + """ + product = self.env['product.product'].create({ + 'name': 'Product', + 'type': 'product', + 'tracking': 'lot', + }) + lot_a = self.env['stock.lot'].create({ + 'name': 'A', + 'product_id': product.id, + 'product_qty': 5, + }) + package = self.env['stock.quant.package'].create({ + 'name': 'Super Package', + }) + stock_location = self.env['stock.warehouse'].search([], limit=1).lot_stock_id + dst_location = stock_location.child_ids[0] + picking_type = self.env.ref('stock.picking_type_internal') + + self.env['stock.quant']._update_available_quantity(product, stock_location, 5.0, lot_id=lot_a, package_id=package) + + picking = self.env['stock.picking'].create({ + 'picking_type_id': picking_type.id, + 'location_id': dst_location.id, + 'location_dest_id': stock_location.id, + 'move_ids': [(0, 0, { + 'name': 'In 5 x %s' % product.name, + 'product_id': product.id, + 'location_id': stock_location.id, + 'location_dest_id': dst_location.id, + 'product_uom_qty': 5, + 'product_uom': product.uom_id.id, + })], + }) + picking.action_confirm() + + picking.move_ids.move_line_ids.write({ + 'quantity': 5, + 'lot_id': lot_a.id, + 'package_id': package.id, + 'result_package_id': package.id, + }) + picking.button_validate() + package.unpack() + + quant = self.env['stock.quant'].search([ + ('product_id', '=', product.id), + ('location_id', '=', dst_location.id), + ]) + action = quant.action_view_stock_moves() + history = self.env['stock.move.line'].search(action['domain']) + self.assertTrue(history) + + class StockQuantRemovalStrategy(TransactionCase): def setUp(self): super().setUp()