From fc18788cb8e0da5d4984d58e8dace59cedf9124d Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 21 Aug 2020 19:06:05 +0200 Subject: [PATCH] Order API: Add ``subevent_after`` query filter --- doc/api/resources/orders.rst | 3 ++- src/pretix/api/views/order.py | 16 ++++++++++++++-- src/tests/api/test_orders.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index b662c0c0c8..23c54e3596 100644 --- a/doc/api/resources/orders.rst +++ b/doc/api/resources/orders.rst @@ -161,7 +161,7 @@ last_modified datetime Last modificati .. versionchanged:: 3.11 - The ``exclude`` query parameter has been added. + The ``exclude`` and ``subevent_after`` query parameter has been added. .. _order-position-resource: @@ -489,6 +489,7 @@ List of all orders recommend using this in combination with ``testmode=false``, since test mode orders can vanish at any time and you will not notice it using this method. :query datetime created_since: Only return orders that have been created since the given date. + :query datetime subevent_after: Only return orders that contain a ticket for a subevent taking place after the given date. :query string exclude: Exclude a field from the output, e.g. ``fees`` or ``positions.downloads``. Can be used as a performance optimization. Can be passed multiple times. :param organizer: The ``slug`` field of the organizer to fetch :param event: The ``slug`` field of the event to fetch diff --git a/src/pretix/api/views/order.py b/src/pretix/api/views/order.py index 846c13dadc..ce517f9805 100644 --- a/src/pretix/api/views/order.py +++ b/src/pretix/api/views/order.py @@ -4,8 +4,8 @@ from decimal import Decimal import django_filters import pytz from django.db import transaction -from django.db.models import Exists, F, OuterRef, Prefetch, Q -from django.db.models.functions import Coalesce, Concat +from django.db.models import Exists, F, OuterRef, Prefetch, Q, Max +from django.db.models.functions import Coalesce, Concat, Greatest from django.http import FileResponse, HttpResponse from django.shortcuts import get_object_or_404 from django.utils.timezone import make_aware, now @@ -61,12 +61,24 @@ with scopes_disabled(): status = django_filters.CharFilter(field_name='status', lookup_expr='iexact') modified_since = django_filters.IsoDateTimeFilter(field_name='last_modified', lookup_expr='gte') created_since = django_filters.IsoDateTimeFilter(field_name='datetime', lookup_expr='gte') + subevent_after = django_filters.IsoDateTimeFilter(method='subevent_after_qs') search = django_filters.CharFilter(method='search_qs') class Meta: model = Order fields = ['code', 'status', 'email', 'locale', 'testmode', 'require_approval'] + def subevent_after_qs(self, qs, name, value): + qs = qs.annotate( + max_se_date=Greatest( + Coalesce(Max('all_positions__subevent__date_to'), Max('all_positions__subevent__date_from')), + Max('all_positions__subevent__date_from') + ) + ).filter( + Q(max_se_date__isnull=True) | Q(max_se_date__gte=value) + ) + return qs + def search_qs(self, qs, name, value): u = value if "-" in value: diff --git a/src/tests/api/test_orders.py b/src/tests/api/test_orders.py index 528e1ac354..eaf7b01df7 100644 --- a/src/tests/api/test_orders.py +++ b/src/tests/api/test_orders.py @@ -255,6 +255,34 @@ TEST_ORDER_RES = { } +@pytest.mark.django_db +def test_order_list_filter_subevent_date(token_client, organizer, event, order, item, taxrule, subevent, question): + res = dict(TEST_ORDER_RES) + with scopes_disabled(): + res["positions"][0]["id"] = order.positions.first().pk + p = order.positions.first() + p.subevent = subevent + p.save() + res["positions"][0]["item"] = item.pk + res["positions"][0]["subevent"] = subevent.pk + res["positions"][0]["answers"][0]["question"] = question.pk + res["last_modified"] = order.last_modified.isoformat().replace('+00:00', 'Z') + res["fees"][0]["tax_rule"] = taxrule.pk + + resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?subevent_after={}'.format( + organizer.slug, event.slug, + (subevent.date_from + datetime.timedelta(hours=1)).isoformat().replace('+00:00', 'Z') + )) + assert resp.status_code == 200 + assert [] == resp.data['results'] + resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?subevent_after={}'.format( + organizer.slug, event.slug, + (subevent.date_from - datetime.timedelta(hours=1)).isoformat().replace('+00:00', 'Z') + )) + assert resp.status_code == 200 + assert [res] == resp.data['results'] + + @pytest.mark.django_db def test_order_list(token_client, organizer, event, order, item, taxrule, question): res = dict(TEST_ORDER_RES)