Allow to enter gift cards into the voucher input (Z#23171961) (#4670)

This commit is contained in:
Raphael Michel
2024-12-05 13:43:46 +01:00
committed by GitHub
parent 94a64ba53a
commit 6b199a2b9c
8 changed files with 192 additions and 58 deletions

View File

@@ -10,18 +10,41 @@
<i class="fa fa-shopping-cart" aria-hidden="true"></i>
<strong>{% trans "Your cart" %}</strong>
</span>
<strong id="cart-deadline-short" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}" aria-hidden="true">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{{ cart.minutes_left|stringformat:"02d" }}:{{ cart.seconds_left|stringformat:"02d" }}
{% else %}
{% trans "Cart expired" %}
{% endif %}
</strong>
{% if cart.positions %}
<strong id="cart-deadline-short" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}" aria-hidden="true">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{{ cart.minutes_left|stringformat:"02d" }}:{{ cart.seconds_left|stringformat:"02d" }}
{% else %}
{% trans "Cart expired" %}
{% endif %}
</strong>
{% endif %}
</h2>
</summary>
<div>
<div class="panel-body">
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=True %}
{% if cart.positions %}
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=True %}
{% endif %}
{% if cart.current_selected_payments %}
<p>{% trans "You already selected the following payment methods:" %}</p>
<div class="list-group">
{% for p in cart.current_selected_payments %}
<div class="list-group-item">
<div class="row">
<div class="col-xs-9">
{{ p.provider_name }}
</div>
<div class="col-xs-3 text-right">
{% if p.payment_amount %}
{{ p.payment_amount|money:request.event.currency }}
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
<div class="checkout-button-row">
<form class="checkout-button-primary" method="get" action="{% eventurl request.event "presale:event.checkout.start" cart_namespace=cart_namespace %}">
<p><button class="btn btn-primary btn-lg" type="submit"{% if has_addon_choices or cart.total == 0 %} aria-label="{% trans "Continue with order process" %}"{% endif %}>

View File

@@ -251,7 +251,8 @@ class CartMixin:
'seconds_left': seconds_left,
'first_expiry': first_expiry,
'is_ordered': bool(order),
'itemcount': sum(c.count for c in positions if not c.addon_to)
'itemcount': sum(c.count for c in positions if not c.addon_to),
'current_selected_payments': [p for p in self.current_selected_payments(total) if p.get('multi_use_supported')]
}
def current_selected_payments(self, total, warn=False, total_includes_payment_fees=False):

View File

@@ -42,6 +42,7 @@ from urllib.parse import quote
from django.conf import settings
from django.contrib import messages
from django.core.cache import caches
from django.core.exceptions import ValidationError
from django.db.models import Q
from django.http import FileResponse, Http404, JsonResponse
from django.shortcuts import get_object_or_404, render
@@ -57,7 +58,7 @@ from django.views.generic import TemplateView, View
from django_scopes import scopes_disabled
from pretix.base.models import (
CartPosition, InvoiceAddress, QuestionAnswer, SubEvent, Voucher,
CartPosition, GiftCard, InvoiceAddress, QuestionAnswer, SubEvent, Voucher,
)
from pretix.base.services.cart import (
CartError, add_items_to_cart, apply_voucher, clear_cart, error_messages,
@@ -438,8 +439,48 @@ class CartApplyVoucher(EventViewMixin, CartActionMixin, AsyncAction, View):
return _('We applied the voucher to as many products in your cart as we could.')
def post(self, request, *args, **kwargs):
from pretix.base.payment import GiftCardPayment
if 'voucher' in request.POST:
return self.do(self.request.event.id, request.POST.get('voucher'), get_or_create_cart_id(self.request),
code = request.POST.get('voucher').strip()
if not self.request.event.vouchers.filter(code__iexact=code):
try:
gc = self.request.event.organizer.accepted_gift_cards.get(secret=code)
gcp = GiftCardPayment(self.request.event)
if not gcp.is_enabled or not gcp.is_allowed(self.request, Decimal("1.00")):
raise ValidationError(error_messages['voucher_invalid'])
else:
cs = cart_session(request)
gcp._add_giftcard_to_cart(cs, gc)
messages.success(
request,
_("The gift card has been saved to your cart. Please continue your checkout.")
)
if "ajax" in self.request.POST or "ajax" in self.request.GET:
return JsonResponse({
'ready': True,
'success': True,
'redirect': self.get_success_url(),
'message': str(
_("The gift card has been saved to your cart. Please continue your checkout.")
)
})
return redirect_to_url(self.get_success_url())
except GiftCard.DoesNotExist:
pass
except ValidationError as e:
messages.error(self.request, str(e.message))
if "ajax" in self.request.POST or "ajax" in self.request.GET:
return JsonResponse({
'ready': True,
'success': False,
'redirect': self.get_success_url(),
'message': str(e.message)
})
return redirect_to_url(self.get_error_url())
return self.do(self.request.event.id, code, get_or_create_cart_id(self.request),
translation.get_language(), request.sales_channel.identifier,
time_machine_now(default=None))
else:
@@ -631,6 +672,8 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, CartMixin, TemplateView
return context
def dispatch(self, request, *args, **kwargs):
from pretix.base.payment import GiftCardPayment
err = None
v = request.GET.get('voucher')
@@ -653,10 +696,24 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, CartMixin, TemplateView
if v_avail < 1 and not err:
err = error_messages['voucher_redeemed_cart'] % self.request.event.settings.reservation_time
except Voucher.DoesNotExist:
if self.request.event.organizer.accepted_gift_cards.filter(secret__iexact=request.GET.get("voucher")).exists():
err = error_messages['gift_card']
else:
try:
gc = self.request.event.organizer.accepted_gift_cards.get(secret=v.strip())
gcp = GiftCardPayment(self.request.event)
if not gcp.is_enabled or not gcp.is_allowed(self.request, Decimal("1.00")):
err = error_messages['voucher_invalid']
else:
cs = cart_session(request)
gcp._add_giftcard_to_cart(cs, gc)
messages.success(
request,
_("The gift card has been saved to your cart. Please now select the products "
"you want to purchase.")
)
return redirect_to_url(self.get_next_url())
except GiftCard.DoesNotExist:
err = error_messages['voucher_invalid']
except ValidationError as e:
err = str(e.message)
else:
context = {}
context['cart'] = self.get_cart()

View File

@@ -632,7 +632,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
context['subevent_list_cache_key'] = self._subevent_list_cachekey()
context['show_cart'] = (
context['cart']['positions'] and (
(context['cart']['positions'] or context['cart'].get('current_selected_payments')) and (
self.request.event.has_subevents or self.request.event.presale_is_running
)
)