[A11y] fix giftcard-checkout error messages (#5175)

* [A11y] fix giftcard-checkout error messages

* move validation to payment_form

* Update checkout_payment.html

* move already-used check to clean as well

* fix tests

* fix code style issue

* fix giftcard-payment in redeem-view

* Fix responsiveness on checkout

* Fix paying for existing orders

* fix cart.py for new GiftCardPaymentForm-signature

* fix order_tests

---------

Co-authored-by: Raphael Michel <michel@rami.io>
This commit is contained in:
Richard Schreiber
2025-05-30 13:29:33 +02:00
committed by GitHub
parent 1752b2f037
commit 66a4a34383
7 changed files with 219 additions and 134 deletions

View File

@@ -16,16 +16,17 @@
{% for p in current_payments %}
<div class="list-group-item">
<div class="row">
<div class="col-xs-9">
{{ p.provider_name }}
<div class="col-md-7 col-sm-6 col-xs-8">
<strong id="payment-label-{{ forloop.counter }}">{{ p.provider_name }}</strong>
</div>
<div class="col-xs-2 text-right">
<div class="col-md-2 col-sm-2 col-xs-4 text-right">
{{ p.payment_amount|money:request.event.currency }}
</div>
<div class="col-xs-1 text-right">
<button name="remove_payment" value="{{ p.id }}" title="{% trans "Remove payment" %}"
class="btn btn-link btn-xs">
<span class="fa fa-trash text-danger"></span>
<div class="col-md-3 col-sm-4 col-xs-12 text-right">
<button name="remove_payment" value="{{ p.id }}" aria-describedby="payment-label-{{ forloop.counter }}"
class="btn btn-danger">
<span class="fa fa-trash"></span>
{% trans "Remove payment" %}
</button>
</div>
</div>
@@ -34,11 +35,11 @@
{% if remaining %}
<div class="list-group-item">
<div class="row">
<div class="col-xs-9">
<div class="col-md-7 col-sm-6 col-xs-8">
<strong>{% trans "Remaining balance" %}</strong><br>
<span class="text-muted">{% trans "Please select a payment method below." %}</span>
</div>
<div class="col-xs-2 text-right">
<div class="col-md-2 col-sm-2 col-xs-4 text-right">
<strong>
{{ remaining|money:request.event.currency }}
</strong>

View File

@@ -70,7 +70,7 @@ from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import eventreverse
from pretix.presale.views import (
CartMixin, EventViewMixin, allow_cors_if_namespaced,
allow_frame_if_namespaced, iframe_entry_view_wrapper,
allow_frame_if_namespaced, get_cart, iframe_entry_view_wrapper,
)
from pretix.presale.views.event import (
get_grouped_items, item_group_by_category,
@@ -441,7 +441,7 @@ 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
from pretix.base.payment import GiftCardPayment, GiftCardPaymentForm
if 'voucher' in request.POST:
code = request.POST.get('voucher').strip()
@@ -454,6 +454,22 @@ class CartApplyVoucher(EventViewMixin, CartActionMixin, AsyncAction, View):
raise ValidationError(error_messages['voucher_invalid'])
else:
cs = cart_session(request)
used_cards = [
p.get('info_data', {}).get('gift_card')
for p in cs.get('payments', [])
if p.get('info_data', {}).get('gift_card')
]
form = GiftCardPaymentForm(
event=request.event,
used_cards=used_cards,
positions=get_cart(request),
testmode=request.event.testmode,
data={'code': code},
)
form.fields = gcp.payment_form_fields
if not form.is_valid():
# raise first validation-error in form
raise next(iter(form.errors.as_data().values()))[0]
gcp._add_giftcard_to_cart(cs, gc)
messages.success(
request,
@@ -694,7 +710,7 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, CartMixin, TemplateView
return context
def dispatch(self, request, *args, **kwargs):
from pretix.base.payment import GiftCardPayment
from pretix.base.payment import GiftCardPayment, GiftCardPaymentForm
err = None
v = request.GET.get('voucher')
@@ -719,12 +735,28 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, CartMixin, TemplateView
err = error_messages['voucher_redeemed_cart'] % self.request.event.settings.reservation_time
except Voucher.DoesNotExist:
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")):
gc = request.event.organizer.accepted_gift_cards.get(secret=v)
gcp = GiftCardPayment(request.event)
if not gcp.is_enabled or not gcp.is_allowed(request, Decimal("1.00")):
err = error_messages['voucher_invalid']
else:
cs = cart_session(request)
used_cards = [
p.get('info_data', {}).get('gift_card')
for p in cs.get('payments', [])
if p.get('info_data', {}).get('gift_card')
]
form = GiftCardPaymentForm(
event=request.event,
used_cards=used_cards,
positions=get_cart(request),
testmode=request.event.testmode,
data={'code': v},
)
form.fields = gcp.payment_form_fields
if not form.is_valid():
# raise first validation-error in form
raise next(iter(form.errors.as_data().values()))[0]
gcp._add_giftcard_to_cart(cs, gc)
messages.success(
request,

View File

@@ -683,6 +683,8 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView):
ctx['show_fees'] = any(p['fee_diff'] for p in self.provider_forms)
if len(self.provider_forms) == 1:
ctx['selected'] = self.provider_forms[0]['provider'].identifier
elif "payment" in self.request.POST:
ctx['selected'] = self.request.POST.get("payment")
return ctx
def get_confirm_url(self, payment):