Voucher list: Refactor to use filter form

This commit is contained in:
Raphael Michel
2018-02-02 15:20:26 +01:00
parent 8a3eaae29c
commit 4ed3df2b08
3 changed files with 143 additions and 55 deletions

View File

@@ -7,7 +7,7 @@ from django.utils.timezone import now
from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from pretix.base.models import (
Event, Invoice, Item, Order, OrderPosition, Organizer, SubEvent,
Checkin, Event, Invoice, Item, Order, OrderPosition, Organizer, SubEvent,
)
from pretix.base.signals import register_payment_providers
from pretix.control.forms.widgets import Select2
@@ -596,3 +596,95 @@ class UserFilterForm(FilterForm):
qs = qs.order_by(self.get_order_by())
return qs
class VoucherFilterForm(FilterForm):
orders = {
}
status = forms.ChoiceField(
label=_('Status'),
choices=(
('', _('All')),
('v', _('Valid')),
('r', _('Redeemed')),
('e', _('Expired')),
('c', _('Redeemed and checked in with ticket')),
),
required=False
)
tag = forms.CharField(
label=_('Filter by tag'),
widget=forms.TextInput(attrs={
'placeholder': _('Filter by tag'),
}),
required=False
)
search = forms.CharField(
label=_('Search voucher'),
widget=forms.TextInput(attrs={
'placeholder': _('Search voucher'),
'autofocus': 'autofocus'
}),
required=False
)
subevent = forms.ModelChoiceField(
label=pgettext_lazy('subevent', 'Date'),
queryset=SubEvent.objects.none(),
required=False,
empty_label=pgettext_lazy('subevent', 'All dates')
)
def __init__(self, *args, **kwargs):
self.event = kwargs.pop('event')
super().__init__(*args, **kwargs)
if self.event.has_subevents:
self.fields['subevent'].queryset = self.event.subevents.all()
self.fields['subevent'].widget = Select2(
attrs={
'data-model-select2': 'event',
'data-select2-url': reverse('control:event.subevents.select2', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
}),
'data-placeholder': pgettext_lazy('subevent', 'All dates')
}
)
self.fields['subevent'].widget.choices = self.fields['subevent'].choices
elif 'subevent':
del self.fields['subevent']
def filter_qs(self, qs):
fdata = self.cleaned_data
if fdata.get('search'):
s = fdata.get('search').strip()
qs = qs.filter(Q(code__icontains=s) | Q(tag__icontains=s) | Q(comment__icontains=s))
if fdata.get('tag'):
s = fdata.get('tag').strip()
qs = qs.filter(tag__icontains=s)
if fdata.get('status'):
s = fdata.get('status')
if s == 'v':
qs = qs.filter(Q(valid_until__isnull=True) | Q(valid_until__gt=now())).filter(redeemed=0)
elif s == 'r':
qs = qs.filter(redeemed__gt=0)
elif s == 'e':
qs = qs.filter(Q(valid_until__isnull=False) & Q(valid_until__lt=now())).filter(redeemed=0)
elif s == 'c':
checkins = Checkin.objects.filter(
position__voucher=OuterRef('pk')
)
qs = qs.annotate(has_checkin=Exists(checkins)).filter(
redeemed__gt=0, has_checkin=True
)
if fdata.get('subevent'):
qs = qs.filter(subevent_id=fdata.get('subevent').pk)
if fdata.get('ordering'):
qs = qs.order_by(self.get_order_by())
return qs

View File

