From 61e1c31511473fa907a98b77e50bee0c98493935 Mon Sep 17 00:00:00 2001 From: Alessandro Uffreduzzi Date: Fri, 14 Jun 2024 15:57:01 +0200 Subject: [PATCH 1/2] [FIX] mrp_bom_attribute_match: fix unfolded print Fix an error with the unfolded print of a BOM using attribute matching. --- .../reports/mrp_report_bom_structure.py | 87 ++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) 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 b4b82c5dc..d50686063 100644 --- a/mrp_bom_attribute_match/reports/mrp_report_bom_structure.py +++ b/mrp_bom_attribute_match/reports/mrp_report_bom_structure.py @@ -1,7 +1,7 @@ # Copyright 2023 Camptocamp SA (https://www.camptocamp.com). # @author Iván Todorovich # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import models +from odoo import _, models from odoo.tools import float_round @@ -109,3 +109,88 @@ class ReportBomStructure(models.AbstractModel): ) price += company.currency_id.round(not_rounded_price) return price + + def _get_pdf_line( + self, + bom_id, + product_id=False, + qty=1, + child_bom_ids=[], # noqa: B006 + unfolded=False, + ): # pylint: disable=dangerous-default-value + """Override to tweak get_sub_lines and calculate product and child_bom""" + + def get_sub_lines(bom, product_id, line_qty, line_id, level): + data = self._get_bom( + bom_id=bom.id, + product_id=product_id, + line_qty=line_qty, + line_id=line_id, + level=level, + ) + bom_lines = data["components"] + lines = [] + for bom_line in bom_lines: + lines.append( + { + "name": bom_line["prod_name"], + "type": "bom", + "quantity": bom_line["prod_qty"], + "uom": bom_line["prod_uom"], + "prod_cost": bom_line["prod_cost"], + "bom_cost": bom_line["total"], + "level": bom_line["level"], + "code": bom_line["code"], + "child_bom": bom_line["child_bom"], + "prod_id": bom_line["prod_id"], + } + ) + if bom_line["child_bom"] and ( + unfolded or bom_line["child_bom"] in child_bom_ids + ): + line = self.env["mrp.bom.line"].browse(bom_line["line_id"]) + # start difference + bom_product = self.env["product.product"].browse(int(product_id)) + product = bom._get_component_template_product( + line, bom_product, line.product_id + ) + child_bom = self.env["mrp.bom"].browse(bom_line["child_bom"]) + lines += get_sub_lines( + child_bom, product.id, bom_line["prod_qty"], line, level + 1 + ) + # end difference + if data["operations"]: + lines.append( + { + "name": _("Operations"), + "type": "operation", + "quantity": data["operations_time"], + "uom": _("minutes"), + "bom_cost": data["operations_cost"], + "level": level, + } + ) + for operation in data["operations"]: + if unfolded or "operation-" + str(bom.id) in child_bom_ids: + lines.append( + { + "name": operation["name"], + "type": "operation", + "quantity": operation["duration_expected"], + "uom": _("minutes"), + "bom_cost": operation["total"], + "level": level + 1, + } + ) + return lines + + bom = self.env["mrp.bom"].browse(bom_id) + product_id = ( + product_id or bom.product_id.id or bom.product_tmpl_id.product_variant_id.id + ) + + data = self._get_bom(bom_id=bom_id, product_id=product_id, line_qty=qty) + pdf_lines = get_sub_lines(bom, product_id, qty, False, 1) + data["components"] = [] + data["lines"] = pdf_lines + return data From 88185c7cba091dd160f1bf25605ff7bdd4bd6c9b Mon Sep 17 00:00:00 2001 From: Ilyas Date: Mon, 17 Jun 2024 17:07:05 +0500 Subject: [PATCH 2/2] [IMP] mrp_bom_attribute_match: tests --- .../test_mrp_bom_attribute_match_nested.py | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match_nested.py b/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match_nested.py index 7865fb5d4..a7ef1f2f9 100644 --- a/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match_nested.py +++ b/mrp_bom_attribute_match/tests/test_mrp_bom_attribute_match_nested.py @@ -81,7 +81,42 @@ class TestMrpBomAttributeMatchNested(TestMrpBomAttributeMatchBase): ) def test_nested(self): + self.env["mrp.routing.workcenter"].create( + [ + { + "name": "Operation 1", + "workcenter_id": self.env.ref("mrp.mrp_workcenter_1").id, + "bom_id": self.bom_top.id, + }, + { + "name": "Operation 2", + "workcenter_id": self.env.ref("mrp.mrp_workcenter_2").id, + "bom_id": self.bom_top.id, + }, + { + "name": "Operation 1", + "workcenter_id": self.env.ref("mrp.mrp_workcenter_1").id, + "bom_id": self.bom_sub.id, + }, + { + "name": "Operation 2", + "workcenter_id": self.env.ref("mrp.mrp_workcenter_2").id, + "bom_id": self.bom_sub.id, + }, + ] + ) BomStructureReport = self.env["report.mrp.report_bom_structure"] - + values_top = BomStructureReport._get_report_values( + self.bom_top.ids, + data={"variant": self.bom_top.product_tmpl_id.product_variant_id.id}, + ) + values_sub = BomStructureReport._get_report_values( + self.bom_sub.ids, + data={"variant": self.bom_sub.product_tmpl_id.product_variant_id.id}, + ) + self.assertIn("Sub Sub 1", str(values_top["docs"][0]["lines"])) + self.assertIn("Sub-Level", str(values_top["docs"][0]["lines"])) + self.assertIn("Sub Sub 1", str(values_sub["docs"][0]["lines"])) + self.assertNotIn("Sub-Level", str(values_sub["docs"][0]["lines"])) BomStructureReport._get_report_data(self.bom_sub.id) BomStructureReport._get_report_data(self.bom_top.id)