mirror of
https://github.com/pretix/pretix.git
synced 2026-05-08 15:44:02 +00:00
Order overview PDF: Allow to filter by subevent date
This commit is contained in:
@@ -112,7 +112,7 @@ def dictsum(*dicts) -> dict:
|
|||||||
|
|
||||||
def order_overview(
|
def order_overview(
|
||||||
event: Event, subevent: SubEvent=None, date_filter='', date_from=None, date_until=None, fees=False,
|
event: Event, subevent: SubEvent=None, date_filter='', date_from=None, date_until=None, fees=False,
|
||||||
admission_only=False, base_qs=None, base_fees_qs=None,
|
admission_only=False, base_qs=None, base_fees_qs=None, subevent_date_from=None, subevent_date_until=None
|
||||||
) -> Tuple[List[Tuple[ItemCategory, List[Item]]], Dict[str, Tuple[Decimal, Decimal]]]:
|
) -> Tuple[List[Tuple[ItemCategory, List[Item]]], Dict[str, Tuple[Decimal, Decimal]]]:
|
||||||
items = event.items.all().select_related(
|
items = event.items.all().select_related(
|
||||||
'category', # for re-grouping
|
'category', # for re-grouping
|
||||||
@@ -125,6 +125,11 @@ def order_overview(
|
|||||||
qs = qs.filter(subevent__in=subevent)
|
qs = qs.filter(subevent__in=subevent)
|
||||||
elif subevent:
|
elif subevent:
|
||||||
qs = qs.filter(subevent=subevent)
|
qs = qs.filter(subevent=subevent)
|
||||||
|
if subevent_date_from:
|
||||||
|
qs = qs.filter(subevent__date_from__gte=subevent_date_from)
|
||||||
|
if subevent_date_until:
|
||||||
|
qs = qs.filter(subevent__date_from__lt=subevent_date_until)
|
||||||
|
|
||||||
if admission_only:
|
if admission_only:
|
||||||
qs = qs.filter(item__admission=True)
|
qs = qs.filter(item__admission=True)
|
||||||
items = items.filter(admission=True)
|
items = items.filter(admission=True)
|
||||||
@@ -232,7 +237,7 @@ def order_overview(
|
|||||||
payment_cat_obj.name = _('Fees')
|
payment_cat_obj.name = _('Fees')
|
||||||
payment_items = []
|
payment_items = []
|
||||||
|
|
||||||
if subevent is None and fees:
|
if subevent is None and not subevent_date_from and not subevent_date_until and fees:
|
||||||
qs = OrderFee.all if base_fees_qs is None else base_fees_qs
|
qs = OrderFee.all if base_fees_qs is None else base_fees_qs
|
||||||
qs = qs.filter(
|
qs = qs.filter(
|
||||||
order__event=event
|
order__event=event
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ from pretix.base.forms.widgets import (
|
|||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
Checkin, CheckinList, Device, Event, EventMetaProperty, EventMetaValue,
|
Checkin, CheckinList, Device, Event, EventMetaProperty, EventMetaValue,
|
||||||
Gate, Invoice, InvoiceAddress, Item, Order, OrderPayment, OrderPosition,
|
Gate, Invoice, InvoiceAddress, Item, Order, OrderPayment, OrderPosition,
|
||||||
OrderRefund, Organizer, Question, QuestionAnswer, SubEvent,
|
OrderRefund, Organizer, Question, QuestionAnswer, Quota, SubEvent,
|
||||||
SubEventMetaValue, Team, TeamAPIToken, TeamInvite, Voucher,
|
SubEventMetaValue, Team, TeamAPIToken, TeamInvite, Voucher,
|
||||||
)
|
)
|
||||||
from pretix.base.signals import register_payment_providers
|
from pretix.base.signals import register_payment_providers
|
||||||
@@ -591,11 +591,10 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
|
|||||||
widget=FilterNullBooleanSelect,
|
widget=FilterNullBooleanSelect,
|
||||||
label=_('At least one ticket with check-in'),
|
label=_('At least one ticket with check-in'),
|
||||||
)
|
)
|
||||||
checkin_attention = forms.NullBooleanField(
|
quota = SafeModelChoiceField(
|
||||||
|
queryset=Quota.objects.none(),
|
||||||
|
label=_('Affected quota'),
|
||||||
required=False,
|
required=False,
|
||||||
widget=FilterNullBooleanSelect,
|
|
||||||
label=_('Requires special attention'),
|
|
||||||
help_text=_('Only matches orders with the attention checkbox set directly for the order, not based on the product.'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -680,6 +679,17 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
|
|||||||
label=_('Ticket secret'),
|
label=_('Ticket secret'),
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
|
self.fields['quota'].queryset = self.event.quotas.all()
|
||||||
|
self.fields['quota'].widget = Select2(
|
||||||
|
attrs={
|
||||||
|
'data-model-select2': 'generic',
|
||||||
|
'data-select2-url': reverse('control:event.items.quotas.select2', kwargs={
|
||||||
|
'event': self.event.slug,
|
||||||
|
'organizer': self.event.organizer.slug,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.fields['quota'].widget.choices = self.fields['quota'].choices
|
||||||
for q in self.event.questions.all():
|
for q in self.event.questions.all():
|
||||||
self.fields['question_{}'.format(q.pk)] = forms.CharField(
|
self.fields['question_{}'.format(q.pk)] = forms.CharField(
|
||||||
label=q.question,
|
label=q.question,
|
||||||
@@ -773,6 +783,12 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
|
|||||||
qs = qs.filter(
|
qs = qs.filter(
|
||||||
all_positions__secret__icontains=fdata.get('ticket_secret')
|
all_positions__secret__icontains=fdata.get('ticket_secret')
|
||||||
).distinct()
|
).distinct()
|
||||||
|
if fdata.get('quota'):
|
||||||
|
quota = fdata['quota']
|
||||||
|
qs = qs.filter(
|
||||||
|
Q(all_positions__item__in=quota.items.all(), all_positions__variation__isnull=True) |
|
||||||
|
Q(all_positions__variation__in=quota.variations.all())
|
||||||
|
).distinct()
|
||||||
for q in self.event.questions.all():
|
for q in self.event.questions.all():
|
||||||
if fdata.get(f'question_{q.pk}'):
|
if fdata.get(f'question_{q.pk}'):
|
||||||
answers = QuestionAnswer.objects.filter(
|
answers = QuestionAnswer.objects.filter(
|
||||||
|
|||||||
@@ -296,6 +296,17 @@ class OverviewReport(Report):
|
|||||||
subevent = self.form_data.get('subevent')
|
subevent = self.form_data.get('subevent')
|
||||||
story.append(Paragraph(pgettext('subevent', 'Date: {}').format(subevent), self.get_style()))
|
story.append(Paragraph(pgettext('subevent', 'Date: {}').format(subevent), self.get_style()))
|
||||||
story.append(Spacer(1, 5 * mm))
|
story.append(Spacer(1, 5 * mm))
|
||||||
|
|
||||||
|
if form_data.get('subevent_date_range'):
|
||||||
|
d_start, d_end = resolve_timeframe_to_dates_inclusive(now(), form_data['subevent_date_range'], self.timezone)
|
||||||
|
story += [
|
||||||
|
Paragraph(_('{axis} between {start} and {end}').format(
|
||||||
|
axis=_('Event date'),
|
||||||
|
start=date_format(d_start, 'SHORT_DATE_FORMAT') if d_start else '–',
|
||||||
|
end=date_format(d_end, 'SHORT_DATE_FORMAT') if d_end else '–',
|
||||||
|
), self.get_style()),
|
||||||
|
Spacer(1, 5 * mm)
|
||||||
|
]
|
||||||
return story
|
return story
|
||||||
|
|
||||||
def _get_data(self, form_data):
|
def _get_data(self, form_data):
|
||||||
@@ -303,12 +314,18 @@ class OverviewReport(Report):
|
|||||||
d_start, d_end = resolve_timeframe_to_dates_inclusive(now(), form_data['date_range'], self.timezone)
|
d_start, d_end = resolve_timeframe_to_dates_inclusive(now(), form_data['date_range'], self.timezone)
|
||||||
else:
|
else:
|
||||||
d_start, d_end = None, None
|
d_start, d_end = None, None
|
||||||
|
if form_data.get('subevent_date_range'):
|
||||||
|
sd_start, sd_end = resolve_timeframe_to_dates_inclusive(now(), form_data['subevent_date_range'], self.timezone)
|
||||||
|
else:
|
||||||
|
sd_start, sd_end = None, None
|
||||||
return order_overview(
|
return order_overview(
|
||||||
self.event,
|
self.event,
|
||||||
subevent=form_data.get('subevent'),
|
subevent=form_data.get('subevent'),
|
||||||
date_filter=form_data.get('date_axis'),
|
date_filter=form_data.get('date_axis'),
|
||||||
date_from=d_start,
|
date_from=d_start,
|
||||||
date_until=d_end,
|
date_until=d_end,
|
||||||
|
subevent_date_from=sd_start,
|
||||||
|
subevent_date_until=sd_end,
|
||||||
fees=True
|
fees=True
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -427,9 +444,18 @@ class OverviewReport(Report):
|
|||||||
@property
|
@property
|
||||||
def export_form_fields(self) -> dict:
|
def export_form_fields(self) -> dict:
|
||||||
f = OverviewFilterForm(event=self.event)
|
f = OverviewFilterForm(event=self.event)
|
||||||
|
f.fields = OrderedDict(f.fields.items())
|
||||||
del f.fields['ordering']
|
del f.fields['ordering']
|
||||||
del f.fields['date_from']
|
del f.fields['date_from']
|
||||||
del f.fields['date_until']
|
del f.fields['date_until']
|
||||||
|
if self.event.has_subevents:
|
||||||
|
f.fields['subevent_date_range'] = DateFrameField(
|
||||||
|
label=_('Event date'),
|
||||||
|
include_future_frames=True,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
f.fields.move_to_end("subevent_date_range", last=False)
|
||||||
|
f.fields.move_to_end("subevent", last=False)
|
||||||
f.fields['date_range'] = DateFrameField(
|
f.fields['date_range'] = DateFrameField(
|
||||||
label=_('Date range'),
|
label=_('Date range'),
|
||||||
include_future_frames=False,
|
include_future_frames=False,
|
||||||
|
|||||||
Reference in New Issue
Block a user