[FIX] stock: Fix package_level unlink
Steps to reproduce : - Create two products - Create a planned internal transfer with one of each product from Stock -> Location A - Hit "Mark as todo" - Hit "Put in pack" - Validate the picking - Create an new planned internal transfer, with the same products and quantities, but from Location A -> Location B - Remove the destination package for one product. - This will remove the destination package for all products in the same package. When unlinking a package level, it will unlink all moves and move_lines at the same time. Problem is that if a single move_line is updated in a picking where multiple move_lines are in the same package, it will unlink it for all the move_lines instead. closes odoo/odoo#107448 X-original-commit: 9dcbc420f50ece3356dff57cbdc467c7893ff2c2 Signed-off-by: Tiffany Chang <tic@odoo.com>
This commit is contained in:
@@ -368,7 +368,9 @@ class StockMoveLine(models.Model):
|
||||
# TODO: make package levels less of a pain and fix this
|
||||
package_level = ml.package_level_id
|
||||
ml.package_level_id = False
|
||||
package_level.unlink()
|
||||
# Only need to unlink the package level if it's empty. Otherwise will unlink it to still valid move lines.
|
||||
if not package_level.move_line_ids:
|
||||
package_level.unlink()
|
||||
|
||||
# When we try to write on a reserved move line any fields from `triggers` or directly
|
||||
# `reserved_uom_qty` (the actual reserved quantity), we need to make sure the associated
|
||||
|
||||
@@ -1263,3 +1263,69 @@ class TestPacking(TestPackingCommon):
|
||||
self.assertEqual(picking.state, 'done')
|
||||
self.assertEqual(picking.move_ids.quantity_done, 0.4)
|
||||
self.assertEqual(len(picking.move_line_ids.result_package_id), 2)
|
||||
|
||||
def test_put_out_of_pack_transfer(self):
|
||||
""" When a transfer has multiple products all in the same package, removing a product from the destination package
|
||||
(i.e. removing it from the package but still putting it in the same location) shouldn't remove it for other products. """
|
||||
loc_1 = self.env['stock.location'].create({
|
||||
'name': 'Location A',
|
||||
'location_id': self.stock_location.id,
|
||||
})
|
||||
loc_2 = self.env['stock.location'].create({
|
||||
'name': 'Location B',
|
||||
'location_id': self.stock_location.id,
|
||||
})
|
||||
pack = self.env['stock.quant.package'].create({'name': 'New Package'})
|
||||
self.env['stock.quant']._update_available_quantity(self.productA, loc_1, 5, package_id=pack)
|
||||
self.env['stock.quant']._update_available_quantity(self.productB, loc_1, 4, package_id=pack)
|
||||
|
||||
picking = self.env['stock.picking'].create({
|
||||
'location_id': loc_1.id,
|
||||
'location_dest_id': loc_2.id,
|
||||
'picking_type_id': self.warehouse.int_type_id.id,
|
||||
})
|
||||
moveA = self.env['stock.move'].create({
|
||||
'name': self.productA.name,
|
||||
'product_id': self.productA.id,
|
||||
'product_uom_qty': 5,
|
||||
'product_uom': self.productA.uom_id.id,
|
||||
'picking_id': picking.id,
|
||||
'location_id': loc_1.id,
|
||||
'location_dest_id': loc_2.id,
|
||||
})
|
||||
moveB = self.env['stock.move'].create({
|
||||
'name': self.productB.name,
|
||||
'product_id': self.productB.id,
|
||||
'product_uom_qty': 4,
|
||||
'product_uom': self.productB.uom_id.id,
|
||||
'picking_id': picking.id,
|
||||
'location_id': loc_1.id,
|
||||
'location_dest_id': loc_2.id,
|
||||
})
|
||||
# Check availabilities
|
||||
picking.action_assign()
|
||||
self.assertEqual(len(moveA.move_line_ids), 1, "A move line should have been created for the reservation of the package.")
|
||||
self.assertEqual(moveA.move_line_ids.package_id.id, pack.id, "The package should have been reserved for both products.")
|
||||
self.assertEqual(moveB.move_line_ids.package_id.id, pack.id, "The package should have been reserved for both products.")
|
||||
pack_level = moveA.move_line_ids.package_level_id
|
||||
|
||||
# Remove the product A from the package in the destination.
|
||||
moveA.move_line_ids.result_package_id = False
|
||||
self.assertEqual(moveA.move_line_ids.result_package_id.id, False, "No package should be linked in the destination.")
|
||||
self.assertEqual(moveA.move_line_ids.package_level_id.id, False, "Package level should have been unlinked from this move line.")
|
||||
self.assertEqual(moveB.move_line_ids.result_package_id.id, pack.id, "Package should have stayed the same.")
|
||||
self.assertEqual(moveB.move_line_ids.package_level_id.id, pack_level.id, "Package level should have stayed the same.")
|
||||
|
||||
# Validate the picking
|
||||
moveA.move_line_ids.qty_done = 5
|
||||
moveB.move_line_ids.qty_done = 4
|
||||
picking.button_validate()
|
||||
|
||||
# Check that the quants have their expected location/package/quantities
|
||||
quantA = self.env['stock.quant'].search([('product_id', '=', self.productA.id), ('location_id', '=', loc_2.id)])
|
||||
quantB = self.env['stock.quant'].search([('product_id', '=', self.productB.id), ('location_id', '=', loc_2.id)])
|
||||
self.assertEqual(pack.location_id.id, loc_2.id, "Package should have been moved to Location B.")
|
||||
self.assertEqual(quantA.quantity, 5, "All 5 units of product A should be in location B")
|
||||
self.assertEqual(quantA.package_id.id, False, "There should be no package for product A as it was removed in the move.")
|
||||
self.assertEqual(quantB.quantity, 4, "All 4 units of product B should be in location B")
|
||||
self.assertEqual(quantB.package_id.id, pack.id, "Product B should still be in the initial package.")
|
||||
|
||||
Reference in New Issue
Block a user