Skip to content
Snippets Groups Projects
Verified Commit 83bd6ec1 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

To make data checks work with extra lessons/events, unify date querysets

parent 8fa4593c
No related branches found
No related tags found
1 merge request!153Resolve "Data checks ignore events and extra lessons"
Pipeline #6141 passed
import logging import logging
from django.db.models import F from django.db.models import F
from django.db.models.expressions import ExpressionWrapper, Func, Value
from django.db.models.fields import DateField
from django.db.models.functions import Concat
from django.db.models.query_utils import Q from django.db.models.query_utils import Q
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
...@@ -92,15 +89,6 @@ class NoGroupsOfPersonsSetInPersonalNotesDataCheck(DataCheck): ...@@ -92,15 +89,6 @@ class NoGroupsOfPersonsSetInPersonalNotesDataCheck(DataCheck):
cls.register_result(note) cls.register_result(note)
weekday_to_date = ExpressionWrapper(
Func(
Concat(F("year"), F("week")), Value("IYYYIW"), output_field=DateField(), function="TO_DATE"
)
+ F("lesson_period__period__weekday"),
output_field=DateField(),
)
class LessonDocumentationOnHolidaysDataCheck(DataCheck): class LessonDocumentationOnHolidaysDataCheck(DataCheck):
"""Checks for lesson documentation objects on holidays. """Checks for lesson documentation objects on holidays.
...@@ -123,13 +111,11 @@ class LessonDocumentationOnHolidaysDataCheck(DataCheck): ...@@ -123,13 +111,11 @@ class LessonDocumentationOnHolidaysDataCheck(DataCheck):
holidays = Holiday.objects.all() holidays = Holiday.objects.all()
documentations = LessonDocumentation.objects.not_empty().annotate( documentations = LessonDocumentation.objects.not_empty().annotate_date_range()
actual_date=weekday_to_date
)
q = Q() q = Q()
for holiday in holidays: for holiday in holidays:
q = q | Q(actual_date__gte=holiday.date_start, actual_date__lte=holiday.date_end) q = q | Q(day_end__gte=holiday.date_start, day_start__lte=holiday.date_end)
documentations = documentations.filter(q) documentations = documentations.filter(q)
for doc in documentations: for doc in documentations:
...@@ -159,11 +145,11 @@ class PersonalNoteOnHolidaysDataCheck(DataCheck): ...@@ -159,11 +145,11 @@ class PersonalNoteOnHolidaysDataCheck(DataCheck):
holidays = Holiday.objects.all() holidays = Holiday.objects.all()
personal_notes = PersonalNote.objects.not_empty().annotate(actual_date=weekday_to_date) personal_notes = PersonalNote.objects.not_empty().annotate_date_range()
q = Q() q = Q()
for holiday in holidays: for holiday in holidays:
q = q | Q(actual_date__gte=holiday.date_start, actual_date__lte=holiday.date_end) q = q | Q(day_end__gte=holiday.date_start, day_start__lte=holiday.date_end)
personal_notes = personal_notes.filter(q) personal_notes = personal_notes.filter(q)
for note in personal_notes: for note in personal_notes:
......
from datetime import date, datetime from datetime import date, datetime
from typing import Optional, Sequence, Union from typing import Optional, Sequence, Union
from django.db.models import QuerySet from django.db.models import Case, ExpressionWrapper, F, Func, QuerySet, Value, When
from django.db.models.fields import DateField
from django.db.models.functions import Concat
from django.db.models.query import Prefetch from django.db.models.query import Prefetch
from django.db.models.query_utils import Q from django.db.models.query_utils import Q
...@@ -11,6 +13,65 @@ from aleksis.apps.chronos.managers import DateRangeQuerySetMixin ...@@ -11,6 +13,65 @@ from aleksis.apps.chronos.managers import DateRangeQuerySetMixin
from aleksis.core.managers import CurrentSiteManagerWithoutMigrations from aleksis.core.managers import CurrentSiteManagerWithoutMigrations
class RegisterObjectRelatedQuerySet(QuerySet):
"""Common queryset for personal notes and lesson documentations with shared API."""
def _get_weekday_to_date(self, weekday_name, year_name="year", week_name="week"):
"""Get a ORM function which converts a weekday, a week and a year to a date."""
return ExpressionWrapper(
Func(
Concat(F(year_name), F(week_name)),
Value("IYYYIW"),
output_field=DateField(),
function="TO_DATE",
)
+ F(weekday_name),
output_field=DateField(),
)
def annotate_day(self) -> QuerySet:
"""Annotate every personal note/lesson documentation with the real date.
Attribute name: ``day``
.. note::
For events, this will annotate ``None``.
"""
return self.annotate(
day=Case(
When(
lesson_period__isnull=False,
then=self._get_weekday_to_date("lesson_period__period__weekday"),
),
When(
extra_lesson__isnull=False,
then=self._get_weekday_to_date(
"extra_lesson__period__weekday", "extra_lesson__year", "extra_lesson__week"
),
),
)
)
def annotate_date_range(self) -> QuerySet:
"""Annotate every personal note/lesson documentation with the real date.
Attribute names: ``day_start``, ``day_end``
.. note::
For lesson periods and extra lessons,
this will annotate the same date for start and end day.
"""
return self.annotate_day().annotate(
day_start=Case(
When(day__isnull=False, then="day"),
When(day__isnull=True, then="event__date_start"),
),
day_end=Case(
When(day__isnull=False, then="day"), When(day__isnull=True, then="event__date_end"),
),
)
class PersonalNoteManager(CurrentSiteManagerWithoutMigrations): class PersonalNoteManager(CurrentSiteManagerWithoutMigrations):
"""Manager adding specific methods to personal notes.""" """Manager adding specific methods to personal notes."""
...@@ -33,7 +94,7 @@ class PersonalNoteManager(CurrentSiteManagerWithoutMigrations): ...@@ -33,7 +94,7 @@ class PersonalNoteManager(CurrentSiteManagerWithoutMigrations):
) )
class PersonalNoteQuerySet(QuerySet): class PersonalNoteQuerySet(RegisterObjectRelatedQuerySet, QuerySet):
def not_empty(self): def not_empty(self):
"""Get all not empty personal notes.""" """Get all not empty personal notes."""
return self.filter( return self.filter(
...@@ -45,7 +106,7 @@ class LessonDocumentationManager(CurrentSiteManagerWithoutMigrations): ...@@ -45,7 +106,7 @@ class LessonDocumentationManager(CurrentSiteManagerWithoutMigrations):
pass pass
class LessonDocumentationQuerySet(QuerySet): class LessonDocumentationQuerySet(RegisterObjectRelatedQuerySet, QuerySet):
def not_empty(self): def not_empty(self):
"""Get all not empty lesson documentations.""" """Get all not empty lesson documentations."""
return self.filter(~Q(topic="") | ~Q(group_note="") | ~Q(homework="")) return self.filter(~Q(topic="") | ~Q(group_note="") | ~Q(homework=""))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment