[FIX] mrp: split the MO into the correct quantity

Steps to Reproduce the Bug:
- Create a BoM:
    - Product: P1, Quantity: 1 unit
    - Component:
        - C1, Quantity: 1 unit

- Create a MO to produce 10 units of P1:
    - This requires 10 units of C1
- In draft state, split the quantity into 10

**Problem:**
The created MOs have component quantities of 0.1 instead of 1.

When the MO is split, we update the product quantity of the original MO
to 1, which triggers the `_compute_move_raw_ids` because it depends on
the product_qty of the MO. Therefore, the move will be updated to 1.
https://github.com/odoo/odoo/blob/17.0/addons/mrp/models/mrp_production.py#L1793

Subsequently, the factor is calculated based on the `move_qty` and the
`qty_initial` of the MO.
https://github.com/odoo/odoo/blob/17.0/addons/mrp/models/mrp_production.py#L1828

Factor = 1 / 10 = 0.1

Afterwards, this quantity is set on the original move and the backorder
moves:
https://github.com/odoo/odoo/blob/17.0/addons/mrp/models/mrp_production.py#L1830
https://github.com/odoo/odoo/blob/17.0/addons/mrp/models/mrp_production.py#L1835

opw-3825708

closes odoo/odoo#159713

X-original-commit: 10554f3a3e28374c460a475a4908015aeb8a81cc
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
2024-03-29 09:12:21 +00:00
parent a04942c9aa
commit e59f37999a
2 changed files with 22 additions and 2 deletions
+2 -2
View File
@@ -746,7 +746,7 @@ class MrpProduction(models.Model):
@api.depends('company_id', 'bom_id', 'product_id', 'product_qty', 'product_uom_id', 'location_src_id')
def _compute_move_raw_ids(self):
for production in self:
if production.state != 'draft':
if production.state != 'draft' or self.env.context.get('skip_compute_move_raw_ids'):
continue
list_move_raw = [Command.link(move.id) for move in production.move_raw_ids.filtered(lambda m: not m.bom_line_id)]
if not production.bom_id and not production._origin.product_id:
@@ -1790,7 +1790,7 @@ class MrpProduction(models.Model):
(production.move_raw_ids | production.move_finished_ids).origin = production._get_origin()
backorder_vals = production.copy_data(default=production._get_backorder_mo_vals())[0]
backorder_qtys = amounts[production][1:]
production.product_qty = amounts[production][0]
production.with_context(skip_compute_move_raw_ids=True).product_qty = amounts[production][0]
next_seq = max(production.procurement_group_id.mrp_production_ids.mapped("backorder_sequence"), default=1)
+20
View File
@@ -607,6 +607,26 @@ class TestMrpProductionBackorder(TestMrpCommon):
# The backorder is re reserved depending on the picking type
self.assertEqual(backorder.reserve_visible, False)
def test_split_mo(self):
"""
Test that an MO is split correctly.
BoM: 1 finished product = 0.5 comp1 + 1 comp2
"""
mo = self.env['mrp.production'].create({
'product_qty': 10,
'bom_id': self.bom_1.id,
})
self.assertEqual(mo.move_raw_ids.mapped('product_uom_qty'), [5, 10])
self.assertEqual(mo.state, 'draft')
action = mo.action_split()
wizard = Form(self.env[action['res_model']].with_context(action['context']))
wizard.counter = 10
action = wizard.save().action_split()
# check that the MO is split in 10 and the components are split accordingly
self.assertEqual(len(mo.procurement_group_id.mrp_production_ids), 10)
self.assertEqual(mo.product_qty, 1)
self.assertEqual(mo.move_raw_ids.mapped('product_uom_qty'), [0.5, 1])
class TestMrpWorkorderBackorder(TransactionCase):
@classmethod