diff --git a/addons/stock/models/stock_package_level.py b/addons/stock/models/stock_package_level.py index 8dd5bbd2c71..e7f2191be68 100644 --- a/addons/stock/models/stock_package_level.py +++ b/addons/stock/models/stock_package_level.py @@ -64,9 +64,10 @@ class StockPackageLevel(models.Model): 'move_id': corresponding_move.id, }) else: - package_level.move_line_ids.write({'qty_done': 0}) + package_level.move_line_ids.filtered(lambda ml: ml.product_qty == 0).unlink() + package_level.move_line_ids.filtered(lambda ml: ml.product_qty != 0).write({'qty_done': 0}) - @api.depends('move_line_ids') + @api.depends('move_line_ids', 'move_line_ids.package_id', 'move_line_ids.result_package_id') def _compute_fresh_pack(self): for package_level in self: if not package_level.move_line_ids or all(ml.package_id and ml.package_id == ml.result_package_id for ml in package_level.move_line_ids): @@ -168,14 +169,14 @@ class StockPackageLevel(models.Model): all_in = False return all_in - @api.depends('state', 'move_line_ids') + @api.depends('state', 'move_ids', 'move_line_ids') def _compute_location_id(self): for pl in self: if pl.state == 'new' or pl.is_fresh_package: pl.location = False - elif pl.state in ('draft', 'cancel'): - pl.location_id = pl.picking_id.location_id elif pl.state == 'confirmed' and pl.move_ids: pl.location_id = pl.move_ids[0].location_id elif pl.state in ('assigned', 'done') and pl.move_line_ids: pl.location_id = pl.move_line_ids[0].location_id + else: + pl.location_id = pl.picking_id.location_id diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 06a4a5cb5cd..a365ed52c6c 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -561,7 +561,12 @@ class Picking(models.Model): moves = self.mapped('move_lines').filtered(lambda move: move.state not in ('draft', 'cancel', 'done')) if not moves: raise UserError(_('Nothing to check the availability for.')) + # If a package level is done when confirmed its location can be different than where it will be reserved. + # So we remove the move lines created when confirmed to set quantity done to the new reserved ones. + package_level_done = self.mapped('package_level_ids').filtered(lambda pl: pl.is_done and pl.state == 'confirmed') + package_level_done.write({'is_done': False}) moves._action_assign() + package_level_done.write({'is_done': True}) return True @api.multi diff --git a/addons/stock/tests/test_packing.py b/addons/stock/tests/test_packing.py index f8cbcb24c15..c119bd18d10 100644 --- a/addons/stock/tests/test_packing.py +++ b/addons/stock/tests/test_packing.py @@ -173,3 +173,10 @@ class TestPacking(TransactionCase): picking.do_unreserve() self.assertEqual(picking.package_level_ids.mapped('location_id.id'), [self.stock_location.id], 'The package levels should have back the original location.') + picking.package_level_ids.write({'is_done': True}) + picking.action_assign() + package_level_reserved = picking.package_level_ids.filtered(lambda pl: pl.state == 'assigned') + package_level_confirmed = picking.package_level_ids.filtered(lambda pl: pl.state == 'confirmed') + self.assertEqual(package_level_reserved.location_id.id, shelf1_location.id, 'The reserved package level must be reserved in shelf1') + self.assertEqual(package_level_confirmed.location_id.id, self.stock_location.id, 'The not reserved package should keep its location') + self.assertEqual(picking.package_level_ids.mapped('is_done'), [True, True], 'Both package should still done')