diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py index b5ac19b21ab7e7895d9429c0e0b5e7f841c50c89..a80d22be6058a173cb6f4b3da80283d6ca0f55bd 100644 --- a/aleksis/apps/alsijil/model_extensions.py +++ b/aleksis/apps/alsijil/model_extensions.py @@ -1,4 +1,4 @@ -from django.db.models import FilteredRelation, Q, QuerySet +from django.db.models import FilteredRelation, Q, QuerySet, Value from django.db.models.aggregates import Count, Sum from django.utils.translation import gettext as _ @@ -34,36 +34,58 @@ Person.add_permission("register_absence_person", _("Can register an absence for def annotate_person_statistics( - persons: QuerySet[Person], participations_filter: Q, personal_notes_filter: Q + persons: QuerySet[Person], + participations_filter: Q, + personal_notes_filter: Q, + *, + ignore_filters: bool = False, ) -> QuerySet[Person]: """Annotate a queryset of persons with class register statistics.""" - persons = persons.annotate( - filtered_participation_statuses=FilteredRelation( - "participations", - condition=(participations_filter), - ), - filtered_personal_notes=FilteredRelation( - "new_personal_notes", - condition=(personal_notes_filter), - ), - ).annotate( - participation_count=Count( - "filtered_participation_statuses", - filter=Q(filtered_participation_statuses__absence_reason__isnull=True), - distinct=True, - ), - absence_count=Count( - "filtered_participation_statuses", - filter=Q(filtered_participation_statuses__absence_reason__count_as_absent=True), - distinct=True, - ), - tardiness_sum=Sum("filtered_participation_statuses__tardiness", distinct=True), - tardiness_count=Count( - "filtered_participation_statuses", - filter=Q(filtered_participation_statuses__tardiness__gt=0), - distinct=True, - ), - ) + + if ignore_filters: + persons = persons.annotate( + absence_count=Value(0), + filtered_participation_statuses=FilteredRelation( + "participations", + condition=Q(pk=None), + ), + filtered_personal_notes=FilteredRelation( + "new_personal_notes", + condition=Q(pk=None), + ), + participation_count=Value(0), + tardiness_count=Value(0), + tardiness_sum=Value(0), + ) + else: + persons = persons.annotate( + filtered_participation_statuses=FilteredRelation( + "participations", + condition=(participations_filter), + ), + filtered_personal_notes=FilteredRelation( + "new_personal_notes", + condition=(personal_notes_filter), + ), + ).annotate( + participation_count=Count( + "filtered_participation_statuses", + filter=Q(filtered_participation_statuses__absence_reason__isnull=True), + distinct=True, + ), + absence_count=Count( + "filtered_participation_statuses", + filter=Q(filtered_participation_statuses__absence_reason__count_as_absent=True), + distinct=True, + ), + tardiness_sum=Sum("filtered_participation_statuses__tardiness", distinct=True), + tardiness_count=Count( + "filtered_participation_statuses", + filter=Q(filtered_participation_statuses__tardiness__gt=0), + distinct=True, + ), + ) + persons = persons.order_by("last_name", "first_name") for absence_reason in AbsenceReason.objects.all(): @@ -116,4 +138,5 @@ def annotate_person_statistics_for_school_term( persons, Q(participations__related_documentation__in=docs), Q(new_personal_notes__documentation__in=docs), + ignore_filters=len(docs) == 0, )