diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index ba16938dec9..385776fc426 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -1477,3 +1477,63 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): #Check Exception error is logged on so_2 activity = self.env['mail.activity'].search([('res_id', '=', so_2.id), ('res_model', '=', 'sale.order')]) self.assertEqual(len(activity), 1, 'When no backorder is created for a partial delivery, a warning error should be logged in its origin SO') + + def test_3_steps_and_unpack(self): + """ + When removing the package of a stock.move.line mid-flow in a 3-steps delivery with backorders, make sure that + the OUT picking does not get packages again on its stock.move.line. + Steps: + - create a SO of product A for 10 units + - on PICK_1 picking: put 2 units in Done and put in a package, validate, create a backorder + - on PACK_1 picking: remove the destination package for the 2 units, validate, create a backorder + - on OUT picking: the stock.move.line should not have a package + - on PICK_2 picking: put 2 units in Done and put in a package, validate, create a backorder + - on OUT picking: the stock.move.line should still not have a package + - on PACK_2: validate, create a backorder + - on OUT picking: there should be 2 stock.move.lines, one with package and one without + """ + warehouse = self.company_data.get('default_warehouse') + self.env['res.config.settings'].write({ + 'group_stock_tracking_lot': True, + 'group_stock_adv_location': True, + 'group_stock_multi_locations': True, + }) + warehouse.delivery_steps = 'pick_pack_ship' + self.env['stock.quant']._update_available_quantity(self.test_product_delivery, warehouse.lot_stock_id, 10) + + so_1 = self._get_new_sale_order(product=self.test_product_delivery) + so_1.action_confirm() + pick_picking = so_1.picking_ids.filtered(lambda p: p.picking_type_id == warehouse.pick_type_id) + pack_picking = so_1.picking_ids.filtered(lambda p: p.picking_type_id == warehouse.pack_type_id) + out_picking = so_1.picking_ids.filtered(lambda p: p.picking_type_id == warehouse.out_type_id) + + pick_picking.move_ids.quantity_done = 2 + pick_picking.action_put_in_pack() + backorder_wizard_dict = pick_picking.button_validate() + backorder_wizard = Form(self.env[backorder_wizard_dict['res_model']].with_context(backorder_wizard_dict['context'])).save() + backorder_wizard.process() + + pack_picking.move_line_ids.result_package_id = False + pack_picking.move_ids.quantity_done = 2 + pack_picking.button_validate() + + self.assertEqual(out_picking.move_line_ids.package_id.id, False) + self.assertEqual(out_picking.move_line_ids.result_package_id.id, False) + + pick_picking_2 = so_1.picking_ids.filtered(lambda x: x.picking_type_id == warehouse.pick_type_id and x.state != 'done') + + pick_picking_2.move_ids.quantity_done = 2 + package_2 = pick_picking_2.action_put_in_pack() + backorder_wizard_dict = pick_picking_2.button_validate() + backorder_wizard = Form(self.env[backorder_wizard_dict['res_model']].with_context(backorder_wizard_dict['context'])).save() + backorder_wizard.process() + + self.assertEqual(out_picking.move_line_ids.package_id.id, False) + self.assertEqual(out_picking.move_line_ids.result_package_id.id, False) + + pack_picking_2 = so_1.picking_ids.filtered(lambda p: p.picking_type_id == warehouse.pack_type_id and p.state != 'done') + + pack_picking_2.move_ids.quantity_done = 2 + pack_picking_2.button_validate() + + self.assertRecordValues(out_picking.move_line_ids, [{'result_package_id': False}, {'result_package_id': package_2.id}]) diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 87b4eae91fb..14fd77daa5e 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -964,7 +964,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 and not ml.result_package_id) + move_lines_to_pack = picking.move_line_ids.filtered(lambda ml: ml.package_id == pack and not ml.result_package_id and ml.state not in ('done', 'cancel')) if not package_level_ids: self.env['stock.package_level'].create({ 'picking_id': picking.id,