Add a service fee per ticket sold

This commit is contained in:
Thomas Hollstegge 2019-05-20 14:54:27 +02:00 committed by Raphael Michel
parent 937651eb34
commit 315d6de155
3 changed files with 48 additions and 18 deletions

View file

@ -11,6 +11,7 @@ from pretix.base.signals import order_fee_calculation
from pretix.base.templatetags.money import money_filter from pretix.base.templatetags.money import money_filter
from pretix.control.signals import nav_event_settings from pretix.control.signals import nav_event_settings
from pretix.presale.signals import fee_calculation_for_cart, front_page_top, order_meta_from_request from pretix.presale.signals import fee_calculation_for_cart, front_page_top, order_meta_from_request
from pretix.presale.views import get_cart
@receiver(nav_event_settings, dispatch_uid='service_fee_nav_settings') @receiver(nav_event_settings, dispatch_uid='service_fee_nav_settings')
@ -26,7 +27,15 @@ def navbar_settings(sender, request, **kwargs):
}] }]
def get_fees(event, total, invoice_address, mod=''): def get_fees(event, total, invoice_address, mod='', request=None, positions=[]):
if request is not None and not positions:
positions = get_cart(request)
positions = [pos for pos in positions if not pos.addon_to and pos.price != Decimal('0.00')]
fee_per_ticket = event.settings.get('service_fee_per_ticket' + mod, as_type=Decimal)
if mod and fee_per_ticket is None:
fee_per_ticket = event.settings.get('service_fee_per_ticket', as_type=Decimal)
fee_abs = event.settings.get('service_fee_abs' + mod, as_type=Decimal) fee_abs = event.settings.get('service_fee_abs' + mod, as_type=Decimal)
if mod and fee_abs is None: if mod and fee_abs is None:
fee_abs = event.settings.get('service_fee_abs', as_type=Decimal) fee_abs = event.settings.get('service_fee_abs', as_type=Decimal)
@ -35,11 +44,12 @@ def get_fees(event, total, invoice_address, mod=''):
if mod and fee_percent is None: if mod and fee_percent is None:
fee_percent = event.settings.get('service_fee_percent', as_type=Decimal) fee_percent = event.settings.get('service_fee_percent', as_type=Decimal)
fee_per_ticket = Decimal("0") if fee_per_ticket is None else fee_per_ticket
fee_abs = Decimal("0") if fee_abs is None else fee_abs fee_abs = Decimal("0") if fee_abs is None else fee_abs
fee_percent = Decimal("0") if fee_percent is None else fee_percent fee_percent = Decimal("0") if fee_percent is None else fee_percent
if (fee_abs or fee_percent) and total != Decimal('0.00'): if (fee_per_ticket or fee_abs or fee_percent) and total != Decimal('0.00'):
fee = round_decimal(fee_abs + total * (fee_percent / 100), event.currency) fee = round_decimal(fee_abs + total * (fee_percent / 100) + len(positions) * fee_per_ticket, event.currency)
tax_rule = event.settings.tax_rate_default or TaxRule.zero() tax_rule = event.settings.tax_rate_default or TaxRule.zero()
if tax_rule.tax_applicable(invoice_address): if tax_rule.tax_applicable(invoice_address):
tax = tax_rule.tax(fee) tax = tax_rule.tax(fee)
@ -77,31 +87,35 @@ def cart_fee(sender: Event, request: HttpRequest, invoice_address, total, **kwar
pass pass
else: else:
mod = '_resellers' mod = '_resellers'
return get_fees(sender, total, invoice_address, mod) return get_fees(sender, total, invoice_address, mod, request)
@receiver(order_fee_calculation, dispatch_uid="service_fee_calc_order") @receiver(order_fee_calculation, dispatch_uid="service_fee_calc_order")
def order_fee(sender: Event, invoice_address, total, meta_info, **kwargs): def order_fee(sender: Event, positions, invoice_address, total, meta_info, **kwargs):
mod = '' mod = ''
if meta_info.get('servicefees_reseller_id'): if meta_info.get('servicefees_reseller_id'):
mod = '_resellers' mod = '_resellers'
return get_fees(sender, total, invoice_address, mod) return get_fees(sender, total, invoice_address, mod, positions=positions)
@receiver(front_page_top, dispatch_uid="service_fee_front_page_top") @receiver(front_page_top, dispatch_uid="service_fee_front_page_top")
def front_page_top_recv(sender: Event, **kwargs): def front_page_top_recv(sender: Event, **kwargs):
fees = [] fees = []
fee_per_ticket = sender.settings.get('service_fee_per_ticket', as_type=Decimal)
if fee_per_ticket:
fees = fees + ["{} {}".format(money_filter(fee_per_ticket, sender.currency), ugettext('per ticket'))]
fee_abs = sender.settings.get('service_fee_abs', as_type=Decimal) fee_abs = sender.settings.get('service_fee_abs', as_type=Decimal)
if fee_abs: if fee_abs:
fees = fees + [money_filter(fee_abs, sender.currency)] fees = fees + ["{} {}".format(money_filter(fee_abs, sender.currency), ugettext('per order'))]
fee_percent = sender.settings.get('service_fee_percent', as_type=Decimal) fee_percent = sender.settings.get('service_fee_percent', as_type=Decimal)
if fee_percent: if fee_percent:
fees = fees + ['{} %'.format(fee_percent)] fees = fees + ['{} % {}'.format(fee_percent, ugettext('per order'))]
if fee_abs or fee_percent: if fee_per_ticket or fee_abs or fee_percent:
return '<p>%s</p>' % ugettext('A service fee of {} will be added on top of each order.').format( return '<p>%s</p>' % ugettext('A service fee of {} will be added on top of each order.').format(
' + '.join(fees) ' {} '.format(ugettext('plus')).join(fees)
) )

View file

@ -7,10 +7,16 @@
{% csrf_token %} {% csrf_token %}
{% bootstrap_form_errors form %} {% bootstrap_form_errors form %}
<fieldset> <fieldset>
{% bootstrap_field form.service_fee_abs layout="control" %} <legend>{% trans "Service fees" %}</legend>
{% bootstrap_field form.service_fee_percent layout="control" %} {% bootstrap_field form.service_fee_per_ticket addon_after=request.event.currency layout="control" %}
{% bootstrap_field form.service_fee_abs_resellers layout="control" %} {% bootstrap_field form.service_fee_abs addon_after=request.event.currency layout="control" %}
{% bootstrap_field form.service_fee_percent_resellers layout="control" %} {% bootstrap_field form.service_fee_percent addon_after="%" layout="control" %}
</fieldset>
<fieldset>
<legend>{% trans "Service fees with resellers" %}</legend>
{% bootstrap_field form.service_fee_per_ticket_resellers addon_after=request.event.currency layout="control" %}
{% bootstrap_field form.service_fee_abs_resellers addon_after=request.event.currency layout="control" %}
{% bootstrap_field form.service_fee_percent_resellers addon_after="%" layout="control" %}
</fieldset> </fieldset>
<div class="form-group submit-group"> <div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save"> <button type="submit" class="btn btn-primary btn-save">

View file

@ -5,23 +5,33 @@ from django.utils.translation import ugettext_lazy as _
from pretix.base.forms import SettingsForm from pretix.base.forms import SettingsForm
from pretix.base.models import Event from pretix.base.models import Event
from pretix.control.views.event import EventSettingsViewMixin, EventSettingsFormView from pretix.control.views.event import EventSettingsViewMixin, EventSettingsFormView
from pretix.helpers.money import change_decimal_field
class ServiceFeeSettingsForm(SettingsForm): class ServiceFeeSettingsForm(SettingsForm):
service_fee_abs = forms.DecimalField(label=_('Service fee')) service_fee_abs = forms.DecimalField(label=_('Fixed fee per order'))
service_fee_percent = forms.DecimalField( service_fee_percent = forms.DecimalField(
label=_('Service fee (%)'), label=_('Percentual fee per order'),
help_text=_('Percentage of the order total. Note that this percentage will currently only ' help_text=_('Percentage of the order total. Note that this percentage will currently only '
'be calculated on the summed price of sold tickets, not on other fees like e.' 'be calculated on the summed price of sold tickets, not on other fees like e.'
'g. shipping fees, if there are any.') 'g. shipping fees, if there are any.')
) )
service_fee_abs_resellers = forms.DecimalField(label=_('Service fee with resellers')) service_fee_per_ticket = forms.DecimalField(
label=_('Fixed fee per ticket'),
help_text=_('This fee will be added for each ticket sold, except for free items and addons.')
)
service_fee_abs_resellers = forms.DecimalField(label=_('Fixed fee per order'))
service_fee_percent_resellers = forms.DecimalField( service_fee_percent_resellers = forms.DecimalField(
label=_('Service fee with resellers (%)'), label=_('Percentual fee per order'),
help_text=_('Percentage of the order total. Note that this percentage will currently only ' help_text=_('Percentage of the order total. Note that this percentage will currently only '
'be calculated on the summed price of sold tickets, not on other fees like e.' 'be calculated on the summed price of sold tickets, not on other fees like e.'
'g. shipping fees, if there are any.') 'g. shipping fees, if there are any.')
) )
service_fee_per_ticket_resellers = forms.DecimalField(
label=_('Fixed fee per ticket'),
help_text=_('This fee will be added for each ticket sold, except for free items and addons.')
)
class SettingsView(EventSettingsViewMixin, EventSettingsFormView): class SettingsView(EventSettingsViewMixin, EventSettingsFormView):