Add filter for date for multiple exporters

This commit is contained in:
Raphael Michel
2021-03-29 12:05:56 +02:00
parent 2b660ccbf7
commit 7d5170155a
5 changed files with 190 additions and 28 deletions

View File

@@ -1,16 +1,19 @@
import copy
import json
from collections import OrderedDict
from datetime import datetime, time, timedelta
from io import BytesIO
from typing import Tuple
import dateutil.parser
from django import forms
from django.conf import settings
from django.contrib.staticfiles import finders
from django.core.files import File
from django.core.files.storage import default_storage
from django.db.models import Exists, OuterRef
from django.db.models import Exists, OuterRef, Q
from django.db.models.functions import Coalesce
from django.utils.timezone import make_aware
from django.utils.translation import gettext as _, gettext_lazy
from jsonfallback.functions import JSONExtract
from reportlab.lib import pagesizes
@@ -236,12 +239,27 @@ class BadgeExporter(BaseExporter):
'want to print to a sheet of stickers with a regular office printer. Please note '
'that your individual badge layouts must already be in the correct size.')
)),
('date_from',
forms.DateField(
label=_('Start date'),
widget=forms.DateInput(attrs={'class': 'datepickerfield'}),
required=False,
help_text=_('Only include tickets for dates on or after this date.')
)),
('date_to',
forms.DateField(
label=_('End date'),
widget=forms.DateInput(attrs={'class': 'datepickerfield'}),
required=False,
help_text=_('Only include tickets for dates on or before this date.')
)),
('order_by',
forms.ChoiceField(
label=_('Sort by'),
choices=[
('name', _('Attendee name')),
('code', _('Order code')),
('date', _('Event date')),
] + ([
('name:{}'.format(k), _('Attendee name: {part}').format(part=label))
for k, label, w in name_scheme['fields']
@@ -266,10 +284,26 @@ class BadgeExporter(BaseExporter):
else:
qs = qs.filter(order__status__in=[Order.STATUS_PAID])
if form_data.get('date_from'):
dt = make_aware(datetime.combine(
dateutil.parser.parse(form_data['date_from']).date(),
time(hour=0, minute=0, second=0)
), self.event.timezone)
qs = qs.filter(Q(subevent__date_from__gte=dt) | Q(subevent__isnull=True, order__event__date_from__gte=dt))
if form_data.get('date_to'):
dt = make_aware(datetime.combine(
dateutil.parser.parse(form_data['date_to']).date() + timedelta(days=1),
time(hour=0, minute=0, second=0)
), self.event.timezone)
qs = qs.filter(Q(subevent__date_from__lt=dt) | Q(subevent__isnull=True, order__event__date_from__lt=dt))
if form_data.get('order_by') == 'name':
qs = qs.order_by('attendee_name_cached', 'order__code')
elif form_data.get('order_by') == 'code':
qs = qs.order_by('order__code')
elif form_data.get('order_by') == 'date':
qs = qs.annotate(ed=Coalesce('subevent__date_from', 'order__event__date_from')).order_by('ed', 'order__code')
elif form_data.get('order_by', '').startswith('name:'):
part = form_data['order_by'][5:]
qs = qs.annotate(

View File

@@ -1,10 +1,14 @@
from collections import OrderedDict
from datetime import datetime, time, timedelta
from io import BytesIO
import dateutil.parser
from django import forms
from django.conf import settings
from django.core.files.base import ContentFile
from django.db.models import Q
from django.db.models.functions import Coalesce
from django.utils.timezone import make_aware
from django.utils.translation import gettext as _, gettext_lazy
from jsonfallback.functions import JSONExtract
from PyPDF2.merger import PdfFileMerger
@@ -32,12 +36,27 @@ class AllTicketsPDF(BaseExporter):
label=_('Include pending orders'),
required=False
)),
('date_from',
forms.DateField(
label=_('Start date'),
widget=forms.DateInput(attrs={'class': 'datepickerfield'}),
required=False,
help_text=_('Only include tickets for dates on or after this date.')
)),
('date_to',
forms.DateField(
label=_('End date'),
widget=forms.DateInput(attrs={'class': 'datepickerfield'}),
required=False,
help_text=_('Only include tickets for dates on or before this date.')
)),
('order_by',
forms.ChoiceField(
label=_('Sort by'),
choices=[
('name', _('Attendee name')),
('code', _('Order code')),
('date', _('Event date')),
] + ([
('name:{}'.format(k), _('Attendee name: {part}').format(part=label))
for k, label, w in name_scheme['fields']
@@ -45,6 +64,11 @@ class AllTicketsPDF(BaseExporter):
)),
]
)
if not self.is_multievent and not self.event.has_subevents:
del d['date_from']
del d['date_to']
return d
def render(self, form_data):
@@ -60,10 +84,26 @@ class AllTicketsPDF(BaseExporter):
else:
qs = qs.filter(order__status__in=[Order.STATUS_PAID])
if form_data.get('date_from'):
dt = make_aware(datetime.combine(
dateutil.parser.parse(form_data['date_from']).date(),
time(hour=0, minute=0, second=0)
), self.event.timezone)
qs = qs.filter(Q(subevent__date_from__gte=dt) | Q(subevent__isnull=True, order__event__date_from__gte=dt))
if form_data.get('date_to'):
dt = make_aware(datetime.combine(
dateutil.parser.parse(form_data['date_to']).date() + timedelta(days=1),
time(hour=0, minute=0, second=0)
), self.event.timezone)
qs = qs.filter(Q(subevent__date_from__lt=dt) | Q(subevent__isnull=True, order__event__date_from__lt=dt))
if form_data.get('order_by') == 'name':
qs = qs.order_by('attendee_name_cached', 'order__code')
elif form_data.get('order_by') == 'code':
qs = qs.order_by('order__code')
elif form_data.get('order_by') == 'date':
qs = qs.annotate(ed=Coalesce('subevent__date_from', 'order__event__date_from')).order_by('ed', 'order__code')
elif form_data.get('order_by', '').startswith('name:'):
part = form_data['order_by'][5:]
qs = qs.annotate(