From 1e59b8eb71ba164b248948b51afad6eb4912a65b Mon Sep 17 00:00:00 2001 From: Franco Leyes Date: Tue, 28 Jan 2025 16:20:41 -0300 Subject: [PATCH] [FIX] sale_product_pack: adjust discount formula for detailed packs The discount formula for detailed packs has been updated to address inconsistencies when pricelists explicitly display discounts. The new formula ensures accurate representation of the combined discount by correctly factoring in both the parent pack and component discounts. Example: Parent pack discount: 5% Component A discount: 10% Component B discount: 20% The issue occurred when pricelists explicitly displayed discounts. For example, when the pricelist showed the discount percentage but did not properly calculate the combined effect of the pack discount and the component discounts, the displayed total was inconsistent. With the new formula: Component A effective discount: 100.0 - ((100.0 - 5.0) * (100.0 - 10.0) / 100.0) = 14.5% Component B effective discount: 100.0 - ((100.0 - 5.0) * (100.0 - 20.0) / 100.0) = 24.0% This ensures that when pricelists explicitly show discounts, the displayed percentage matches the calculated prices. --- sale_product_pack/models/sale_order_line.py | 6 +++- .../tests/test_sale_product_pack.py | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/sale_product_pack/models/sale_order_line.py b/sale_product_pack/models/sale_order_line.py index 2486b1902..ee65663c7 100644 --- a/sale_product_pack/models/sale_order_line.py +++ b/sale_product_pack/models/sale_order_line.py @@ -153,7 +153,11 @@ def _get_pack_line_discount(self): if self.pack_parent_line_id.pack_component_price == "detailed": for pack_line in self.pack_parent_line_id.product_id.pack_line_ids: if pack_line.product_id == self.product_id: - discount = pack_line.sale_discount + discount = 100.0 - ( + (100.0 - self.discount) + * (100.0 - pack_line.sale_discount) + / 100.0 + ) break return discount diff --git a/sale_product_pack/tests/test_sale_product_pack.py b/sale_product_pack/tests/test_sale_product_pack.py index 4fbaafbc7..fc7fe6f8b 100644 --- a/sale_product_pack/tests/test_sale_product_pack.py +++ b/sale_product_pack/tests/test_sale_product_pack.py @@ -335,3 +335,38 @@ def test_create_several_lines_03(self): self.assertEqual(sequence_tp, self.sale_order.order_line[2].sequence) self.assertEqual(sequence_tp, self.sale_order.order_line[3].sequence) self.assertEqual(self.sale_order.order_line[4].product_id, product) + + def test_compute_discount_for_detailed_packs(self): + group_discount = self.env.ref("product.group_discount_per_so_line") + self.env.user.write({"groups_id": [(4, group_discount.id)]}) + product_pack = self.env.ref("product_pack.product_pack_cpu_detailed_components") + self.discount_pricelist.discount_policy = "without_discount" + sale_order = self.env["sale.order"].create( + { + "partner_id": self.env.ref("base.res_partner_12").id, + "pricelist_id": self.discount_pricelist.id, + "order_line": [ + ( + 0, + 0, + { + "product_id": product_pack.id, + "product_uom_qty": 1, + "pack_component_price": "detailed", + }, + ) + ], + } + ) + sale_order.action_update_prices() + pack_lines = sale_order.order_line.filtered( + lambda line: line.pack_parent_line_id + ) + self.assertEqual( + len(pack_lines), 3, "Expected 3 lines for the components of the pack." + ) + self.assertEqual( + pack_lines.mapped("discount"), + [19, 19, 10], + "Discounts for the pack lines are not calculated correctly.", + )