[FIX] stock,mrp: change procure method at cancellation
Usecase : sell a mto/manufacture product. Confirm the sale order.
Cancel the delivery and the production then
duplicate the delivery.
- if the delivery was cancelled before the production, another
production is created.
- if the delivery was cancelled after the production, no other
production is created.
In the second case, the production cancellation will reset the procure
method of the delivery. The duplication will not trigger the mto
procurement.
This commit will override the procure method of each cancelled moves and
set it to `make_to_stock'. This way, we have the same behavior independently of the flow.
Task : 2212125
closes odoo/odoo#48366
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
This commit is contained in:
@@ -1539,3 +1539,111 @@ class TestSaleMrpFlow(AccountTestCommon):
|
||||
mo = self.env['mrp.production'].search([('product_id', '=', finished_product.id)])
|
||||
|
||||
self.assertTrue(mo, 'Manufacturing order created.')
|
||||
|
||||
def test_cancel_flow_1(self):
|
||||
""" Sell a MTO/manufacture product.
|
||||
|
||||
Cancel the delivery and the production order. Then duplicate
|
||||
the delivery. Another production order should be created."""
|
||||
route_manufacture = self.warehouse.manufacture_pull_id.route_id.id
|
||||
route_mto = self.warehouse.mto_pull_id.route_id.id
|
||||
self.uom_unit = self.env.ref('uom.product_uom_unit')
|
||||
|
||||
# Create finished product
|
||||
finished_product = self.env['product.product'].create({
|
||||
'name': 'Geyser',
|
||||
'type': 'product',
|
||||
'route_ids': [(4, route_mto), (4, route_manufacture)],
|
||||
})
|
||||
|
||||
product_raw = self.env['product.product'].create({
|
||||
'name': 'raw Geyser',
|
||||
'type': 'product',
|
||||
})
|
||||
|
||||
# Create bom for finish product
|
||||
bom = self.env['mrp.bom'].create({
|
||||
'product_id': finished_product.id,
|
||||
'product_tmpl_id': finished_product.product_tmpl_id.id,
|
||||
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [(5, 0), (0, 0, {'product_id': product_raw.id})]
|
||||
})
|
||||
|
||||
# Create sale order
|
||||
sale_form = Form(self.env['sale.order'])
|
||||
sale_form.partner_id = self.env['res.partner'].create({'name': 'My Test Partner'})
|
||||
with sale_form.order_line.new() as line:
|
||||
line.name = finished_product.name
|
||||
line.product_id = finished_product
|
||||
line.product_uom_qty = 1.0
|
||||
line.product_uom = self.uom_unit
|
||||
line.price_unit = 10.0
|
||||
sale_order = sale_form.save()
|
||||
|
||||
sale_order.action_confirm()
|
||||
|
||||
mo = self.env['mrp.production'].search([('product_id', '=', finished_product.id)])
|
||||
delivery = sale_order.picking_ids
|
||||
delivery.action_cancel()
|
||||
mo.action_cancel()
|
||||
copied_delivery = delivery.copy()
|
||||
copied_delivery.action_confirm()
|
||||
mos = self.env['mrp.production'].search([('product_id', '=', finished_product.id)])
|
||||
self.assertEqual(len(mos), 1)
|
||||
self.assertEqual(mos.state, 'cancel')
|
||||
|
||||
def test_cancel_flow_2(self):
|
||||
""" Sell a MTO/manufacture product.
|
||||
|
||||
Cancel the production order and the delivery. Then duplicate
|
||||
the delivery. Another production order should be created."""
|
||||
route_manufacture = self.warehouse.manufacture_pull_id.route_id.id
|
||||
route_mto = self.warehouse.mto_pull_id.route_id.id
|
||||
self.uom_unit = self.env.ref('uom.product_uom_unit')
|
||||
|
||||
# Create finished product
|
||||
finished_product = self.env['product.product'].create({
|
||||
'name': 'Geyser',
|
||||
'type': 'product',
|
||||
'route_ids': [(4, route_mto), (4, route_manufacture)],
|
||||
})
|
||||
|
||||
product_raw = self.env['product.product'].create({
|
||||
'name': 'raw Geyser',
|
||||
'type': 'product',
|
||||
})
|
||||
|
||||
# Create bom for finish product
|
||||
bom = self.env['mrp.bom'].create({
|
||||
'product_id': finished_product.id,
|
||||
'product_tmpl_id': finished_product.product_tmpl_id.id,
|
||||
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'normal',
|
||||
'bom_line_ids': [(5, 0), (0, 0, {'product_id': product_raw.id})]
|
||||
})
|
||||
|
||||
# Create sale order
|
||||
sale_form = Form(self.env['sale.order'])
|
||||
sale_form.partner_id = self.env['res.partner'].create({'name': 'My Test Partner'})
|
||||
with sale_form.order_line.new() as line:
|
||||
line.name = finished_product.name
|
||||
line.product_id = finished_product
|
||||
line.product_uom_qty = 1.0
|
||||
line.product_uom = self.uom_unit
|
||||
line.price_unit = 10.0
|
||||
sale_order = sale_form.save()
|
||||
|
||||
sale_order.action_confirm()
|
||||
|
||||
mo = self.env['mrp.production'].search([('product_id', '=', finished_product.id)])
|
||||
delivery = sale_order.picking_ids
|
||||
mo.action_cancel()
|
||||
delivery.action_cancel()
|
||||
copied_delivery = delivery.copy()
|
||||
copied_delivery.action_confirm()
|
||||
mos = self.env['mrp.production'].search([('product_id', '=', finished_product.id)])
|
||||
self.assertEqual(len(mos), 1)
|
||||
self.assertEqual(mos.state, 'cancel')
|
||||
|
||||
@@ -541,7 +541,7 @@ class StockMove(models.Model):
|
||||
self.ensure_one()
|
||||
|
||||
picking_type_id = self.picking_type_id or self.picking_id.picking_type_id
|
||||
|
||||
|
||||
# If "show suggestions" is not checked on the picking type, we have to filter out the
|
||||
# reserved move lines. We do this by displaying `move_line_nosuggest_ids`. We use
|
||||
# different views to display one field or another so that the webclient doesn't have to
|
||||
@@ -1291,7 +1291,12 @@ class StockMove(models.Model):
|
||||
if all(state in ('done', 'cancel') for state in siblings_states):
|
||||
move.move_dest_ids.write({'procure_method': 'make_to_stock'})
|
||||
move.move_dest_ids.write({'move_orig_ids': [(3, move.id, 0)]})
|
||||
self.write({'state': 'cancel', 'move_orig_ids': [(5, 0, 0)], 'delay_alert_date': False})
|
||||
self.write({
|
||||
'state': 'cancel',
|
||||
'move_orig_ids': [(5, 0, 0)],
|
||||
'delay_alert_date': False,
|
||||
'procure_method': 'make_to_stock',
|
||||
})
|
||||
return True
|
||||
|
||||
def _prepare_extra_move_vals(self, qty):
|
||||
|
||||
Reference in New Issue
Block a user