diff --git a/mrp_bom_attribute_match/__manifest__.py b/mrp_bom_attribute_match/__manifest__.py index 7b55dcf88a7..6c63ce60a44 100644 --- a/mrp_bom_attribute_match/__manifest__.py +++ b/mrp_bom_attribute_match/__manifest__.py @@ -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", @@ -10,4 +10,5 @@ "data": [ "views/mrp_bom_views.xml", ], + "installable": True, } diff --git a/mrp_bom_attribute_match/models/mrp_bom.py b/mrp_bom_attribute_match/models/mrp_bom.py index ccb7f41604e..66a78dc1eb6 100644 --- a/mrp_bom_attribute_match/models/mrp_bom.py +++ b/mrp_bom_attribute_match/models/mrp_bom.py @@ -91,12 +91,8 @@ def _check_component_attributes(self): for rec in self: if not rec.component_template_id: 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 - ) + 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 if not comp_attrs: raise ValidationError( _( @@ -312,9 +308,7 @@ 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 - ) + prod_attr_ids = bom_product_id.valid_product_template_attribute_line_ids.attribute_id.ids # check attributes if not all(item in prod_attr_ids for item in comp_attr_ids): _log.info( diff --git a/mrp_bom_attribute_match/reports/mrp_report_bom_structure.py b/mrp_bom_attribute_match/reports/mrp_report_bom_structure.py index 3cb22891133..5f1b0109ac0 100644 --- a/mrp_bom_attribute_match/reports/mrp_report_bom_structure.py +++ b/mrp_bom_attribute_match/reports/mrp_report_bom_structure.py @@ -2,13 +2,27 @@ # @author Iván Todorovich # 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. @@ -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 diff --git a/mrp_bom_attribute_match/tests/common.py b/mrp_bom_attribute_match/tests/common.py index 40ecd0c2953..21f88d12cc7 100644 --- a/mrp_bom_attribute_match/tests/common.py +++ b/mrp_bom_attribute_match/tests/common.py @@ -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, @@ -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) diff --git a/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match.py b/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match.py index 90cbbca0595..851aceb5db2 100644 --- a/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match.py +++ b/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match.py @@ -1,3 +1,4 @@ +from odoo import Command from odoo.exceptions import UserError, ValidationError from odoo.tests import Form @@ -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: @@ -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): @@ -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"], diff --git a/mrp_bom_attribute_match/views/mrp_bom_views.xml b/mrp_bom_attribute_match/views/mrp_bom_views.xml index 3ba95fb697e..ad2a5830feb 100644 --- a/mrp_bom_attribute_match/views/mrp_bom_views.xml +++ b/mrp_bom_attribute_match/views/mrp_bom_views.xml @@ -18,9 +18,13 @@ expr="//field[@name='bom_line_ids']//field[@name='product_id']" position="attributes" > - - {'readonly': [('component_template_id', '!=', False)]} - + component_template_id + "1" + + "1"