mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
Implement ticket download dates (closes #15)
This commit is contained in:
@@ -81,8 +81,7 @@ class SettingsForm(forms.Form):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.obj = kwargs.pop('obj')
|
||||
if 'initial' not in kwargs:
|
||||
kwargs['initial'] = self.obj.settings
|
||||
kwargs['initial'] = self.obj.settings
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def save(self):
|
||||
|
||||
@@ -73,6 +73,10 @@ DEFAULTS = {
|
||||
'default': 'True',
|
||||
'type': bool
|
||||
},
|
||||
'ticket_download_date': {
|
||||
'default': None,
|
||||
'type': datetime
|
||||
},
|
||||
'last_order_modification_date': {
|
||||
'default': None,
|
||||
'type': datetime
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
{% trans "Plugins" %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'control:event.settings.tickets' organizer=request.event.organizer.slug event=request.event.slug %}"
|
||||
{% if "event.settings.tickets" == url_name %}class="active"{% endif %} >
|
||||
{% trans "Tickets" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{% extends "pretixcontrol/event/settings_base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block inside %}
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% if "success" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "Your changes have been saved." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Ticket download" %}</legend>
|
||||
{% bootstrap_field form.ticket_download layout="horizontal" %}
|
||||
{% bootstrap_field form.ticket_download_date layout="horizontal" %}
|
||||
</fieldset>
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -13,6 +13,7 @@ urlpatterns = [
|
||||
url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
|
||||
url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),
|
||||
url(r'^settings/payment$', event.PaymentSettings.as_view(), name='event.settings.payment'),
|
||||
url(r'^settings/tickets$', event.TicketSettings.as_view(), name='event.settings.tickets'),
|
||||
url(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
||||
url(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'),
|
||||
url(r'^items/(?P<item>[0-9a-f-]+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
||||
|
||||
@@ -2,6 +2,7 @@ from collections import OrderedDict
|
||||
from django.conf import settings
|
||||
from django.shortcuts import render, redirect
|
||||
from django.utils.functional import cached_property
|
||||
from django.views.generic import FormView
|
||||
from django.views.generic.base import TemplateView
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django import forms
|
||||
@@ -303,5 +304,64 @@ class PaymentSettings(EventPermissionRequiredMixin, TemplateView, SingleObjectMi
|
||||
}) + '?success=true'
|
||||
|
||||
|
||||
class TicketSettingsForm(SettingsForm):
|
||||
ticket_download = forms.BooleanField(
|
||||
label=_("Use feature"),
|
||||
help_text=_("Use pretix to generate tickets for the user to download and print out."),
|
||||
required=False
|
||||
)
|
||||
ticket_download_date = forms.DateTimeField(
|
||||
label=_("Download date"),
|
||||
help_text=_("Ticket download will be offered after this date."),
|
||||
required=True
|
||||
)
|
||||
|
||||
def prepare_fields(self):
|
||||
# See clean()
|
||||
for k, v in self.fields.items():
|
||||
v._required = v.required
|
||||
v.required = False
|
||||
v.widget.is_required = False
|
||||
|
||||
def clean(self):
|
||||
# required=True files should only be required if the feature is enabled
|
||||
cleaned_data = super().clean()
|
||||
enabled = cleaned_data.get('ticket_download') == 'True'
|
||||
if not enabled:
|
||||
return
|
||||
for k, v in self.fields.items():
|
||||
val = cleaned_data.get(k)
|
||||
if v._required and (val is None or val == ""):
|
||||
print(enabled, k, v)
|
||||
self.add_error(k, _('This field is required.'))
|
||||
|
||||
|
||||
class TicketSettings(EventPermissionRequiredMixin, FormView):
|
||||
model = Event
|
||||
form_class = TicketSettingsForm
|
||||
template_name = 'pretixcontrol/event/tickets.html'
|
||||
permission = 'can_change_settings'
|
||||
|
||||
def form_valid(self, form):
|
||||
form.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self) -> str:
|
||||
return reverse('control:event.settings.tickets', kwargs={
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'event': self.request.event.slug
|
||||
}) + '?success=true'
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['obj'] = self.request.event
|
||||
return kwargs
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
form.prepare_fields()
|
||||
return form
|
||||
|
||||
|
||||
def index(request, organizer, event):
|
||||
return render(request, 'pretixcontrol/event/index.html', {})
|
||||
|
||||
@@ -24,6 +24,31 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if order.status == 'p' and event.settings.ticket_download %}
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{% trans "Ticket download" %}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if can_download %}
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Please use the buttons below to obtain your ticket. Please have your ticket ready when
|
||||
entering the event.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<a href="{% url "presale:event.order.download" organizer=request.event.organizer.slug event=request.event.slug order=order.code %}"
|
||||
class="btn btn-primary">
|
||||
<span class="fa fa-print"></span> {% trans "Download PDF" %}
|
||||
</a>
|
||||
{% else %}
|
||||
{% blocktrans trimmed with date=event.settings.ticket_download_date|date %}
|
||||
You will be able to download your tickets here on {{ date }}.
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="panel panel-primary cart">
|
||||
<div class="panel-heading">
|
||||
{% if order.can_modify_answers %}
|
||||
|
||||
@@ -2,6 +2,7 @@ from io import StringIO, BytesIO
|
||||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import redirect
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.functional import cached_property
|
||||
from django.views.generic import TemplateView, View
|
||||
@@ -48,6 +49,11 @@ class OrderDetails(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['order'] = self.order
|
||||
ctx['can_download'] = (
|
||||
self.request.event.settings.ticket_download
|
||||
and now() > self.request.event.settings.ticket_download_date
|
||||
and self.order.status == Order.STATUS_PAID
|
||||
)
|
||||
ctx['cart'] = self.get_cart(
|
||||
answers=True,
|
||||
queryset=OrderPosition.objects.current.filter(order=self.order)
|
||||
@@ -144,6 +150,13 @@ class OrderCancel(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
|
||||
class OrderDownload(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
|
||||
View):
|
||||
|
||||
def get_order_url(self):
|
||||
return reverse('presale:event.order', kwargs={
|
||||
'event': self.request.event.slug,
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'order': self.order.code,
|
||||
})
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
from reportlab.graphics.shapes import Drawing
|
||||
from reportlab.pdfgen import canvas
|
||||
@@ -151,8 +164,14 @@ class OrderDownload(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
|
||||
from reportlab.graphics.barcode.qr import QrCodeWidget
|
||||
from reportlab.graphics import renderPDF
|
||||
from PyPDF2 import PdfFileWriter, PdfFileReader
|
||||
|
||||
if self.order.status != Order.STATUS_PAID:
|
||||
return HttpResponseForbidden(_('Order is not paid'))
|
||||
messages.error(request, _('Order is not paid.'))
|
||||
return redirect(self.get_order_url())
|
||||
if not self.request.event.settings.ticket_download or now() < self.request.event.settings.ticket_download_date:
|
||||
messages.error(request, _('Ticket download is not (yet) enabled.'))
|
||||
return redirect(self.get_order_url())
|
||||
|
||||
response = HttpResponse(content_type='application/pdf')
|
||||
response['Content-Disposition'] = 'inline; filename="order%s%s.pdf"' % (request.event.slug, self.order.code)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user