diff --git a/src/pretix/api/serializers/event.py b/src/pretix/api/serializers/event.py index a46066bb48..786f3ffc96 100644 --- a/src/pretix/api/serializers/event.py +++ b/src/pretix/api/serializers/event.py @@ -668,6 +668,7 @@ class EventSettingsSerializer(SettingsSerializer): 'cancel_allow_user_paid_keep_percentage', 'cancel_allow_user_paid_adjust_fees', 'cancel_allow_user_paid_adjust_fees_explanation', + 'cancel_allow_user_paid_adjust_fees_step', 'cancel_allow_user_paid_refund_as_giftcard', 'cancel_allow_user_paid_require_approval', 'change_allow_user_variation', diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 9588a387f0..525b424acf 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -1225,6 +1225,21 @@ DEFAULTS = { "e.g. to explain choosing a lower refund will help your organization.") ) }, + 'cancel_allow_user_paid_adjust_fees_step': { + 'default': None, + 'type': Decimal, + 'form_class': forms.DecimalField, + 'serializer_class': serializers.DecimalField, + 'serializer_kwargs': dict( + max_digits=10, decimal_places=2 + ), + 'form_kwargs': dict( + max_digits=10, decimal_places=2, + label=_("Step size for reduction amount"), + help_text=_('By default, customers can choose an arbitrary amount for you to keep. If you set this to e.g. ' + '10, they will only be able to choose values in increments of 10.') + ) + }, 'cancel_allow_user_paid_require_approval': { 'default': 'False', 'type': bool, diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 540b401dea..799ccb1d86 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -572,6 +572,7 @@ class CancelSettingsForm(SettingsForm): 'cancel_allow_user_paid_keep_percentage', 'cancel_allow_user_paid_adjust_fees', 'cancel_allow_user_paid_adjust_fees_explanation', + 'cancel_allow_user_paid_adjust_fees_step', 'cancel_allow_user_paid_refund_as_giftcard', 'cancel_allow_user_paid_require_approval', 'change_allow_user_variation', diff --git a/src/pretix/control/templates/pretixcontrol/event/cancel.html b/src/pretix/control/templates/pretixcontrol/event/cancel.html index 5ef9f4bc7d..e99b7275e3 100644 --- a/src/pretix/control/templates/pretixcontrol/event/cancel.html +++ b/src/pretix/control/templates/pretixcontrol/event/cancel.html @@ -23,6 +23,7 @@ {% bootstrap_field form.cancel_allow_user_paid_adjust_fees layout="control" %}
diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index 29d6ce2e4d..acd8aa291e 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -1,4 +1,5 @@ import inspect +import json import mimetypes import os import re @@ -786,16 +787,27 @@ class OrderCancel(EventViewMixin, OrderDetailMixin, TemplateView): def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx['order'] = self.order + prs = self.order.payment_refund_sum fee = self.order.user_cancel_fee - refund_amount = self.order.payment_refund_sum - fee + refund_amount = prs - fee proposals = self.order.propose_auto_refunds(refund_amount) ctx['cancel_fee'] = fee ctx['refund_amount'] = refund_amount + ctx['payment_refund_sum'] = prs ctx['can_auto_refund'] = sum(proposals.values()) == refund_amount ctx['proposals'] = [ p.payment_provider.payment_presale_render(payment=p) for p in proposals ] + if self.request.event.settings.cancel_allow_user_paid_adjust_fees_step: + steps = [fee] + s = fee + while s < prs: + steps.append(s) + s += self.request.event.settings.cancel_allow_user_paid_adjust_fees_step + if prs not in steps: + steps.append(prs) + ctx['ticks'] = json.dumps([float(p) for p in steps]) return ctx @@ -831,6 +843,11 @@ class OrderCancelDo(EventViewMixin, OrderDetailMixin, AsyncAction, View): messages.error(request, _('You chose an invalid cancellation fee.')) return redirect(self.get_order_url()) if custom_fee is not None and fee <= custom_fee <= self.order.payment_refund_sum: + if self.request.event.settings.cancel_allow_user_paid_adjust_fees_step: + if (custom_fee - fee) % self.request.event.settings.cancel_allow_user_paid_adjust_fees_step != Decimal('0.00'): + messages.error(request, _('You chose an invalid cancellation fee.')) + return redirect(self.get_order_url()) + fee = custom_fee else: messages.error(request, _('You chose an invalid cancellation fee.')) diff --git a/src/pretix/static/pretixpresale/scss/_event.scss b/src/pretix/static/pretixpresale/scss/_event.scss index c234f716bb..5901d0784c 100644 --- a/src/pretix/static/pretixpresale/scss/_event.scss +++ b/src/pretix/static/pretixpresale/scss/_event.scss @@ -214,6 +214,11 @@ h2.subevent-head { @include slider_background-image($brand-success, darken($brand-success, 5%), mix($brand-success, darken($brand-success, 5%))); } + .slider-tick-container { + opacity: 0; + visibility: hidden; + } + input { flex: 0; }