From 07b8eff60ff328058032943b64536d9a47e70d6f Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Thu, 2 May 2019 11:42:52 +0000 Subject: [PATCH] [FIX] mrp: recursive bom with different quantities Backport from 12 to saas-11.3 (original commit : 97b44806f5121e97b62ba25da910e77e26a9424d) Having 4 products and 3 BoMs: BoM 1: product = Finished quantity = 100 units - Semi-Finished 10 units BoM 2: product = Semi-Finished quantity = 10 units - Assembly 10 units BoM 3: product = Assembly quantity = 10 units - Raw Material 10 units (product.product 5$/unit) Before this commit, the price for 100 units of Finished product was 500$, which is wrong. The price was calculated using 100 units of Semi-Finished product and not 10 units as it should be. Now, the price is 50$ opw-1973347 closes odoo/odoo#33115 Signed-off-by: Jorge Pinna Puissant (jpp) closes odoo/odoo#34900 Signed-off-by: Simon Goffin (sig) --- addons/mrp/report/mrp_report_bom_structure.py | 2 +- addons/mrp/tests/test_bom.py | 86 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/addons/mrp/report/mrp_report_bom_structure.py b/addons/mrp/report/mrp_report_bom_structure.py index f7e8a0ea6a5..5f6784278f9 100644 --- a/addons/mrp/report/mrp_report_bom_structure.py +++ b/addons/mrp/report/mrp_report_bom_structure.py @@ -171,7 +171,7 @@ class ReportBomStructure(models.AbstractModel): for line in bom.bom_line_ids: if line.child_bom_id: - qty = line.product_uom_id._compute_quantity(line.product_qty * factor, line.child_bom_id.product_uom_id) + qty = line.product_uom_id._compute_quantity(line.product_qty * factor, line.child_bom_id.product_uom_id) / line.child_bom_id.product_qty sub_price = self._get_price(line.child_bom_id, qty) price += sub_price else: diff --git a/addons/mrp/tests/test_bom.py b/addons/mrp/tests/test_bom.py index 8dcfb0cfb13..97f6ae223e1 100644 --- a/addons/mrp/tests/test_bom.py +++ b/addons/mrp/tests/test_bom.py @@ -347,3 +347,89 @@ class TestBoM(TestMrpCommon): self.assertEqual(float_compare(component_line['total'], crumble_cost, precision_digits=2), 0) # total price = 15.51 + crumble_cost + operation_cost(10 + 1.67 = 11.67) = 27.18 + crumble_cost self.assertEqual(float_compare(report_values['lines']['total'], 27.18 + crumble_cost, precision_digits=2), 0, 'Product Bom Price is not correct') + + def test_bom_report_recursive_bom(self): + """ Test report with recursive BoM and different quantities. + BoM 1: + product = Finished (units) + quantity = 100 units + - Semi-Finished 5 kg + + BoM 2: + product = Semi-Finished (kg) + quantity = 11 kg + - Assembly 2 dozens + + BoM 3: + product = Assembly (dozens) + quantity = 5 dozens + - Raw Material 4 litres (product.product 5$/litre) + + Check the Price for 80 units of Finished -> 2.92$: + """ + # Create a products templates + uom_unit = self.env.ref('uom.product_uom_unit') + uom_kg = self.env.ref('uom.product_uom_kgm') + uom_dozen = self.env.ref('uom.product_uom_dozen') + uom_litre = self.env.ref('uom.product_uom_litre') + + finished = self.env['product.product'].create({ + 'name': 'Finished', + 'type': 'product', + 'uom_id': uom_unit.id, + 'uom_po_id': uom_unit.id, + }) + + semi_finished = self.env['product.product'].create({ + 'name': 'Semi-Finished', + 'type': 'product', + 'uom_id': uom_kg.id, + 'uom_po_id': uom_kg.id, + }) + + assembly = self.env['product.product'].create({ + 'name': 'Assembly', + 'type': 'product', + 'uom_id': uom_dozen.id, + 'uom_po_id': uom_dozen.id, + }) + + raw_material = self.env['product.product'].create({ + 'name': 'Raw Material', + 'type': 'product', + 'uom_id': uom_litre.id, + 'uom_po_id': uom_litre.id, + 'standard_price': 5, + }) + + #Create bom + 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 = semi_finished + line.product_uom_id = uom_kg + line.product_qty = 5 + bom_finished = bom_finished.save() + + bom_semi_finished = Form(self.env['mrp.bom']) + bom_semi_finished.product_tmpl_id = semi_finished.product_tmpl_id + bom_semi_finished.product_qty = 11 + with bom_semi_finished.bom_line_ids.new() as line: + line.product_id = assembly + line.product_uom_id = uom_dozen + line.product_qty = 2 + bom_semi_finished = bom_semi_finished.save() + + bom_assembly = Form(self.env['mrp.bom']) + bom_assembly.product_tmpl_id = assembly.product_tmpl_id + bom_assembly.product_qty = 5 + with bom_assembly.bom_line_ids.new() as line: + line.product_id = raw_material + line.product_uom_id = uom_litre + line.product_qty = 4 + bom_assembly = bom_assembly.save() + + 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)