Skip to content

Commit

Permalink
[17.0][MIG] mrp_bom_attribute_match
Browse files Browse the repository at this point in the history
  • Loading branch information
ferran-S73 committed Oct 22, 2024
1 parent e8ebb9c commit 4d473d3
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 34 deletions.
3 changes: 2 additions & 1 deletion mrp_bom_attribute_match/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "BOM Attribute Match",
"version": "15.0.1.1.1",
"version": "17.0.1.0.0",
"category": "Manufacturing",
"author": "Ilyas, Ooops, Odoo Community Association (OCA)",
"summary": "Dynamic BOM component based on product attribute",
Expand All @@ -10,4 +10,5 @@
"data": [
"views/mrp_bom_views.xml",
],
"installable": True,
}
31 changes: 14 additions & 17 deletions mrp_bom_attribute_match/models/mrp_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,27 +89,25 @@ def _compute_match_on_attribute_ids(self):
@api.constrains("component_template_id")
def _check_component_attributes(self):
for rec in self:
if not rec.component_template_id:
cmp_tmpl = rec.component_template_id
if not cmp_tmpl:
continue
comp_attrs = (
rec.component_template_id.valid_product_template_attribute_line_ids.attribute_id
)
prod_attrs = (
rec.bom_id.product_tmpl_id.valid_product_template_attribute_line_ids.attribute_id
)
bom_prod = rec.bom_id.product_tmpl_id
comp_attrs = cmp_tmpl.valid_product_template_attribute_line_ids.attribute_id
prod_attrs = bom_prod.valid_product_template_attribute_line_ids.attribute_id
if not comp_attrs:
raise ValidationError(
_(
"No match on attribute has been detected for Component "
"(Product Template) %s",
rec.component_template_id.display_name,
cmp_tmpl.display_name,
)
)
if not all(attr in prod_attrs for attr in comp_attrs):
raise ValidationError(
_(
"Some attributes of the dynamic component are not included into "
"production product attributes."
"Some attributes of the dynamic component are not included into"
" production product attributes."
)
)

