[FIX] stock: transfer the package level to backorder

The packages reservations are not correctly done in case of a backorder

To reproduce the issue:
(Use demo data)
1. In Settings, enable:
    - Delivery Packages
    - Multi-Step Routes
2. Edit the warehouse:
    - Outgoing Shipments: 2 steps
3. In Operations Types > Delivery Order, enable:
    - Show Detailed Operations
    - Move Entire Packages
4. Create a Pick P:
    - 1 x [DESK0004] Desk
    - 1 x Large Cabinet
5. Put each product in a separate pack
6. Validate P
7. Create a Delivery Order (Planned Transfer):
    - 1 x [DESK0004] Desk
    - 1 x Large Cabinet
8. Mark as TODO, Check Availability
9. In Detailed Operations, mark one of the packs as Done
10. Validate the DO, Create a backorder

Error: The not-yet-done pack is still on the delivery order and its
status is "Reserved". This line shouldn't be present anymore. Moreover,
the backorder has a line for this pack, its state is "Draft" (instead of
"Reserved") and the state of the BO is Ready.

When creating the backorder, the packages levels of the not-yet-done
moves are transferred to the new picking (i.e., the backorder) However,
these moves does not have a package level defined (due to
9d758fa2e1). Therefore, when checking the
packs:
https://github.com/odoo/odoo/blob/e7450bee8f018a5334d9628235824f2fc6f32cec/addons/stock/models/stock_picking.py#L822-L832
`package_level_ids` is empty, so a new `stock.package_level` is created
(instead of using the one of the initial delivery order). And
`move_lines_to_pack` is empty too, so the new `stock.package_level`
won't have any move lines and its state will be "Draft"

We should rather transfer the package levels of the moves' lines.

OPW-2659176
closes #77509

closes odoo/odoo#80072

X-original-commit: 4fd5cd6f940575090021dedd2159d050b594dd69
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
Co-authored-by: Adrien Widart <awt@odoo.com>
Co-authored-by: Florent de Labarre <florent.mirieu@gmail.com>
This commit is contained in:
Adrien Widart
2021-11-19 13:37:29 +00:00
co-authored by Florent de Labarre
parent 8e049f4f26
commit f53b702071
2 changed files with 59 additions and 1 deletions
+1 -1
View File
@@ -1133,7 +1133,7 @@ class Picking(models.Model):
body=_('The backorder <a href=# data-oe-model=stock.picking data-oe-id=%d>%s</a> has been created.') % (
backorder_picking.id, backorder_picking.name))
moves_to_backorder.write({'picking_id': backorder_picking.id})
moves_to_backorder.mapped('package_level_id').write({'picking_id':backorder_picking.id})
moves_to_backorder.move_line_ids.package_level_id.write({'picking_id':backorder_picking.id})
moves_to_backorder.mapped('move_line_ids').write({'picking_id': backorder_picking.id})
backorders |= backorder_picking
if backorder_picking.picking_type_id.reservation_method == 'at_confirm':
+58
View File
@@ -831,3 +831,61 @@ class TestPacking(TestPackingCommon):
self.assertEqual(receipt.state, 'assigned')
receipt.move_ids_without_package[1].product_uom_qty = 0
self.assertEqual(receipt.state, 'assigned')
def test_2_steps_and_backorder(self):
""" When creating a backorder with a package, the latter should be reserved in the new picking. Moreover,
the initial picking shouldn't have any line about this package """
def create_picking(pick_type, from_loc, to_loc):
picking = self.env['stock.picking'].create({
'picking_type_id': pick_type.id,
'location_id': from_loc.id,
'location_dest_id': to_loc.id,
})
move_A, move_B = self.env['stock.move'].create([{
'name': self.productA.name,
'product_id': self.productA.id,
'product_uom_qty': 1,
'product_uom': self.productA.uom_id.id,
'picking_id': picking.id,
'location_id': from_loc.id,
'location_dest_id': to_loc.id,
}, {
'name': self.productB.name,
'product_id': self.productB.id,
'product_uom_qty': 1,
'product_uom': self.productB.uom_id.id,
'picking_id': picking.id,
'location_id': from_loc.id,
'location_dest_id': to_loc.id,
}])
picking.action_confirm()
picking.action_assign()
return picking, move_A, move_B
self.warehouse.delivery_steps = 'pick_ship'
pick_type = self.warehouse.pick_type_id
delivery_type = self.warehouse.out_type_id
self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 1)
self.env['stock.quant']._update_available_quantity(self.productB, self.stock_location, 1)
picking, moveA, moveB = create_picking(pick_type, pick_type.default_location_src_id, pick_type.default_location_dest_id)
moveA.move_line_ids.qty_done = 1
picking.action_put_in_pack()
moveB.move_line_ids.qty_done = 1
picking.action_put_in_pack()
picking.button_validate()
picking, _, _ = create_picking(delivery_type, delivery_type.default_location_src_id, self.customer_location)
packB = picking.package_level_ids[1]
with Form(picking) as picking_form:
with picking_form.package_level_ids_details.edit(0) as package_level:
package_level.is_done = True
action_data = picking.button_validate()
backorder_wizard = Form(self.env['stock.backorder.confirmation'].with_context(action_data['context'])).save()
backorder_wizard.process()
bo = self.env['stock.picking'].search([('backorder_id', '=', picking.id)])
self.assertNotIn(packB, picking.package_level_ids)
self.assertEqual(packB, bo.package_level_ids)
self.assertEqual(bo.package_level_ids.state, 'assigned')