From 8ea9d5685dcc2ee224e40e3b2a180a3979e0b913 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Wed, 28 Jun 2017 17:28:30 +0200 Subject: [PATCH] Use FilterForm for list of orders --- src/pretix/control/forms/filter.py | 98 +++++++++++++++++- .../templates/pretixcontrol/orders/index.html | 99 +++++++++---------- .../pretixcontrol/search/orders.html | 4 +- src/pretix/control/views/orders.py | 46 ++------- src/pretix/control/views/search.py | 30 +----- 5 files changed, 157 insertions(+), 120 deletions(-) diff --git a/src/pretix/control/forms/filter.py b/src/pretix/control/forms/filter.py index f6cc4a3a3b..36cdea5b94 100644 --- a/src/pretix/control/forms/filter.py +++ b/src/pretix/control/forms/filter.py @@ -1,10 +1,13 @@ from django import forms +from django.db.models import Q +from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ -from pretix.base.models import Organizer +from pretix.base.models import Item, Order, Organizer +from pretix.base.signals import register_payment_providers -class OrderSearchFilterForm(forms.Form): +class OrderFilterForm(forms.Form): query = forms.CharField( label=_('Search for…'), widget=forms.TextInput(attrs={ @@ -27,6 +30,88 @@ class OrderSearchFilterForm(forms.Form): ), required=False, ) + + def filter_qs(self, qs): + fdata = self.cleaned_data + + if fdata.get('query'): + u = fdata.get('query') + if "-" in u: + code = (Q(event__slug__icontains=u.split("-")[0]) + & Q(code__icontains=Order.normalize_code(u.split("-")[1]))) + else: + code = Q(code__icontains=Order.normalize_code(u)) + qs = qs.filter( + code + | Q(email__icontains=u) + | Q(positions__attendee_name__icontains=u) + | Q(positions__attendee_email__icontains=u) + | Q(invoice_address__name__icontains=u) + | Q(invoice_address__company__icontains=u) + ) + + if fdata.get('status'): + s = fdata.get('status') + if s == 'o': + qs = qs.filter(status=Order.STATUS_PENDING, expires__lt=now().replace(hour=0, minute=0, second=0)) + elif s == 'ne': + qs = qs.filter(status__in=[Order.STATUS_PENDING, Order.STATUS_EXPIRED]) + else: + qs = qs.filter(status=s) + + return qs + + @property + def filtered(self): + return self.is_valid() and any(self.cleaned_data.values()) + + +class EventOrderFilterForm(OrderFilterForm): + item = forms.ModelChoiceField( + label=_('Products'), + queryset=Item.objects.none(), + required=False, + empty_label=_('All products') + ) + provider = forms.ChoiceField( + label=_('Payment provider'), + choices=[ + ('', _('All payment providers')), + ], + required=False, + ) + + def get_payment_providers(self): + providers = [] + responses = register_payment_providers.send(self.event) + for receiver, response in responses: + provider = response(self.event) + providers.append({ + 'name': provider.identifier, + 'verbose_name': provider.verbose_name + }) + return providers + + def __init__(self, *args, **kwargs): + self.event = kwargs.pop('event') + super().__init__(*args, **kwargs) + self.fields['item'].queryset = self.event.items.all() + self.fields['provider'].choices += [(p['name'], p['verbose_name']) for p in self.get_payment_providers()] + + def filter_qs(self, qs): + fdata = self.cleaned_data + qs = super().filter_qs(qs) + + if fdata.get('item'): + qs = qs.filter(positions__item_id__in=(fdata.get('item'),)) + + if fdata.get('provider'): + qs = qs.filter(payment_provider=fdata.get('provider')) + + return qs + + +class OrderSearchFilterForm(OrderFilterForm): organizer = forms.ModelChoiceField( label=_('Organizer'), queryset=Organizer.objects.none(), @@ -43,3 +128,12 @@ class OrderSearchFilterForm(forms.Form): self.fields['organizer'].queryset = Organizer.objects.filter( pk__in=request.user.teams.values_list('organizer', flat=True) ) + + def filter_qs(self, qs): + fdata = self.cleaned_data + qs = super().filter_qs(qs) + + if fdata.get('organizer'): + qs = qs.filter(event__organizer=fdata.get('organizer')) + + return qs diff --git a/src/pretix/control/templates/pretixcontrol/orders/index.html b/src/pretix/control/templates/pretixcontrol/orders/index.html index 60f9df4d3e..b899a032b4 100644 --- a/src/pretix/control/templates/pretixcontrol/orders/index.html +++ b/src/pretix/control/templates/pretixcontrol/orders/index.html @@ -2,6 +2,7 @@ {% load i18n %} {% load eventurl %} {% load urlreplace %} +{% load bootstrap3 %} {% block title %}{% trans "Orders" %}{% endblock %} {% block content %}

{% trans "Orders" %}

@@ -25,64 +26,60 @@ {% endif %} {% else %} -

-

-
- - +
+ +
+ + -
- -
- - - - - -
-

+
+ +
+
+ {% bootstrap_field filter_form.status layout='inline' %} +
+
+ {% bootstrap_field filter_form.item layout='inline' %} +
+
+ {% bootstrap_field filter_form.provider layout='inline' %} +
+
+ {% bootstrap_field filter_form.query layout='inline' %} +
+
+ +
+
+
{% include "pretixcontrol/pagination.html" %}
- - - - - + + + + + diff --git a/src/pretix/control/templates/pretixcontrol/search/orders.html b/src/pretix/control/templates/pretixcontrol/search/orders.html index 8516a0fba1..1dc7e8ef55 100644 --- a/src/pretix/control/templates/pretixcontrol/search/orders.html +++ b/src/pretix/control/templates/pretixcontrol/search/orders.html @@ -19,7 +19,9 @@
diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index f6f9b2fc39..419ec33b39 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -3,7 +3,6 @@ from datetime import timedelta from django.conf import settings from django.contrib import messages from django.core.urlresolvers import reverse -from django.db.models import Q from django.http import FileResponse, Http404, HttpResponseNotAllowed from django.shortcuts import redirect, render from django.utils.functional import cached_property @@ -31,6 +30,7 @@ from pretix.base.signals import ( register_data_exporters, register_payment_providers, ) from pretix.base.views.async import AsyncAction +from pretix.control.forms.filter import EventOrderFilterForm from pretix.control.forms.orders import ( CommentForm, ExporterForm, ExtendForm, OrderContactForm, OrderLocaleForm, OrderPositionAddForm, OrderPositionChangeForm, @@ -50,28 +50,9 @@ class OrderList(EventPermissionRequiredMixin, ListView): qs = Order.objects.filter( event=self.request.event ) - if self.request.GET.get("user", "") != "": - u = self.request.GET.get("user", "") - qs = qs.filter( - Q(email__icontains=u) | Q(positions__attendee_name__icontains=u) - | Q(positions__attendee_email__icontains=u) - | Q(invoice_address__name__icontains=u) - | Q(invoice_address__company__icontains=u) - ) - if self.request.GET.get("status", "") != "": - s = self.request.GET.get("status", "") - if s == 'o': - qs = qs.filter(status=Order.STATUS_PENDING, expires__lt=now().replace(hour=0, minute=0, second=0)) - elif s == 'ne': - qs = qs.filter(status__in=[Order.STATUS_PENDING, Order.STATUS_EXPIRED]) - else: - qs = qs.filter(status=s) - if self.request.GET.get("item", "") != "": - i = self.request.GET.get("item", "") - qs = qs.filter(positions__item_id__in=(i,)) - if self.request.GET.get("provider", "") != "": - p = self.request.GET.get("provider", "") - qs = qs.filter(payment_provider=p) + if self.filter_form.is_valid(): + qs = self.filter_form.filter_qs(qs) + if self.request.GET.get("ordering", "") != "": p = self.request.GET.get("ordering", "") p_admissable = ('-code', 'code', '-email', 'email', '-total', 'total', '-datetime', 'datetime', '-status', 'status') @@ -80,24 +61,15 @@ class OrderList(EventPermissionRequiredMixin, ListView): return qs.distinct() - def get_payment_providers(self): - providers = [] - responses = register_payment_providers.send(self.request.event) - for receiver, response in responses: - provider = response(self.request.event) - providers.append({ - 'name': provider.identifier, - 'verbose_name': provider.verbose_name - }) - return providers - def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) - ctx['items'] = Item.objects.filter(event=self.request.event) - ctx['filtered'] = ("status" in self.request.GET or "item" in self.request.GET or "user" in self.request.GET or "provider" in self.request.GET) - ctx['providers'] = self.get_payment_providers() + ctx['filter_form'] = self.filter_form return ctx + @cached_property + def filter_form(self): + return EventOrderFilterForm(data=self.request.GET, event=self.request.event) + class OrderView(EventPermissionRequiredMixin, DetailView): context_object_name = 'order' diff --git a/src/pretix/control/views/search.py b/src/pretix/control/views/search.py index 8cb50bda82..1969e2da44 100644 --- a/src/pretix/control/views/search.py +++ b/src/pretix/control/views/search.py @@ -1,6 +1,5 @@ from django.db.models import Q from django.utils.functional import cached_property -from django.utils.timezone import now from django.views.generic import ListView from pretix.base.models import Order @@ -33,34 +32,7 @@ class OrderSearch(ListView): ) if self.filter_form.is_valid(): - fdata = self.filter_form.cleaned_data - if fdata.get('query'): - u = fdata.get('query') - if "-" in u: - code = (Q(event__slug__icontains=u.split("-")[0]) - & Q(code__icontains=Order.normalize_code(u.split("-")[1]))) - else: - code = Q(code__icontains=Order.normalize_code(u)) - qs = qs.filter( - code - | Q(email__icontains=u) - | Q(positions__attendee_name__icontains=u) - | Q(positions__attendee_email__icontains=u) - | Q(invoice_address__name__icontains=u) - | Q(invoice_address__company__icontains=u) - ) - - if fdata.get('status'): - s = fdata.get('status') - if s == 'o': - qs = qs.filter(status=Order.STATUS_PENDING, expires__lt=now().replace(hour=0, minute=0, second=0)) - elif s == 'ne': - qs = qs.filter(status__in=[Order.STATUS_PENDING, Order.STATUS_EXPIRED]) - else: - qs = qs.filter(status=s) - - if fdata.get('organizer'): - qs = qs.filter(event__organizer=fdata.get('organizer')) + qs = self.filter_form.filter_qs(qs) if self.request.GET.get("ordering", "") != "": p = self.request.GET.get("ordering", "")
{% trans "Order code" %} - {% trans "User" %} - {% trans "Order total" %} - {% trans "Order date" %} - {% trans "Status" %} - {% trans "Order code" %} + + {% trans "User" %} + + {% trans "Order total" %} + + {% trans "Order date" %} + + + {% trans "Status" %} + +