[FIX] mrp: allow use kit as component in MO without BoM

Steps to reproduce the bug:
- Create a kit product
- Create a storable product without BoM “P1”
- Create a MO to produce one unit of “P1”
- Add the kit product as component
- confirm the MO

Problem:
The Manufacturing Order is cancelled. This is because the MO contains
a kit product, and we need to generate moves based on its Bill of
Materials. However, at the same time, we cancel and remove the move
associated with the original product, which is no longer relevant.
But We remove it before creating the moves generated from the phantom
product. Consequently, since we cancel the move, the 'compute_state'
of the MO is triggered, and as there is only one 'move_finished' status
in 'cancel,' the status of the MO is set to 'cancel:

https://github.com/odoo/odoo/blob/5c238bbb18c682ff2d25f740aad604feb7bb5bbc/addons/mrp/models/mrp_production.py#L462-L463

Opw-3548464

closes odoo/odoo#140016

X-original-commit: baa0924974fee0115a0bce117141a8096455b88d
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
This commit is contained in:
Djamel Touati
2023-11-14 13:49:18 +00:00
parent 6f599655e4
commit cf2d37ecd3
2 changed files with 32 additions and 4 deletions
+4 -4
View File
@@ -374,14 +374,14 @@ class StockMove(models.Model):
# delete the move with original product which is not relevant anymore
moves_ids_to_unlink.add(move.id)
move_to_unlink = self.env['stock.move'].browse(moves_ids_to_unlink).sudo()
move_to_unlink.quantity = 0
move_to_unlink._action_cancel()
move_to_unlink.unlink()
if phantom_moves_vals_list:
phantom_moves = self.env['stock.move'].create(phantom_moves_vals_list)
phantom_moves._adjust_procure_method()
moves_ids_to_return |= phantom_moves.action_explode().ids
move_to_unlink = self.env['stock.move'].browse(moves_ids_to_unlink).sudo()
move_to_unlink.quantity = 0
move_to_unlink._action_cancel()
move_to_unlink.unlink()
return self.env['stock.move'].browse(moves_ids_to_return)
def action_show_details(self):
+28
View File
@@ -3616,3 +3616,31 @@ class TestMrpOrder(TestMrpCommon):
warehouse.pbm_route_id.rule_ids.delay = 100
delays, _ = rule._get_lead_days(self.bom_1.product_id, bom=self.bom_1)
self.assertEqual(delays['total_delay'], self.env.company.manufacturing_lead + self.bom_1.days_to_prepare_mo + self.bom_1.produce_delay + 100 * 2)
def test_use_kit_as_component_in_production_without_bom(self):
"""
Test that a MO is not cancelled when a kit is added in a MO without a BoM.
"""
finished, component, kit = self.env['product.product'].create([{
'name': 'Product %s' % (i + 1),
'type': 'product',
} for i in range(3)])
self.env['mrp.bom'].create({
'product_id': kit.id,
'product_tmpl_id': kit.product_tmpl_id.id,
'type': 'phantom',
'bom_line_ids': [(0, 0, {
'product_id': component.id,
'product_qty': 1,
})],
})
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = finished
mo_form.product_qty = 1
with mo_form.move_raw_ids.new() as line:
line.product_id = kit
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(mo.state, 'confirmed')
self.assertEqual(mo.move_raw_ids.product_id, component)