From d625a764487d6b893479b073ed7ac986056b02d5 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 | 4 ++- .../tests/test_sale_product_pack.py | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/sale_product_pack/models/sale_order_line.py b/sale_product_pack/models/sale_order_line.py index df4ebf736..a044bae8d 100644 --- a/sale_product_pack/models/sale_order_line.py +++ b/sale_product_pack/models/sale_order_line.py @@ -153,7 +153,9 @@ 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..572415143 100644 --- a/sale_product_pack/tests/test_sale_product_pack.py +++ b/sale_product_pack/tests/test_sale_product_pack.py @@ -335,3 +335,37 @@ 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("sale.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") + 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.", + )