Expand All @@ -127,10 +125,10 @@ def _check_variants_validity(self):
if same_attrs:
raise ValidationError(
_(
"You cannot use an attribute value for attribute(s) %(attributes)s "
"in the field “Apply on Variants” as it's the same attribute used "
"in the field “Match on Attribute” related to the component "
"%(component)s.",
"You cannot use an attribute value for attribute(s) "
"%(attributes)s in the field “Apply on Variants” as it's the "
"same attribute used in the field “Match on Attribute” related "
"to the component %(component)s.",
attributes=", ".join(same_attrs.mapped("name")),
component=rec.component_template_id.name,
)
Expand Down Expand Up @@ -312,9 +310,8 @@ def _get_component_template_product(
comp_attr_ids = (
comp.valid_product_template_attribute_line_ids.attribute_id.ids
)
prod_attr_ids = (
bom_product_id.valid_product_template_attribute_line_ids.attribute_id.ids
)
valid_ptal = bom_product_id.valid_product_template_attribute_line_ids
prod_attr_ids = valid_ptal.attribute_id.ids
# check attributes
if not all(item in prod_attr_ids for item in comp_attr_ids):
_log.info(
Expand Down
3 changes: 2 additions & 1 deletion mrp_bom_attribute_match/models/mrp_production.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ def action_confirm(self):
res = super().action_confirm()
for bom_line in self.bom_id.bom_line_ids:
if bom_line.component_template_id:
# product_id was set in mrp.bom.explode for correct flow. Need to remove it.
# product_id was set in mrp.bom.explode for correct flow.
# Need to remove it.
bom_line.product_id = False
return res

Expand Down
36 changes: 30 additions & 6 deletions mrp_bom_attribute_match/reports/mrp_report_bom_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@
# @author Iván Todorovich <ivan.todorovich@camptocamp.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import Command, models
from odoo import Command, api, models


class ReportBomStructure(models.AbstractModel):
_inherit = "report.mrp.report_bom_structure"

def _get_bom_lines(self, bom, bom_quantity, product, line_id, level):
@api.model
def _get_bom_data(
self,
bom,
warehouse,
product=False,
line_qty=False,
bom_line=False,
level=0,
parent_bom=False,
parent_product=False,
index=0,
product_info=False,
ignore_stock=False,
):
# OVERRIDE to fill in the `line.product_id` if a component template is used.
# To avoid a complete override, we HACK the bom by replacing it with a virtual
# record, and modifying it's lines on-the-fly.
Expand All @@ -31,14 +45,24 @@ def _get_bom_lines(self, bom, bom_quantity, product, line_id, level):
line.product_id = line_product
if to_ignore_line_ids:
bom.bom_line_ids = [Command.unlink(id) for id in to_ignore_line_ids]
components, total = super()._get_bom_lines(
bom, bom_quantity, product, line_id, level
data = super()._get_bom_data(
bom,
warehouse,
product=product,
line_qty=line_qty,
bom_line=bom_line,
level=level,
parent_bom=parent_bom,
parent_product=parent_product,
index=index,
product_info=product_info,
ignore_stock=ignore_stock,
)
# Replace any NewId value by the real record id
# Otherwise it's evaluated as False in some situations, and it may cause issues
if has_template_lines:
for component in components:
for component in data.get("components", []):
for key, value in component.items():
if isinstance(value, models.NewId):
component[key] = value.origin
return components, total
return data
3 changes: 2 additions & 1 deletion mrp_bom_attribute_match/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def setUpClass(cls):
"value_ids": [Command.set(cls.product_attribute.value_ids.ids)],
}
)
cls.env.ref("uom.group_uom").write({"users": [(Command.link(cls.env.user.id))]})
# Create boms
cls.bom_id = cls._create_bom(
cls.product_sword,
Expand Down Expand Up @@ -162,7 +163,7 @@ def _create_bom(cls, product, line_form_vals):
for vals in line_form_vals:
with form.bom_line_ids.new() as line_form:
for key, value in vals.items():
field = line_form._model._fields.get(key)
field = cls.env["mrp.bom.line"]._fields.get(key)
if field and field.relational: # pragma: no cover
if value and not isinstance(value, BaseModel):
value = cls.env[field.comodel_name].browse(value)
Expand Down
19 changes: 14 additions & 5 deletions mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from odoo import Command
from odoo.exceptions import UserError, ValidationError
from odoo.tests import Form

Expand Down Expand Up @@ -54,7 +55,7 @@ def test_bom_2(self):
"product_tmpl_id": self.product_plastic.id,
"value_ids": [(4, orchid_attribute_value_id.id)],
}
self.product_plastic.write({"attribute_line_ids": [(0, 0, vals)]})
self.product_plastic.write({"attribute_line_ids": [(Command.create(vals))]})
mrp_bom_form = Form(self.env["mrp.bom"])
mrp_bom_form.product_tmpl_id = self.product_sword
with mrp_bom_form.bom_line_ids.new() as line_form:
Expand All @@ -64,6 +65,8 @@ def test_bom_2(self):
r"production product attributes\.",
):
line_form.component_template_id = self.product_plastic
line_form.component_template_id = self.env["product.template"]
line_form.product_id = self.product_plastic.product_variant_ids[0]
plastic_smells_like_orchid.unlink()

def test_manufacturing_order_1(self):
Expand Down Expand Up @@ -175,13 +178,19 @@ def test_mrp_report_bom_structure(self):
res = BomStructureReport._get_report_data(self.bom_id.id)
self.assertTrue(res["is_variant_applied"])
self.assertEqual(res["lines"]["product"], sword_cyan)
product_l1 = self.env["product.product"].browse(
res["lines"]["components"][0]["product_id"]
)
product_l2 = self.env["product.product"].browse(
res["lines"]["components"][1]["product_id"]
)
self.assertEqual(
res["lines"]["components"][0]["line_id"],
self.bom_id.bom_line_ids[0].id,
product_l1.product_tmpl_id,
self.bom_id.bom_line_ids[0].component_template_id,
)
self.assertEqual(
res["lines"]["components"][1]["line_id"],
self.bom_id.bom_line_ids[1].id,
product_l2,
self.bom_id.bom_line_ids[1].product_id,
)
self.assertEqual(
res["lines"]["components"][0]["parent_id"],
Expand Down
10 changes: 7 additions & 3 deletions mrp_bom_attribute_match/views/mrp_bom_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@
expr="//field[@name='bom_line_ids']//field[@name='product_id']"
position="attributes"
>
<attribute name="attrs">
{'readonly': [('component_template_id', '!=', False)]}
</attribute>
<attribute name="readonly">component_template_id</attribute>
<attribute name="force_save">"1"</attribute>
</xpath>
<xpath
expr="//field[@name='bom_line_ids']//field[@name='product_uom_id']"
position="attributes"
>
<attribute name="force_save">"1"</attribute>
</xpath>
</field>
Expand Down

0 comments on commit 4d473d3

Please sign in to comment.