mirror of
https://github.com/pretix/pretix.git
synced 2026-05-06 15:24:02 +00:00
Allow to enter a voucher before choosing a subevent
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
<label class="col-md-3 control-label" for="id_url">{% trans "Voucher link" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" name="url"
|
||||
value="{% abseventurl request.event "presale:event.redeem" %}?voucher={{ voucher.code }}{% if voucher.subevent_id %}&subevent={{ voucher.subevent_id }}{% endif %}"
|
||||
value="{% abseventurl request.event "presale:event.redeem" %}?voucher={{ voucher.code|urlencode }}{% if voucher.subevent_id %}&subevent={{ voucher.subevent_id }}{% endif %}"
|
||||
class="form-control"
|
||||
id="id_url" readonly>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n %}
|
||||
{% load eventurl %}
|
||||
{% for subev in subevent_list %}
|
||||
<a href="{% eventurl event "presale:event.index" subevent=subev.id cart_namespace=cart_namespace %}"
|
||||
<a href="{% if request.GET.voucher %}{% eventurl event "presale:event.redeem" cart_namespace=cart_namespace %}?voucher={{ request.GET.voucher|urlencode }}&subevent={{ subev.pk }}{% else %}{% eventurl event "presale:event.index" subevent=subev.id cart_namespace=cart_namespace %}{% endif %}"
|
||||
class="subevent-row">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
|
||||
@@ -101,6 +101,12 @@
|
||||
{{ frontpage_text|rich_text }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if request.GET.voucher %}
|
||||
<div class="alert alert-info">
|
||||
{% trans "Please select a date to redeem your voucher." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if subevent and "year" not in request.GET %}
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
|
||||
{% block content %}
|
||||
<h2>{% trans "Voucher redemption" %}</h2>
|
||||
|
||||
{% if subevent %}
|
||||
{% if request.GET.subevent and subevent.pk|stringformat:"i" != request.GET.subevent %}
|
||||
<div class="alert alert-warning">
|
||||
{% trans "This voucher is valid only for the following specific date and time." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<h3>{{ subevent.name }}</h3>
|
||||
{% with ev=subevent %}
|
||||
<div class="info-row">
|
||||
|
||||
@@ -518,7 +518,6 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, TemplateView):
|
||||
kwargs={'cart_namespace': kwargs.get('cart_namespace') or ''})
|
||||
if context['cart_redirect'].startswith('https:'):
|
||||
context['cart_redirect'] = '/' + context['cart_redirect'].split('/', 3)[3]
|
||||
|
||||
return context
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
@@ -566,6 +565,10 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, TemplateView):
|
||||
|
||||
if hasattr(self, 'voucher') and self.voucher.subevent:
|
||||
self.subevent = self.voucher.subevent
|
||||
|
||||
if not err and not self.subevent:
|
||||
return redirect(eventreverse(self.request.event, 'presale:event.index',
|
||||
kwargs={'cart_namespace': kwargs.get('cart_namespace') or ''}) + '?voucher=' + quote(self.voucher.code))
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from pretix.base.channels import get_all_sales_channels
|
||||
from pretix.base.models import ItemVariation, Quota, SeatCategoryMapping
|
||||
from pretix.base.models import ItemVariation, Quota, SeatCategoryMapping, Voucher
|
||||
from pretix.base.models.event import SubEvent
|
||||
from pretix.base.models.items import (
|
||||
ItemBundle, SubEventItem, SubEventItemVariation,
|
||||
@@ -375,6 +375,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
if vouchers_exist is None:
|
||||
vouchers_exist = self.request.event.vouchers.exists()
|
||||
self.request.event.cache.set('vouchers_exist', vouchers_exist)
|
||||
context['show_vouchers'] = context['vouchers_exist'] = vouchers_exist
|
||||
|
||||
if not self.request.event.has_subevents or self.subevent:
|
||||
# Fetch all items
|
||||
@@ -399,12 +400,6 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
context['items_by_category'] = item_group_by_category(items)
|
||||
context['display_add_to_cart'] = display_add_to_cart
|
||||
|
||||
context['show_vouchers'] = vouchers_exist
|
||||
context['vouchers_exist'] = vouchers_exist
|
||||
else:
|
||||
context['show_vouchers'] = False
|
||||
context['vouchers_exist'] = vouchers_exist
|
||||
|
||||
context['ev'] = self.subevent or self.request.event
|
||||
context['subevent'] = self.subevent
|
||||
context['cart'] = self.get_cart()
|
||||
@@ -434,6 +429,13 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
return context
|
||||
|
||||
def _subevent_list_context(self):
|
||||
voucher = None
|
||||
if self.request.GET.get('voucher'):
|
||||
try:
|
||||
voucher = Voucher.objects.get(code__iexact=self.request.GET.get('voucher'), event=self.request.event)
|
||||
except Voucher.DoesNotExist:
|
||||
pass
|
||||
|
||||
context = {}
|
||||
context['list_type'] = self.request.GET.get("style", self.request.event.settings.event_list_type)
|
||||
if context['list_type'] not in ("calendar", "week") and self.request.event.subevents.filter(date_from__gt=now()).count() > 50:
|
||||
@@ -456,7 +458,8 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
add_subevents_for_days(
|
||||
filter_qs_by_attr(self.request.event.subevents_annotated(self.request.sales_channel.identifier).using(settings.DATABASE_REPLICA), self.request),
|
||||
before, after, ebd, set(), self.request.event,
|
||||
self.kwargs.get('cart_namespace')
|
||||
self.kwargs.get('cart_namespace'),
|
||||
voucher,
|
||||
)
|
||||
|
||||
context['show_names'] = ebd.get('_subevents_different_names', False) or sum(
|
||||
@@ -484,7 +487,9 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
add_subevents_for_days(
|
||||
filter_qs_by_attr(self.request.event.subevents_annotated(self.request.sales_channel.identifier).using(settings.DATABASE_REPLICA), self.request),
|
||||
before, after, ebd, set(), self.request.event,
|
||||
self.kwargs.get('cart_namespace')
|
||||
self.kwargs.get('cart_namespace'),
|
||||
self.request.GET.get('voucher'),
|
||||
voucher,
|
||||
)
|
||||
|
||||
context['show_names'] = ebd.get('_subevents_different_names', False) or sum(
|
||||
@@ -503,7 +508,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
context['subevent_list'] = self.request.event.subevents_sorted(
|
||||
filter_qs_by_attr(self.request.event.subevents_annotated(self.request.sales_channel.identifier).using(settings.DATABASE_REPLICA), self.request)
|
||||
)
|
||||
if self.request.event.settings.event_list_available_only:
|
||||
if self.request.event.settings.event_list_available_only and not voucher:
|
||||
context['subevent_list'] = [
|
||||
se for se in context['subevent_list']
|
||||
if not se.presale_has_ended and se.best_availability_state >= Quota.AVAILABILITY_RESERVED
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import calendar
|
||||
from collections import defaultdict
|
||||
from datetime import date, datetime, time, timedelta
|
||||
from urllib.parse import quote
|
||||
|
||||
import isoweek
|
||||
import pytz
|
||||
@@ -357,7 +358,7 @@ def add_events_for_days(request, baseqs, before, after, ebd, timezones):
|
||||
})
|
||||
|
||||
|
||||
def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_namespace=None):
|
||||
def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_namespace=None, voucher=None):
|
||||
qs = qs.filter(active=True, is_public=True).filter(
|
||||
Q(Q(date_to__gte=before) & Q(date_from__lte=after)) |
|
||||
Q(Q(date_from__lte=after) & Q(date_to__gte=before)) |
|
||||
@@ -365,6 +366,7 @@ def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_n
|
||||
).order_by(
|
||||
'date_from'
|
||||
)
|
||||
|
||||
quotas_to_compute = []
|
||||
for se in qs:
|
||||
if se.presale_is_running:
|
||||
@@ -388,7 +390,7 @@ def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_n
|
||||
s = event.settings if event else se.event.settings
|
||||
|
||||
if s.event_list_available_only:
|
||||
if se.presale_has_ended or se.best_availability_state < Quota.AVAILABILITY_RESERVED:
|
||||
if se.presale_has_ended or ((not voucher or not voucher.allow_ignore_quota) and se.best_availability_state < Quota.AVAILABILITY_RESERVED):
|
||||
continue
|
||||
|
||||
timezones.add(s.timezones)
|
||||
@@ -417,7 +419,12 @@ def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_n
|
||||
else None
|
||||
),
|
||||
'event': se,
|
||||
'url': eventreverse(se.event, 'presale:event.index', kwargs=kwargs)
|
||||
'url': (
|
||||
eventreverse(se.event, 'presale:event.redeem',
|
||||
kwargs={k: v for k, v in kwargs.items() if k != 'subevent'}) + f'?subevent={se.pk}&voucher={quote(voucher.code)}'
|
||||
if voucher
|
||||
else eventreverse(se.event, 'presale:event.index', kwargs=kwargs)
|
||||
)
|
||||
})
|
||||
d += timedelta(days=1)
|
||||
|
||||
@@ -426,7 +433,12 @@ def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_n
|
||||
'event': se,
|
||||
'continued': False,
|
||||
'time': datetime_from.time().replace(tzinfo=None) if s.show_times else None,
|
||||
'url': eventreverse(se.event, 'presale:event.index', kwargs=kwargs),
|
||||
'url': (
|
||||
eventreverse(se.event, 'presale:event.redeem',
|
||||
kwargs={k: v for k, v in kwargs.items() if k != 'subevent'}) + f'?subevent={se.pk}&voucher={quote(voucher.code)}'
|
||||
if voucher
|
||||
else eventreverse(se.event, 'presale:event.index', kwargs=kwargs)
|
||||
),
|
||||
'timezone': s.timezone,
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user