Skip to content

Commit

Permalink
[FIX] sale_product_pack: adjust discount formula for detailed packs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lef-adhoc committed Jan 30, 2025
1 parent edc63a6 commit ead3758
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
16 changes: 10 additions & 6 deletions sale_product_pack/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,20 @@ def _get_pack_line_discount(self):
"""returns the discount settled in the parent pack lines"""
self.ensure_one()
discount = 0.0
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
break
for pack_line in self.pack_parent_line_id.product_id.pack_line_ids:
if pack_line.product_id == self.product_id:
discount = 100.0 - (
(100.0 - self.discount) * (100.0 - pack_line.sale_discount) / 100.0
)
break
return discount

@api.depends("product_id", "product_uom", "product_uom_qty")
def _compute_discount(self):
res = super()._compute_discount()
for pack_line in self.filtered("pack_parent_line_id"):
for pack_line in self.filtered(
lambda x: x.pack_parent_line_id
and x.pack_parent_line_id.pack_component_price == "detailed"
):
pack_line.discount = pack_line._get_pack_line_discount()
return res
34 changes: 34 additions & 0 deletions sale_product_pack/tests/test_sale_product_pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
)

0 comments on commit ead3758

Please sign in to comment.