mirror of
https://github.com/pretix/pretix-servicefees.git
synced 2024-12-24 12:03:08 +01:00
add option to split taxes
This commit is contained in:
parent
1ad356307e
commit
17c2b40d1f
3 changed files with 53 additions and 1 deletions
|
@ -1,3 +1,4 @@
|
|||
from collections import defaultdict
|
||||
from decimal import Decimal
|
||||
|
||||
from django.urls import resolve, reverse
|
||||
|
@ -5,7 +6,7 @@ from django.dispatch import receiver
|
|||
from django.http import HttpRequest
|
||||
from django.utils.translation import gettext_lazy as _, gettext, get_language
|
||||
from pretix.base.decimal import round_decimal
|
||||
from pretix.base.models import Event, Order, TaxRule
|
||||
from pretix.base.models import CartPosition, Event, Order, TaxRule
|
||||
from pretix.base.models.orders import OrderFee
|
||||
from pretix.base.settings import settings_hierarkey
|
||||
from pretix.base.signals import order_fee_calculation
|
||||
|
@ -76,7 +77,52 @@ def get_fees(event, total, invoice_address, mod='', request=None, positions=[],
|
|||
summed += fval
|
||||
|
||||
if (fee_per_ticket or fee_abs or fee_percent) and total != Decimal('0.00'):
|
||||
tax_rule_zero = TaxRule.zero()
|
||||
fee = round_decimal(fee_abs + total * (fee_percent / 100) + len(positions) * fee_per_ticket, event.currency)
|
||||
split_taxes = event.settings.get('service_fee_split_taxes', as_type=bool)
|
||||
if split_taxes:
|
||||
# split taxes based on products ordered
|
||||
d = defaultdict(lambda: Decimal('0.00'))
|
||||
for p in positions:
|
||||
if isinstance(p, CartPosition):
|
||||
tr = p.item.tax_rule
|
||||
else:
|
||||
tr = p.tax_rule
|
||||
d[tr] += p.price - p.tax_value
|
||||
|
||||
base_values = sorted([tuple(t) for t in d.items()], key=lambda t: t[0].rate)
|
||||
sum_base = sum(t[1] for t in base_values)
|
||||
if sum_base:
|
||||
fee_values = [(t[0], round_decimal(fee * t[1] / sum_base, event.currency))
|
||||
for t in base_values]
|
||||
sum_fee = sum(t[1] for t in fee_values)
|
||||
|
||||
# If there are rounding differences, we fix them up, but always leaning to the benefit of the tax
|
||||
# authorities
|
||||
if sum_fee > fee:
|
||||
fee_values[0] = (fee_values[0][0], fee_values[0][1] + (fee - sum_fee))
|
||||
elif sum_fee < fee:
|
||||
fee_values[-1] = (fee_values[-1][0], fee_values[-1][1] + (fee - sum_fee))
|
||||
else:
|
||||
fee_values = [(event.settings.tax_rate_default or tax_rule_zero, fee)]
|
||||
|
||||
else:
|
||||
fee_values = [(event.settings.tax_rate_default or tax_rule_zero, fee)]
|
||||
|
||||
fees = []
|
||||
for tax_rule, price in fee_values:
|
||||
tax_rule = tax_rule or tax_rule_zero
|
||||
tax = tax_rule.tax(price, invoice_address=invoice_address, base_price_is='gross')
|
||||
fees.append(OrderFee(
|
||||
fee_type=OrderFee.FEE_TYPE_SERVICE,
|
||||
internal_type='',
|
||||
value=price,
|
||||
tax_rate=tax.rate,
|
||||
tax_value=tax.tax,
|
||||
tax_rule=tax_rule
|
||||
))
|
||||
return fees
|
||||
|
||||
tax_rule = event.settings.tax_rate_default or TaxRule.zero()
|
||||
tax = tax_rule.tax(fee, invoice_address=invoice_address, base_price_is='gross')
|
||||
return [OrderFee(
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
{% bootstrap_field form.service_fee_skip_free layout="control" %}
|
||||
{% bootstrap_field form.service_fee_abs addon_after=request.event.currency layout="control" %}
|
||||
{% bootstrap_field form.service_fee_percent addon_after="%" layout="control" %}
|
||||
{% bootstrap_field form.service_fee_split_taxes layout="control" %}
|
||||
{% bootstrap_field form.service_fee_skip_if_gift_card layout="control" %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
|
|
|
@ -46,6 +46,11 @@ class ServiceFeeSettingsForm(SettingsForm):
|
|||
help_text=_('Note that regardless of this setting, a per-ticket fee will not be charged if the entire order is free.'),
|
||||
required=False
|
||||
)
|
||||
service_fee_split_taxes = forms.BooleanField(
|
||||
label=_('Split taxes proportionate to the tax rates and net values of the ordered products.'),
|
||||
help_text=_('If not split based on ordered products, the tax rate falls back to the event’s base tax rate or no tax, if none is given.'),
|
||||
required=False
|
||||
)
|
||||
|
||||
service_fee_abs_resellers = forms.DecimalField(
|
||||
label=_('Fixed fee per order'),
|
||||
|
|
Loading…
Reference in a new issue