Fix tax rule calculation of negative amounts (PRETIXEU-ANN)

This commit is contained in:
Raphael Michel
2024-10-11 15:28:07 +02:00
parent 9dc38e42d8
commit 8f0a277c7b
2 changed files with 71 additions and 9 deletions

View File

@@ -304,10 +304,21 @@ class TaxRule(LoggedModel):
subtract_from_gross = Decimal('0.00') subtract_from_gross = Decimal('0.00')
rate = adjust_rate rate = adjust_rate
def _limit_subtract(base_price, subtract_from_gross):
if not subtract_from_gross:
return base_price
if base_price >= Decimal('0.00'):
# For positive prices, make sure they don't go negative because of bundles
return max(Decimal('0.00'), base_price - subtract_from_gross)
else:
# If the price is already negative, we don't really care any more
return base_price - subtract_from_gross
if rate == Decimal('0.00'): if rate == Decimal('0.00'):
gross = _limit_subtract(base_price, subtract_from_gross)
return TaxedPrice( return TaxedPrice(
net=max(Decimal('0.00'), base_price - subtract_from_gross), net=gross,
gross=max(Decimal('0.00'), base_price - subtract_from_gross), gross=gross,
tax=Decimal('0.00'), tax=Decimal('0.00'),
rate=rate, rate=rate,
name=self.name, name=self.name,
@@ -320,19 +331,14 @@ class TaxRule(LoggedModel):
base_price_is = 'net' base_price_is = 'net'
if base_price_is == 'gross': if base_price_is == 'gross':
if base_price >= Decimal('0.00'): gross = _limit_subtract(base_price, subtract_from_gross)
# For positive prices, make sure they don't go negative because of bundles
gross = max(Decimal('0.00'), base_price - subtract_from_gross)
else:
# If the price is already negative, we don't really care any more
gross = base_price - subtract_from_gross
net = round_decimal(gross - (gross * (1 - 100 / (100 + rate))), net = round_decimal(gross - (gross * (1 - 100 / (100 + rate))),
currency) currency)
elif base_price_is == 'net': elif base_price_is == 'net':
net = base_price net = base_price
gross = round_decimal((net * (1 + rate / 100)), currency) gross = round_decimal((net * (1 + rate / 100)), currency)
if subtract_from_gross: if subtract_from_gross:
gross -= subtract_from_gross gross = _limit_subtract(gross, subtract_from_gross)
net = round_decimal(gross - (gross * (1 - 100 / (100 + rate))), net = round_decimal(gross - (gross * (1 - 100 / (100 + rate))),
currency) currency)
else: else:

View File

@@ -782,3 +782,59 @@ def test_custom_rules_country_rate_subtract_from_gross(event):
rate=Decimal('100.00'), rate=Decimal('100.00'),
name='', name='',
) )
@pytest.mark.django_db
def test_no_negative_due_to_subtract_from_gross(event):
tr = TaxRule(
event=event,
rate=Decimal("19.00"),
price_includes_tax=True,
)
assert tr.tax(Decimal('100.00'), subtract_from_gross=Decimal('200.00')).gross == Decimal("0.00")
tr = TaxRule(
event=event,
rate=Decimal("0.00"),
price_includes_tax=True,
)
assert tr.tax(Decimal('100.00'), subtract_from_gross=Decimal('200.00')).gross == Decimal("0.00")
tr = TaxRule(
event=event,
rate=Decimal("19.00"),
price_includes_tax=False,
)
assert tr.tax(Decimal('100.00'), subtract_from_gross=Decimal('200.00')).gross == Decimal("0.00")
tr = TaxRule(
event=event,
rate=Decimal("19.00"),
price_includes_tax=True,
)
assert tr.tax(Decimal('100.00'), subtract_from_gross=Decimal('200.00')).gross == Decimal("0.00")
@pytest.mark.django_db
def test_allow_negative(event):
tr = TaxRule(
event=event,
rate=Decimal("19.00"),
price_includes_tax=True,
)
assert tr.tax(Decimal('-100.00')).gross == Decimal("-100.00")
tr = TaxRule(
event=event,
rate=Decimal("0.00"),
price_includes_tax=True,
)
assert tr.tax(Decimal('-100.00')).gross == Decimal("-100.00")
tr = TaxRule(
event=event,
rate=Decimal("19.00"),
price_includes_tax=False,
)
assert tr.tax(Decimal('-100.00')).gross == Decimal("-119.00")
tr = TaxRule(
event=event,
rate=Decimal("19.00"),
price_includes_tax=True,
)
assert tr.tax(Decimal('-100.00')).gross == Decimal("-100.00")