Open kgilpin opened 1 month ago
Title: Fix can_apply_benefit to Exclude Undiscountable Variants from Discount Calculation
Problem:
The can_apply_benefit
method incorrectly allows discounts to be applied to product variants that are not set as discountable. When both a discountable product (e.g., Product A) and a non-discountable variant (e.g., Variant B) are in the same cart, the discount is applied to both items, which should not happen.
Analysis:
The issue stems from the can_apply_benefit
method not correctly differentiating between discountable products and their non-discountable variants. The method needs to ensure that it only returns true if the product or its variant is marked as discountable.
Proposed Changes:
src/oscar/apps/offer/abstract_models.py
: Update the can_apply_benefit
method
tests/integration/offer/test_absolute_benefit.py
: Add test cases
Detailed Steps:
src/oscar/apps/offer/abstract_models.py
: Update the can_apply_benefit
method
can_apply_benefit
method should be updated to include a check that ensures products are marked as discountable before applying benefits.def can_apply_benefit(self, line):
"""
Determines whether the benefit can be applied to a given basket line
"""
product = line.product
# Ensure product and its variants are discountable
return line.stockrecord and product.is_discountable and product.get_parent().is_discountable
tests/integration/offer/test_absolute_benefit.py
: Update/Add test cases
parent_discountable_product = factories.create_product(
structure="parent", is_discountable=True
)
child = factories.create_product(
title="Undiscountable variant",
structure="child",
parent=parent_discountable_product,
is_discountable=False,
price=100,
)
benefit = SomeBenefitObject() # Example Benefit Object
line = SomeBasketLineObject() # Example Line Object
Applicator().apply(basket)
# Verify the behavior with the new logic
assert not benefit.can_apply_benefit(line.child)
These changes will ensure that discounts are correctly applied only to discountable products, preventing non-discountable variants from erroneously receiving discounts.
Original report: https://github.com/django-oscar/django-oscar/issues/4070
Issue Summary
When there are product discountable true and variant discountable false in cart in the same time, discount is calculated for variant which is incorrect.
Steps to Reproduce
Issue
When Product A and Variant B are in the same cart, discount from offer X is calculated for both lines which is incorrect.
Relevant code
Found in version
c49a21979