forked from CGM_Public/pretix_original
Order data export: Allow to filter by product (Z#23212618) (#5826)
* Order data export: Allow to filter by product (Z#23212618) * Fix tests
This commit is contained in:
@@ -39,8 +39,8 @@ from zoneinfo import ZoneInfo
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
Case, CharField, Count, DateTimeField, F, IntegerField, Max, Min, OuterRef,
|
Case, CharField, Count, DateTimeField, Exists, F, IntegerField, Max, Min,
|
||||||
Q, Subquery, Sum, When,
|
OuterRef, Q, Subquery, Sum, When,
|
||||||
)
|
)
|
||||||
from django.db.models.functions import Coalesce
|
from django.db.models.functions import Coalesce
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
@@ -144,6 +144,18 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
d = OrderedDict(d)
|
d = OrderedDict(d)
|
||||||
if not self.is_multievent and not self.event.has_subevents:
|
if not self.is_multievent and not self.event.has_subevents:
|
||||||
del d['event_date_range']
|
del d['event_date_range']
|
||||||
|
if not self.is_multievent:
|
||||||
|
d["items"] = forms.ModelMultipleChoiceField(
|
||||||
|
label=_("Products"),
|
||||||
|
queryset=self.event.items.all(),
|
||||||
|
widget=forms.CheckboxSelectMultiple(
|
||||||
|
attrs={"class": "scrolling-multiple-choice"}
|
||||||
|
),
|
||||||
|
help_text=_("If none are selected, all products are included. Orders are included if they contain "
|
||||||
|
"at least one position of this product. The order totals etc. still include all products "
|
||||||
|
"contained in the order."),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def _get_all_payment_methods(self, qs):
|
def _get_all_payment_methods(self, qs):
|
||||||
@@ -249,6 +261,14 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
pcnt=Subquery(s, output_field=IntegerField())
|
pcnt=Subquery(s, output_field=IntegerField())
|
||||||
).select_related('invoice_address', 'customer')
|
).select_related('invoice_address', 'customer')
|
||||||
|
|
||||||
|
if form_data.get('items'):
|
||||||
|
qs = qs.filter(
|
||||||
|
Exists(OrderPosition.all.filter(
|
||||||
|
order=OuterRef('pk'),
|
||||||
|
item__in=form_data["items"]
|
||||||
|
))
|
||||||
|
)
|
||||||
|
|
||||||
qs = self._date_filter(qs, form_data, rel='')
|
qs = self._date_filter(qs, form_data, rel='')
|
||||||
|
|
||||||
if form_data['paid_only']:
|
if form_data['paid_only']:
|
||||||
@@ -440,6 +460,14 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
if form_data['paid_only']:
|
if form_data['paid_only']:
|
||||||
qs = qs.filter(order__status=Order.STATUS_PAID, canceled=False)
|
qs = qs.filter(order__status=Order.STATUS_PAID, canceled=False)
|
||||||
|
|
||||||
|
if form_data.get('items'):
|
||||||
|
qs = qs.filter(
|
||||||
|
Exists(OrderPosition.all.filter(
|
||||||
|
order=OuterRef('order'),
|
||||||
|
item__in=form_data["items"]
|
||||||
|
))
|
||||||
|
)
|
||||||
|
|
||||||
qs = self._date_filter(qs, form_data, rel='order__')
|
qs = self._date_filter(qs, form_data, rel='order__')
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
@@ -535,6 +563,11 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
if form_data['paid_only']:
|
if form_data['paid_only']:
|
||||||
qs = qs.filter(order__status=Order.STATUS_PAID, canceled=False)
|
qs = qs.filter(order__status=Order.STATUS_PAID, canceled=False)
|
||||||
|
|
||||||
|
if form_data.get('items'):
|
||||||
|
qs = qs.filter(
|
||||||
|
item__in=form_data["items"]
|
||||||
|
)
|
||||||
|
|
||||||
qs = self._date_filter(qs, form_data, rel='order__')
|
qs = self._date_filter(qs, form_data, rel='order__')
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ SAMPLE_EXPORTER_CONFIG = {
|
|||||||
"name": "event_date_range",
|
"name": "event_date_range",
|
||||||
"required": False
|
"required": False
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "items",
|
||||||
|
"required": False
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +111,10 @@ def test_org_list(token_client, organizer, event):
|
|||||||
"name": "events",
|
"name": "events",
|
||||||
"required": False
|
"required": False
|
||||||
})
|
})
|
||||||
|
c['input_parameters'].remove({
|
||||||
|
"name": "items",
|
||||||
|
"required": False
|
||||||
|
})
|
||||||
resp = token_client.get('/api/v1/organizers/{}/exporters/'.format(organizer.slug))
|
resp = token_client.get('/api/v1/organizers/{}/exporters/'.format(organizer.slug))
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
assert c in resp.data['results']
|
assert c in resp.data['results']
|
||||||
@@ -389,7 +397,7 @@ def test_event_scheduled_export_create(user_client, organizer, event, user):
|
|||||||
'/api/v1/organizers/{}/events/{}/scheduled_exports/'.format(organizer.slug, event.slug),
|
'/api/v1/organizers/{}/events/{}/scheduled_exports/'.format(organizer.slug, event.slug),
|
||||||
data={
|
data={
|
||||||
"export_identifier": "orderlist",
|
"export_identifier": "orderlist",
|
||||||
"export_form_data": {"_format": "xlsx", "date_range": "year_this"},
|
"export_form_data": {"_format": "xlsx", "date_range": "year_this", "items": []},
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
"mail_additional_recipients": "foo@example.org",
|
"mail_additional_recipients": "foo@example.org",
|
||||||
"mail_additional_recipients_cc": "",
|
"mail_additional_recipients_cc": "",
|
||||||
@@ -403,7 +411,7 @@ def test_event_scheduled_export_create(user_client, organizer, event, user):
|
|||||||
)
|
)
|
||||||
assert resp.status_code == 201
|
assert resp.status_code == 201
|
||||||
created = event.scheduled_exports.get(id=resp.data["id"])
|
created = event.scheduled_exports.get(id=resp.data["id"])
|
||||||
assert created.export_form_data == {"_format": "xlsx", "date_range": "year_this"}
|
assert created.export_form_data == {"_format": "xlsx", "date_range": "year_this", "items": []}
|
||||||
assert created.owner == user
|
assert created.owner == user
|
||||||
assert created.schedule_next_run > now()
|
assert created.schedule_next_run > now()
|
||||||
|
|
||||||
@@ -414,7 +422,7 @@ def test_event_scheduled_export_create_requires_user(token_client, organizer, ev
|
|||||||
'/api/v1/organizers/{}/events/{}/scheduled_exports/'.format(organizer.slug, event.slug),
|
'/api/v1/organizers/{}/events/{}/scheduled_exports/'.format(organizer.slug, event.slug),
|
||||||
data={
|
data={
|
||||||
"export_identifier": "orderlist",
|
"export_identifier": "orderlist",
|
||||||
"export_form_data": {"_format": "xlsx", "date_range": "year_this"},
|
"export_form_data": {"_format": "xlsx", "date_range": "year_this", "items": []},
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
"mail_additional_recipients": "foo@example.org",
|
"mail_additional_recipients": "foo@example.org",
|
||||||
"mail_additional_recipients_cc": "",
|
"mail_additional_recipients_cc": "",
|
||||||
@@ -453,7 +461,7 @@ def test_event_scheduled_export_update_token(token_client, organizer, event, use
|
|||||||
)
|
)
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
created = event.scheduled_exports.get(id=resp.data["id"])
|
created = event.scheduled_exports.get(id=resp.data["id"])
|
||||||
assert created.export_form_data == {"_format": "xlsx", "date_range": "month_this"}
|
assert created.export_form_data == {"_format": "xlsx", "date_range": "month_this", "items": []}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|||||||
Reference in New Issue
Block a user