Skip to content

Commit

Permalink
Add ordering filters for application event schedules
Browse files Browse the repository at this point in the history
  • Loading branch information
MrThearMan committed Dec 14, 2023
1 parent 79c9b3e commit 96bbdb4
Show file tree
Hide file tree
Showing 5 changed files with 1,216 additions and 680 deletions.
25 changes: 24 additions & 1 deletion api/graphql/types/application_event_schedule/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.contrib.postgres.search import SearchVector
from django.db.models import QuerySet

from api.graphql.extensions.order_filter import CustomOrderingFilter
from applications.choices import ApplicantTypeChoice, ApplicationEventStatusChoice
from applications.models import ApplicationEventSchedule
from applications.querysets.application_event_schedule import ApplicationEventScheduleQuerySet
Expand Down Expand Up @@ -33,11 +34,21 @@ class ApplicationEventScheduleFilterSet(BaseModelFilterSet):

text_search = django_filters.CharFilter(method="filter_text_search")

order_by = django_filters.OrderingFilter(
order_by = CustomOrderingFilter(
fields=[
"pk",
("application_event__id", "application_event_id"),
("application_event__application__id", "application_id"),
"applicant",
("allocated_reservation_unit__unit__name_fi", "allocated_unit_name_fi"),
("allocated_reservation_unit__unit__name_en", "allocated_unit_name_en"),
("allocated_reservation_unit__unit__name_sv", "allocated_unit_name_sv"),
("allocated_reservation_unit__name_fi", "allocated_reservation_unit_name_fi"),
("allocated_reservation_unit__name_en", "allocated_reservation_unit_name_en"),
("allocated_reservation_unit__name_sv", "allocated_reservation_unit_name_sv"),
"allocated_time_of_week",
"application_status",
"application_event_status",
]
)

Expand All @@ -64,3 +75,15 @@ def filter_text_search(qs: ApplicationEventScheduleQuerySet, name: str, value: s
)
query = raw_prefixed_query(value)
return qs.annotate(search=vector).filter(search=query)

@staticmethod
def order_by_allocated_time_of_week(qs: ApplicationEventScheduleQuerySet, desc: bool) -> QuerySet:
return qs.order_by_allocated_time_of_week(desc=desc)

@staticmethod
def order_by_application_status(qs: ApplicationEventScheduleQuerySet, desc: bool) -> QuerySet:
return qs.order_by_application_status(desc=desc)

@staticmethod
def order_by_application_event_status(qs: ApplicationEventScheduleQuerySet, desc: bool) -> QuerySet:
return qs.order_by_application_event_status(desc=desc)
60 changes: 60 additions & 0 deletions applications/querysets/application_event_schedule.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
from typing import Self

from django.db import models
from django.db.models import Case, Value, When
from django.db.models.functions import Cast, Concat

from applications.choices import ApplicationEventStatusChoice
from applications.querysets.helpers import (
applicant_alias_case,
application_event_status_case,
application_event_status_required_aliases,
application_status_case,
unallocated_schedule_count,
)


class ApplicationEventScheduleQuerySet(models.QuerySet):
def order_by_expression(self, alias: str, expression: models.Expression, *, desc: bool = False) -> Self:
order_by = models.OrderBy(models.F(alias), descending=desc)
return self.alias(**{alias: expression}).order_by(order_by)

def allocated(self) -> Self:
return self.exclude(
models.Q(allocated_begin__isnull=True)
Expand All @@ -19,6 +27,13 @@ def allocated(self) -> Self:
| models.Q(allocated_reservation_unit__isnull=True)
)

def with_application_status(self) -> Self:
return self.alias(
unallocated_schedule_count=unallocated_schedule_count("application_event"),
).annotate(
application_status=application_status_case("application_event__application"),
)

def with_event_status(self) -> Self:
return self.alias(
**application_event_status_required_aliases("application_event"),
Expand All @@ -34,3 +49,48 @@ def has_event_status(self, status: ApplicationEventStatusChoice) -> Self:

def has_event_status_in(self, statuses: list[str]) -> Self:
return self.with_event_status().filter(event_status__in=statuses)

def order_by_allocated_time_of_week(self, *, desc: bool = False) -> Self:
return self.allocated_time_of_week_alias().order_by(
models.OrderBy(models.F("allocated_time_of_week"), descending=desc),
)

def allocated_time_of_week_alias(self) -> Self:
"""Annotate allocated time of week as a string of the form `w-hh:mm:ss-hh:mm:ss`"""
return self.alias(
allocated_time_of_week=Case(
When(
condition=(
models.Q(allocated_day__isnull=False)
& models.Q(allocated_begin__isnull=False)
& models.Q(allocated_end__isnull=False)
),
then=Concat(
Cast("allocated_day", output_field=models.CharField(max_length=1)),
Value("-"),
Cast("allocated_begin", output_field=models.CharField(max_length=8)),
Value("-"),
Cast("allocated_end", output_field=models.CharField(max_length=8)),
),
),
default=None,
),
)

def order_by_application_status(self, *, desc: bool = False) -> Self:
from applications.querysets.application import APPLICATION_STATUS_SORT_ORDER

return self.with_application_status().order_by_expression(
alias="__application_status",
expression=APPLICATION_STATUS_SORT_ORDER,
desc=desc,
)

def order_by_application_event_status(self, *, desc: bool = False) -> Self:
from applications.querysets.application_event import APPLICATION_EVENT_STATUS_SORT_ORDER

return self.with_event_status().order_by_expression(
alias="__event_status",
expression=APPLICATION_EVENT_STATUS_SORT_ORDER,
desc=desc,
)
Loading

0 comments on commit 96bbdb4

Please sign in to comment.