[FIX] stock: scheduler run cancel MTO picking

Use case to reproduce:
- Create a sale order with a stockable product.
- Confirm the sale order.
- Validate the pick.
- Validate the pack.
- Cancel the OUT.
- Run the stock scheduler.
-> Picking are created from pick and ship.

The scheduler should not try to create missing pickings
for broken move's chain. Since v11, it's not possible to create
a partial mto chain that means if a chain is broken it's due to
a manual action from a user and thus we won't automatically
repair what he cancelled on purpose. That's why we won't create
a new move out in this case.

It also don't make sense to recreate a new mto chain from a
cancelled picking. Thus we had a condition in domain in order to
only take moves that make sense.

Based on preliminary work from Florent de Labarre <florent.mirieu@gmail.com>

Closes #23441 #23458
OPW-1820226
This commit is contained in:
Arnold Moyaux
2018-03-05 16:07:01 +01:00
parent 599f6a762e
commit 476b45eb9c
2 changed files with 46 additions and 1 deletions
+1 -1
View File
@@ -229,7 +229,7 @@ class ProcurementGroup(models.Model):
@api.model
def _get_exceptions_domain(self):
return [('procure_method', '=', 'make_to_order'), ('move_orig_ids', '=', False)]
return [('procure_method', '=', 'make_to_order'), ('move_orig_ids', '=', False), ('state', 'not in', ('cancel', 'done', 'draft'))]
@api.model
def _run_scheduler_tasks(self, use_new_cursor=False, company_id=False):
+45
View File
@@ -185,6 +185,51 @@ class TestPickShip(TestStockCommon):
# the client picking should not be assigned anymore, as we returned partially what we took
self.assertEqual(picking_client.state, 'confirmed')
def test_mto_resupply_cancel_ship(self):
""" This test simulates a pick pack ship with a resupply route
set. Pick and pack are validated, ship is cancelled. This test
ensure that new picking are not created from the cancelled
ship after the scheduler task. The supply route is only set in
order to make the scheduler run without mistakes (no next
activity).
"""
picking_pick, picking_pack, picking_ship = self.create_pick_pack_ship()
stock_location = self.env['stock.location'].browse(self.stock_location)
warehouse_1 = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.id)], limit=1)
warehouse_1.write({'delivery_steps': 'pick_pack_ship'})
warehouse_2 = self.env['stock.warehouse'].create({
'name': 'Small Warehouse',
'code': 'SWH'
})
warehouse_1.write({
'default_resupply_wh_id': warehouse_2.id,
'resupply_wh_ids': [(6, 0, [warehouse_2.id])]
})
resupply_route = self.env['stock.location.route'].search([('supplier_wh_id', '=', warehouse_2.id), ('supplied_wh_id', '=', warehouse_1.id)])
self.assertTrue(resupply_route)
self.productA.write({'route_ids': [(4, resupply_route.id), (4, self.env.ref('stock.route_warehouse0_mto').id)]})
self.env['stock.quant']._update_available_quantity(self.productA, stock_location, 10.0)
picking_pick.action_assign()
picking_pick.move_lines[0].move_line_ids[0].qty_done = 10.0
picking_pick.action_done()
picking_pack.action_assign()
picking_pack.move_lines[0].move_line_ids[0].qty_done = 10.0
picking_pack.action_done()
picking_ship.action_cancel()
picking_ship.move_lines.write({'procure_method': 'make_to_order'})
self.env['procurement.group'].run_scheduler()
next_activity = self.env['mail.activity'].search([('res_model', '=', 'product.template'), ('res_id', '=', self.productA.product_tmpl_id.id)])
self.assertEqual(picking_ship.state, 'cancel')
self.assertFalse(next_activity, 'If a next activity has been created if means that scheduler failed\
and the end of this test do not have sense.')
self.assertEqual(len(picking_ship.move_lines.mapped('move_orig_ids')), 0,
'Scheduler should not create picking pack and pick since ship has been manually cancelled.')
def test_no_backorder_1(self):
""" Check the behavior of doing less than asked in the picking pick and chosing not to
create a backorder. In this behavior, the second picking should obviously only be able to