@@ -1,5 +1,7 @@
{% extends "pretixcontrol/vouchers/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% load urlreplace %}
{% block title %}{% trans "Vouchers" %}{% endblock %}
{% block inside %}
<p>
@@ -8,34 +10,36 @@
reserve some quota for your very special guests.
{% endblocktrans %}
</p>
<form class="form-inline helper-display-inline" action="" method="get">
<p>
<input type="text" name="search" class="form-control" placeholder="{% trans "Search voucher" %}"
value="{{ request.GET.search }}" autofocus>
<input type="text" name="tag" class="form-control" placeholder="{% trans "Filter by tag" %}"
value="{{ request.GET.tag }}">
<select name="status" class="form-control">
<option value="">{% trans "All vouchers" %}</option>
<option value="v" {% if request.GET.status == "v" %}selected="selected"{% endif %}>{% trans "Valid" %}</option>
<option value="r" {% if request.GET.status == "r" %}selected="selected"{% endif %}>{% trans "Redeemed" %}</option>
<option value="e" {% if request.GET.status == "e" %}selected="selected"{% endif %}>{% trans "Expired" %}</option>
<option value="c" {% if request.GET.status == "c" %}selected="selected"{% endif %}>{% trans "Redeemed and checked in with ticket" %}</option>
</select>
<div class="row filter-form">
<form class="" action="" method="get">
<div class="col-md-3 col-xs-6">
{% bootstrap_field filter_form.search layout='inline' %}
</div>
<div class="col-md-3 col-xs-6">
{% bootstrap_field filter_form.tag layout='inline' %}
</div>
{% if request.event.has_subevents %}
<select name="subevent" class="form-control">
<option value="">{% trans "All dates" context "subevent" %}</option>
{% for se in request.event.subevents.all %}
<option value="{{ se.id }}"
{% if request.GET.subevent|add:0 == se.id %}selected="selected"{% endif %}>
{{ se.name }} {{ se.get_date_range_display }}
</option>
{% endfor %}
</select>
<div class="col-md-2 col-xs-6">
{% bootstrap_field filter_form.status layout='inline' %}
</div>
<div class="col-md-2 col-xs-6">
{% bootstrap_field filter_form.subevent layout='inline' %}
</div>
{% else %}
<div class="col-md-4 col-xs-6">
{% bootstrap_field filter_form.status layout='inline' %}
</div>
{% endif %}
<button class="btn btn-primary" type="submit">{% trans "Filter" %}</button>
<button class="btn btn-default" type="submit" name="download" value="yes">{% trans "Download list" %}</button>
</p>
</form>
<div class="col-md-2 col-xs-6">
<button class="btn btn-primary btn-block" type="submit">
<span class="fa fa-filter"></span>
<span class="hidden-md">
{% trans "Filter" %}
</span>
</button>
</div>
</form>
</div>
{% if vouchers|length == 0 %}
<div class="empty-collection">
<p>
@@ -60,6 +64,9 @@
<a href="{% url "control:event.vouchers.bulk" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i>
{% trans "Create multiple new vouchers" %}</a>
<a href="?{% url_replace request "download" "yes" %}"
class="btn btn-default"><i class="fa fa-download"></i>
{% trans "Download list" %}</a>
</p>
<div class="table-responsive">
<table class="table table-hover table-quotas">

View File

@@ -5,19 +5,20 @@ from django.conf import settings
from django.contrib import messages
from django.core.urlresolvers import resolve, reverse
from django.db import transaction
from django.db.models import Exists, OuterRef, Q, Sum
from django.db.models import Sum
from django.http import (
Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect,
JsonResponse,
)
from django.utils.timezone import now
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.views.generic import (
CreateView, DeleteView, ListView, TemplateView, UpdateView, View,
)
from pretix.base.models import Checkin, Voucher
from pretix.base.models import Voucher
from pretix.base.models.vouchers import _generate_random_code
from pretix.control.forms.filter import VoucherFilterForm
from pretix.control.forms.vouchers import VoucherBulkForm, VoucherForm
from pretix.control.permissions import EventPermissionRequiredMixin
from pretix.control.signals import voucher_form_class
@@ -32,31 +33,19 @@ class VoucherList(PaginationMixin, EventPermissionRequiredMixin, ListView):
def get_queryset(self):
qs = self.request.event.vouchers.all().select_related('item', 'variation')
if self.request.GET.get("search", "") != "":
s = self.request.GET.get("search", "").strip()
qs = qs.filter(Q(code__icontains=s) | Q(tag__icontains=s) | Q(comment__icontains=s))
if self.request.GET.get("tag", "") != "":
s = self.request.GET.get("tag", "")
qs = qs.filter(tag__icontains=s)
if self.request.GET.get("status", "") != "":
s = self.request.GET.get("status", "")
if s == 'v':
qs = qs.filter(Q(valid_until__isnull=True) | Q(valid_until__gt=now())).filter(redeemed=0)
elif s == 'r':
qs = qs.filter(redeemed__gt=0)
elif s == 'e':
qs = qs.filter(Q(valid_until__isnull=False) & Q(valid_until__lt=now())).filter(redeemed=0)
elif s == 'c':
checkins = Checkin.objects.filter(
position__voucher=OuterRef('pk')
)
qs = qs.annotate(has_checkin=Exists(checkins)).filter(
redeemed__gt=0, has_checkin=True
)
if self.request.GET.get("subevent", "") != "":
s = self.request.GET.get("subevent", "")
qs = qs.filter(subevent_id=s)
return qs
if self.filter_form.is_valid():
qs = self.filter_form.filter_qs(qs)
return qs.distinct()
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['filter_form'] = self.filter_form
return ctx
@cached_property
def filter_form(self):
return VoucherFilterForm(data=self.request.GET, event=self.request.event)
def get(self, request, *args, **kwargs):
if request.GET.get("download", "") == "yes":