diff --git a/src/pretix/base/models/organizer.py b/src/pretix/base/models/organizer.py index 7d9dc090a3..6163fc9f50 100644 --- a/src/pretix/base/models/organizer.py +++ b/src/pretix/base/models/organizer.py @@ -82,6 +82,14 @@ class Organizer(LoggedModel): return ObjectRelatedCache(self) + @property + def has_gift_cards(self): + return self.cache.get_or_set( + key='has_gift_cards', + timeout=15, + default=lambda: self.issued_gift_cards.exists() or self.gift_card_issuer_acceptance.exists() + ) + def allow_delete(self): from . import Order, Invoice return ( diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index a40e1a9eac..bb51b7f2fb 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -892,7 +892,6 @@ class GiftCardPayment(BasePaymentProvider): is_enabled = True identifier = "giftcard" verbose_name = _("Gift card") - is_implicit = True def is_allowed(self, request: HttpRequest, total: Decimal=None) -> bool: return False diff --git a/src/pretix/presale/checkoutflow.py b/src/pretix/presale/checkoutflow.py index 1d94225461..5b6ef7394f 100644 --- a/src/pretix/presale/checkoutflow.py +++ b/src/pretix/presale/checkoutflow.py @@ -21,6 +21,7 @@ from pretix.base.services.cart import ( get_fees, set_cart_addons, update_tax_rates, ) from pretix.base.services.orders import perform_order +from pretix.base.templatetags.money import money_filter from pretix.base.views.tasks import AsyncAction from pretix.multidomain.urlreverse import eventreverse from pretix.presale.forms.checkout import ( @@ -531,7 +532,7 @@ class PaymentStep(QuestionsViewMixin, CartMixin, TemplateFlowStep): def post(self, request): self.request = request if request.POST.get("giftcard"): - # TODO: cross-organizer acceptance, check for valid money, … + # TODO: cross-organizer acceptance, … try: gc = GiftCard.objects.get( issuer=request.organizer, @@ -540,13 +541,30 @@ class PaymentStep(QuestionsViewMixin, CartMixin, TemplateFlowStep): if gc.currency != request.event.currency: messages.error(self.request, _("This gift card does not support this currency.")) return self.render() + if gc.pk in self.cart_session['gift_cards']: + messages.error(self.request, _("This gift card is already used for your payment.")) + return self.render() + if gc.value <= Decimal("0.00"): + messages.error(self.request, _("All credit on this gift card has been used.")) + return self.render() if 'gift_cards' not in self.cart_session: self.cart_session['gift_cards'] = [] self.cart_session['gift_cards'] = self.cart_session['gift_cards'] + [gc.pk] - return self.render() + + remainder = self._total_order_value - gc.value + if remainder >= Decimal('0.00'): + messages.success(self.request, _("Your gift card has been applied, but {} still need to be paid. Please select a payment method.").format( + money_filter(remainder, self.event.currency) + )) + else: + messages.success(self.request, _("Your gift card has been applied.")) + return redirect(self.get_step_url(request)) except GiftCard.DoesNotExist: messages.error(self.request, _("This gift card is not known.")) return self.render() + except GiftCard.MultipleObjectsReturned: + messages.error(self.request, _("This gift card can not be redeemed since its code is not unique. Please contact the organizer of this event.")) + return self.render() for p in self.provider_forms: if p['provider'].identifier == request.POST.get('payment', ''): @@ -572,6 +590,7 @@ class PaymentStep(QuestionsViewMixin, CartMixin, TemplateFlowStep): if len(self.provider_forms) == 1: ctx['selected'] = self.provider_forms[0]['provider'].identifier ctx['cart'] = self.get_cart() + ctx['has_gift_cards'] = self.request.organizer.has_gift_cards return ctx @cached_property diff --git a/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html b/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html index 58dcb81c6a..53f1ff9baf 100644 --- a/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html +++ b/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html @@ -12,26 +12,25 @@ {% csrf_token %}
+ {% blocktrans %} + If you have a gift card, please enter the gift card code here. If the gift card does not have + enough credit to pay for the full order, you will be shown this page again and you can either + redeem another gift card or select a different payment method for the difference. + {% endblocktrans %} +
+ +{% trans "There are no payment providers enabled." %}
{% if not event.live %}