[FIX] stock: dont reassign package when removed in 3-steps delivery

In a 3-steps delivery with backorders, when removing the package in the 2nd step, it should be absent from the last step (OUT picking).
However, assigning a package on the backorder of the 1st picking and creating a new backorder reassigns the package to the OUT picking.
Settings: 3-steps delivery, packaging
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 does not have a package
- on PICK_2 picking: put 2 units in Done and put in a package, validate, create a backorder
- on PACK_1 picking: the package was reassigned to the destination package
- on OUT picking: the stock.move.line has the original package that was removed before

This fix ensures that a package can't be assigned on 'done' stock.move.line

closes odoo/odoo#123743

X-original-commit: bd2b7f816a155ea25cc8c34cd5abe599dac73c1e
Signed-off-by: Diez Stéphane (snd) <snd@odoo.com>
This commit is contained in:
snd
2023-06-06 01:13:41 +02:00
parent 1c359c3106
commit c76881ab7e
2 changed files with 61 additions and 1 deletions
@@ -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}])
+1 -1
View File
@@ -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,