[FIX] mrp: Don't change product_qty/uom when update bom on draft MO

Fix the issue when update the bom on a draft MO, the product_qty and
product_uom_id will be reseted to 1.0 unit.
The original product_qty and product_uom_id hould be kept when update
bom.

X-original-commit: f1a397ede16c56db3410fd9c5fe387dc98c46422
Part-of: odoo/odoo#135691
This commit is contained in:
yhu-odoo
2023-09-18 10:14:10 +00:00
parent 4aaee61a5f
commit a7ec4d60e7
2 changed files with 38 additions and 8 deletions
+7 -1
View File
@@ -2207,6 +2207,8 @@ class MrpProduction(models.Model):
to the corresponding MO's components, by-products and workorders.
"""
self.ensure_one()
product_qty = self.product_qty
uom = self.product_uom_id
moves_to_unlink = self.env['stock.move']
workorders_to_unlink = self.env['mrp.workorder']
# For draft MO, all the work will be done by compute methods.
@@ -2224,6 +2226,10 @@ class MrpProduction(models.Model):
self.bom_id = bom
moves_to_unlink.unlink()
workorders_to_unlink.unlink()
if self.state == 'draft':
# we reset the product_qty/uom when the bom is changed on a draft MO
# change them back to the original value
self.write({'product_qty': product_qty, 'product_uom_id': uom.id})
return
def operation_key_values(record):
@@ -2239,7 +2245,7 @@ class MrpProduction(models.Model):
bom_byproducts_by_id = {byproduct.id: byproduct for byproduct in bom.byproduct_ids.filtered(filter_by_attributes)}
operations_by_id = {operation.id: operation for operation in bom.operation_ids.filtered(filter_by_attributes)}
# Compares the BoM's operations to the MO's workoders.
# Compares the BoM's operations to the MO's workorders.
for workorder in self.workorder_ids:
operation = operations_by_id.pop(workorder.operation_id.id, False)
if not operation:
+31 -7
View File
@@ -1372,8 +1372,9 @@ class TestBoM(TestMrpCommon):
# Creates a MO.
mo_form = Form(self.env['mrp.production'])
mo_form.bom_id = bom
mo_form.product_qty = 10
mo_1 = mo_form.save()
self.assertEqual(mo_1.move_raw_ids[0].product_uom_qty, 1)
self.assertEqual(mo_1.move_raw_ids[0].product_uom_qty, 10)
self.assertEqual(mo_1.is_outdated_bom, False)
# Update MO's component quantity.
mo_form = Form(mo_1)
@@ -1397,6 +1398,8 @@ class TestBoM(TestMrpCommon):
"By-Product and Operation were added to the BoM, it should be marked as updated")
# Call "Update BoM" action, it should reset the MO as defined by the BoM.
mo_1.action_update_bom()
self.assertEqual(mo_1.product_qty, 10,
"MO's quantity should be kept")
self.assertEqual(mo_1.is_outdated_bom, False,
"After 'Update BoM' action, MO's BoM should no longer be marked as updated")
self.assertEqual(mo_1.workorder_ids.operation_id.id, operation.id)
@@ -1417,8 +1420,8 @@ class TestBoM(TestMrpCommon):
self.assertEqual(mo_1.is_outdated_bom, False,
"After 'Update BoM' action, MO's BoM should no longer be marked as updated")
self.assertRecordValues(mo_1.move_raw_ids, [
{'bom_line_id': bom.bom_line_ids[0].id, 'product_uom_qty': bom.bom_line_ids[0].product_qty},
{'bom_line_id': bom.bom_line_ids[1].id, 'product_uom_qty': bom.bom_line_ids[1].product_qty},
{'bom_line_id': bom.bom_line_ids[0].id, 'product_uom_qty': bom.bom_line_ids[0].product_qty * 10},
{'bom_line_id': bom.bom_line_ids[1].id, 'product_uom_qty': bom.bom_line_ids[1].product_qty * 10},
])
# Updates the BoM again (replace a component by another product).
bom_form = Form(bom)
@@ -1468,22 +1471,44 @@ class TestBoM(TestMrpCommon):
component_2 = self.env['product.product'].create(dict(common_vals, name="Jar"))
bom = self.env['mrp.bom'].create({
'product_tmpl_id': finished_product.product_tmpl_id.id,
'product_qty': 1.0,
'product_qty': 2.0,
'bom_line_ids': [Command.create({'product_id': p.id, 'product_qty': 1}) for p in [component_1, component_2]],
})
# Creates a MO.
mo_form = Form(self.env['mrp.production'])
mo_form.bom_id = bom
mo_form.product_qty = 4
mo_form.product_uom_id = uom_dozen
mo_1 = mo_form.save()
mo_1.action_confirm()
self.assertRecordValues(mo_1.move_raw_ids, [{
'product_id': component_1.id, 'product_uom_qty': 24, 'product_uom': uom_unit.id,
}, {
'product_id': component_2.id, 'product_uom_qty': 24, 'product_uom': uom_unit.id,
}])
### Test draft MO ###
# Updates BOM's quantity to 1 unit
bom.product_qty = 1
self.assertEqual(mo_1.is_outdated_bom, True,
"BoM changed, it should be marked as updated.")
mo_1.action_update_bom()
self.assertRecordValues(mo_1,
[{'product_qty': 4, 'product_uom_id': uom_dozen.id}])
self.assertRecordValues(mo_1.move_raw_ids, [{
'product_id': component_1.id, 'product_uom_qty': 48, 'product_uom': uom_unit.id,
}, {
'product_id': component_2.id, 'product_uom_qty': 48, 'product_uom': uom_unit.id,
}])
### Test confirmed MO ###
mo_1.product_qty = 1
self.assertRecordValues(mo_1.move_raw_ids, [{
'product_id': component_1.id, 'product_uom_qty': 12, 'product_uom': uom_unit.id,
}, {
'product_id': component_2.id, 'product_uom_qty': 12, 'product_uom': uom_unit.id,
}])
mo_1.action_confirm()
# Updates the BoM by set the first BoM line's quantity to 2.
bom_form = Form(bom)
with bom_form.bom_line_ids.edit(0) as bom_line:
@@ -1525,7 +1550,6 @@ class TestBoM(TestMrpCommon):
self.assertEqual(mo_2.is_outdated_bom, True)
# Call "Update BoM" action, it should update the MO raw moves' quantity accordingly.
# import pudb; pudb.set_trace()
mo_2.action_update_bom()
self.assertEqual(mo_2.is_outdated_bom, False)
# As there is a difference for the second component, the quantity should