[FIX] mrp: validate BOM lines with same product as BOM

Current behavior before PR:

It is possible to create a BOM that has a BOM line that reference the
same product as the BOM itself.  This is undesirable as when we create a
manufacturing order for this product we will have an error.

It is a regression bug that was introduced in commit
575353e251a0cce3bbff759edaeb56b5718beb11 between v12 and v13.

Behavior after PR is merged:

When saving a BOM it will validate that no product line references the
same product, or the same product variant, as the BOM itself.  Note that
it is allowed to have a BOM for a product variant that references
another variant of the same product.

opw-2347941

closes odoo/odoo#59633

X-original-commit: 917e4c67b4aa14ca71ec6cba4bc6d20a86459f42
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
This commit is contained in:
Nicolas Galler
2020-10-09 12:05:27 +00:00
parent 75f21637de
commit 4c2a03aa8f
2 changed files with 75 additions and 2 deletions
+6 -2
View File
@@ -89,8 +89,12 @@ class MrpBom(models.Model):
def _check_bom_lines(self):
for bom in self:
for bom_line in bom.bom_line_ids:
if bom.product_id and bom_line.product_id == bom.product_id:
raise ValidationError(_("BoM line product %s should not be the same as BoM product.", bom.display_name))
if bom.product_id:
same_product = bom.product_id == bom_line.product_id
else:
same_product = bom.product_tmpl_id == bom_line.product_id.product_tmpl_id
if same_product:
raise ValidationError(_("BoM line product %s should not be the same as BoM product.") % bom.display_name)
if bom.product_id and bom_line.bom_product_template_attribute_value_ids:
raise ValidationError(_("BoM cannot concern product %s and have a line with attributes (%s) at the same time.")
% (bom.product_id.display_name, ", ".join([ptav.display_name for ptav in bom_line.bom_product_template_attribute_value_ids])))
+69
View File
@@ -729,3 +729,72 @@ class TestBoM(TestMrpCommon):
report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom_id=bom_finished.id, searchQty=80)
self.assertAlmostEqual(report_values['lines']['total'], 2.92)
def test_validate_no_bom_line_with_same_product(self):
"""
Cannot set a BOM line on a BOM with the same product as the BOM itself
"""
uom_unit = self.env.ref('uom.product_uom_unit')
finished = self.env['product.product'].create({
'name': 'Finished',
'type': 'product',
'uom_id': uom_unit.id,
'uom_po_id': uom_unit.id,
})
bom_finished = Form(self.env['mrp.bom'])
bom_finished.product_tmpl_id = finished.product_tmpl_id
bom_finished.product_qty = 100
with bom_finished.bom_line_ids.new() as line:
line.product_id = finished
line.product_uom_id = uom_unit
line.product_qty = 5
with self.assertRaises(exceptions.ValidationError), self.cr.savepoint():
bom_finished = bom_finished.save()
def test_validate_no_bom_line_with_same_product_variant(self):
"""
Cannot set a BOM line on a BOM with the same product variant as the BOM itself
"""
uom_unit = self.env.ref('uom.product_uom_unit')
bom_finished = Form(self.env['mrp.bom'])
bom_finished.product_tmpl_id = self.product_7_template
bom_finished.product_id = self.product_7_3
bom_finished.product_qty = 100
with bom_finished.bom_line_ids.new() as line:
line.product_id = self.product_7_3
line.product_uom_id = uom_unit
line.product_qty = 5
with self.assertRaises(exceptions.ValidationError), self.cr.savepoint():
bom_finished = bom_finished.save()
def test_validate_bom_line_with_different_product_variant(self):
"""
Can set a BOM line on a BOM with a different product variant as the BOM itself (same product)
Usecase for example A black T-shirt made from a white T-shirt and
black color.
"""
uom_unit = self.env.ref('uom.product_uom_unit')
bom_finished = Form(self.env['mrp.bom'])
bom_finished.product_tmpl_id = self.product_7_template
bom_finished.product_id = self.product_7_3
bom_finished.product_qty = 100
with bom_finished.bom_line_ids.new() as line:
line.product_id = self.product_7_2
line.product_uom_id = uom_unit
line.product_qty = 5
bom_finished = bom_finished.save()
def test_validate_bom_line_with_variant_of_bom_product(self):
"""
Can set a BOM line on a BOM with a product variant when the BOM has no variant selected
"""
uom_unit = self.env.ref('uom.product_uom_unit')
bom_finished = Form(self.env['mrp.bom'])
bom_finished.product_tmpl_id = self.product_6.product_tmpl_id
# no product_id
bom_finished.product_qty = 100
with bom_finished.bom_line_ids.new() as line:
line.product_id = self.product_7_2
line.product_uom_id = uom_unit
line.product_qty = 5
bom_finished = bom_finished.save()