Skip to content
Snippets Groups Projects

Resolve "Substitutions PDF for new data model"

Merged magicfelix requested to merge 215-substitutions-pdf-for-new-data-model into master
All threads resolved!
Compare changes
  • Side-by-side
  • Inline
Files
13
  • 92a25fff
    diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py
    index 35f4e01..f348c00 100644
    --- a/aleksis/apps/chronos/models.py
    +++ b/aleksis/apps/chronos/models.py
    @@ -1221,6 +1221,7 @@ class AutomaticPlan(LiveDocument):
             from aleksis.apps.chronos.util.chronos_helpers import get_substitutions_context_data  # noqa
    
             context = get_substitutions_context_data(
    +            wanted_day=date.today(),
                 request=None,
                 is_print=True,
                 number_of_days=self.number_of_days,
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/rooms.html b/aleksis/apps/chronos/templates/chronos/partials/rooms.html
    new file mode 100644
    index 0000000..1e42988
    --- /dev/null
    +++ b/aleksis/apps/chronos/templates/chronos/partials/rooms.html
    @@ -0,0 +1,8 @@
    +{% for room in rooms %}
    +  <span data-position="bottom" class="tooltipped"
    +        data-tooltip="{{ room }}">
    +      <a href="{% url "timetable" "room" room.pk %}">
    +          {{ room.short_name }}{% if not forloop.last %},{% endif %}
    +      </a>
    +  </span>
    +{% endfor %}
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/badge.html b/aleksis/apps/chronos/templates/chronos/partials/subs/badge.html
    index c04c9dd..c807244 100644
    --- a/aleksis/apps/chronos/templates/chronos/partials/subs/badge.html
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/badge.html
    @@ -2,6 +2,4 @@
    
     {% if sub.cancelled %}
       <span class="badge new green">{% trans "Cancelled" %}</span>
    -{% elif item.el.cancelled_for_teachers %}
    -  <span class="badge new green">{% trans "Cancelled for teachers" %}</span>
     {% endif %}
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/colour.html b/aleksis/apps/chronos/templates/chronos/partials/subs/colour.html
    index 833a24b..e59b37f 100644
    --- a/aleksis/apps/chronos/templates/chronos/partials/subs/colour.html
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/colour.html
    @@ -1,11 +1,5 @@
    -{% if item.type == "substitution" %}
    -  {% if item.el.cancelled or item.el.cancelled_for_teachers %}
    -    green-text
    -  {% else %}
    -    black-text
    -  {% endif %}
    -{% elif item.type == "supervision_substitution" %}
    -  blue-text
    -{% elif item.type == "event" %}
    -  purple-text
    +{% if item.el.cancelled %}
    +  green-text
    +{% else %}
    +  black-text
     {% endif %}
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/groups.html b/aleksis/apps/chronos/templates/chronos/partials/subs/groups.html
    index d1a4da9..079e0f0 100644
    --- a/aleksis/apps/chronos/templates/chronos/partials/subs/groups.html
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/groups.html
    @@ -1,5 +1,15 @@
    -{% if type == "substitution" %}
    -  {% include "chronos/partials/groups.html" with groups=el.lesson_period.lesson.groups.all %}
    -{% elif type == "extra_lesson" or type == "event" %}
    +{% if el.cancelled and el.amends.groups.all %}
    +  {% include "chronos/partials/groups.html" with groups=el.amends.groups.all %}
    +{% elif el.groups.all and el.amends.groups.all %}
    +  <s>
    +    {% include "chronos/partials/groups.html" with groups=el.amends.groups.all %}
    +  </s>
    +  →
    +  <strong>
    +    {% include "chronos/partials/groups.html" with groups=el.groups.all %}
    +  </strong>
    +{% elif el.groups.all and not el.amends.groups.all %}
       {% include "chronos/partials/groups.html" with groups=el.groups.all %}
    +{% elif el.amends.groups.all %}
    +  {% include "chronos/partials/groups.html" with groups=el.amends.groups.all %}
     {% endif %}
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/period.html b/aleksis/apps/chronos/templates/chronos/partials/subs/period.html
    index ef1d283..4ba7706 100644
    --- a/aleksis/apps/chronos/templates/chronos/partials/subs/period.html
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/period.html
    @@ -1,19 +1,7 @@
     <strong>
    -  {% if type == "substitution" and item.start_period == item.end_period %}
    -    {{ el.lesson_period.period.period }}.
    -  {% elif type == "substitution"  %}
    -    {{ item.start_period }}.–{{ item.end_period }}.
    -  {% elif type == "extra_lesson" %}
    -    {{ el.period.period }}.
    -  {% elif type == "event" %}
    -    {% if el.period_from_on_day == el.period_to_on_day %}
    -      {{ el.period_from_on_day }}.
    -    {% else %}
    -      {{ el.period_from_on_day }}.–{{ el.period_to_on_day }}.
    -    {% endif %}
    -  {% elif type == "supervision_substitution" %}
    -    {% with break=el.supervision.break_item %}
    -      {{ break.after_period_number }}./{{ break.before_period_number }}.
    -    {% endwith %}
    +  {% if el.datetime_start %}
    +    {{ el.datetime_start.time }} - {{ el.datetime_end.time }}
    +  {% elif el.date_start %}
    +    {{ el.date_start }} - {{ el.date_end }}
       {% endif %}
     </strong>
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/room.html b/aleksis/apps/chronos/templates/chronos/partials/subs/room.html
    index 94f2d35..123faba 100644
    --- a/aleksis/apps/chronos/templates/chronos/partials/subs/room.html
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/room.html
    @@ -1,39 +1,15 @@
    -{% if type == "substitution" %}
    -  {% if el.cancelled or el.cancelled_for_teachers %}
    -    {# Cancelled lesson: no room #}
    -  {% elif el.room and el.lesson_period.room %}
    -    {# New and old room available #}
    -    <span class="tooltipped" data-position="bottom"
    -          data-tooltip="{{ el.lesson_period.room.name }} → {{ el.room.name }}"
    -          title="{{ el.lesson_period.room.name }} → {{ el.room.name }}">
    -      <a href="{% url "timetable" "room" el.lesson_period.room.pk %}">
    -          <s>{{ el.lesson_period.room.short_name }}</s>
    -      </a>
    -      →
    -      <a href="{% url "timetable" "room" el.room.pk %}">
    -          <strong>{{ el.room.short_name }}</strong>
    -      </a>
    -    </span>
    -  {% elif el.room and not el.lesson_period.room %}
    -    {# Only new room available #}
    -    {% include "chronos/partials/room.html" with room=el.room %}
    -  {% elif not el.room and not el.lesson_period.room %}
    -    {# Nothing to view #}
    -  {% else %}
    -    {# Only old room available #}
    -    {% include "chronos/partials/room.html" with room=el.lesson_period.room %}
    -  {% endif %}
    -{% elif type == "supervision_substitution" %}
    -  {% with supervision=el.supervision %}
    -    <span data-position="bottom" class="tooltipped"
    -          data-tooltip="{{ supervision.area.name }}" title="{{ supervision.area.name }}">
    -      {{ supervision.area.short_name }}
    -    </span>
    -  {% endwith %}
    -{% elif type == "extra_lesson" %}
    -  {% include "chronos/partials/room.html" with room=el.room %}
    -{% elif type == "event" %}
    -  {% for room in el.rooms.all %}
    -    {% include "chronos/partials/room.html" with room=room %}{% if not forloop.last %},{% endif %}
    -  {% endfor %}
    +{% if el.cancelled and el.amends.rooms.all %}
    +  {% include "chronos/partials/rooms.html" with rooms=el.amends.rooms.all %}
    +{% elif el.rooms.all and el.amends.rooms.all %}
    +  <s>
    +    {% include "chronos/partials/rooms.html" with rooms=el.amends.rooms.all %}
    +  </s>
    +  →
    +  <strong>
    +    {% include "chronos/partials/rooms.html" with rooms=el.rooms.all %}
    +  </strong>
    +{% elif el.rooms.all and not el.amends.rooms.all %}
    +  {% include "chronos/partials/rooms.html" with rooms=el.rooms.all %}
    +{% elif el.amends.rooms.all %}
    +  {% include "chronos/partials/rooms.html" with rooms=el.amends.rooms.all %}
     {% endif %}
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/rooms.html b/aleksis/apps/chronos/templates/chronos/partials/subs/rooms.html
    new file mode 100644
    index 0000000..123faba
    --- /dev/null
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/rooms.html
    @@ -0,0 +1,15 @@
    +{% if el.cancelled and el.amends.rooms.all %}
    +  {% include "chronos/partials/rooms.html" with rooms=el.amends.rooms.all %}
    +{% elif el.rooms.all and el.amends.rooms.all %}
    +  <s>
    +    {% include "chronos/partials/rooms.html" with rooms=el.amends.rooms.all %}
    +  </s>
    +  →
    +  <strong>
    +    {% include "chronos/partials/rooms.html" with rooms=el.rooms.all %}
    +  </strong>
    +{% elif el.rooms.all and not el.amends.rooms.all %}
    +  {% include "chronos/partials/rooms.html" with rooms=el.rooms.all %}
    +{% elif el.amends.rooms.all %}
    +  {% include "chronos/partials/rooms.html" with rooms=el.amends.rooms.all %}
    +{% endif %}
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/subject.html b/aleksis/apps/chronos/templates/chronos/partials/subs/subject.html
    index 1b7a3c5..dcbfa4b 100644
    --- a/aleksis/apps/chronos/templates/chronos/partials/subs/subject.html
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/subject.html
    @@ -1,28 +1,28 @@
     {% load i18n %}
    
    -{% if type == "substitution" %}
    -  {% if not el.lesson_period.lesson.subject and not el.subject %}
    -  {% elif el.cancelled or el.cancelled_for_teachers %}
    -    <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.lesson_period.lesson.subject.name }}">
    -    <s>{{ el.lesson_period.lesson.subject.short_name }}</s>
    -  </span>
    -  {% elif el.subject and el.lesson_period.lesson.subject %}
    -    <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.lesson_period.lesson.subject.name }}">
    -    <s>{{ el.lesson_period.lesson.subject.short_name }}</s>
    -  </span>
    -    →
    -    <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.subject.name }}">
    -    <strong>{{ el.subject.short_name }}</strong>
    -  </span>
    -  {% elif el.subject and not el.lesson_period.lesson.subject %}
    -    {% include "chronos/partials/subject.html" with subject=el.subject %}
    -  {% else %}
    -    {% include "chronos/partials/subject.html" with subject=el.lesson_period.lesson.subject %}
    +{% if not el.amends.subject and not el.subject %}
    +  {% if el.amends.title %}
    +    <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.amends.title }}">
    +    <s>{{ el.amends.title }}</s>
       {% endif %}
    -{% elif type == "supervision_substitution" %}
    -  {% trans "Supervision" %}
    -{% elif type == "extra_lesson" %}
    +  {% if el.title %}
    +    <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.title }}">
    +    <s>{{ el.title }}</s>
    +  {% endif %}
    +{% elif el.cancelled %}
    +  <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.subject.short_name }}">
    +  <s>{{ el.subject.short_name }}</s>
    +</span>
    +{% elif el.subject and el.amends.subject %}
    +  <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.amends.subject.name }}">
    +  <s>{{ el.amends.subject.short_name }}</s>
    +</span>
    +  →
    +  <span data-position="bottom" class="tooltipped" data-tooltip="{{ el.subject.name }}">
    +  <strong>{{ el.subject.short_name }}</strong>
    +</span>
    +{% elif el.subject and not el.amends.subject %}
       {% include "chronos/partials/subject.html" with subject=el.subject %}
    -{% elif type == "event" %}
    -  {% trans "Event" %}
    +{% else %}
    +  {% include "chronos/partials/subject.html" with subject=el.amends.subject %}
     {% endif %}
    diff --git a/aleksis/apps/chronos/templates/chronos/partials/subs/teachers.html b/aleksis/apps/chronos/templates/chronos/partials/subs/teachers.html
    index 4fa80d8..9e08eeb 100644
    --- a/aleksis/apps/chronos/templates/chronos/partials/subs/teachers.html
    +++ b/aleksis/apps/chronos/templates/chronos/partials/subs/teachers.html
    @@ -1,27 +1,15 @@
    -{% if type == "substitution" %}
    -  {% if el.cancelled and el.lesson_period.lesson.teachers.all %}
    -    {% include "chronos/partials/teachers.html" with teachers=el.lesson_period.lesson.teachers.all %}
    -  {% elif el.teachers.all and el.lesson_period.lesson.teachers.all %}
    -    <s>
    -      {% include "chronos/partials/teachers.html" with teachers=el.lesson_period.lesson.teachers.all %}
    -    </s>
    -    →
    -    <strong>
    -      {% include "chronos/partials/teachers.html" with teachers=el.teachers.all %}
    -    </strong>
    -  {% elif el.teachers.all and not el.lesson_period.lesson.teachers.all %}
    -    {% include "chronos/partials/teachers.html" with teachers=el.teachers.all %}
    -  {% elif el.lesson_period.lesson.teachers.all %}
    -    {% include "chronos/partials/teachers.html" with teachers=el.lesson_period.lesson.teachers.all %}
    -  {% endif %}
    -{% elif type == "supervision_substitution" %}
    +{% if el.cancelled and el.amends.teachers.all %}
    +  {% include "chronos/partials/teachers.html" with teachers=el.amends.teachers.all %}
    +{% elif el.teachers.all and el.amends.teachers.all %}
       <s>
    -    {% include "chronos/partials/teachers.html" with teachers=el.supervision.teachers %}
    +    {% include "chronos/partials/teachers.html" with teachers=el.amends.teachers.all %}
       </s>
       →
       <strong>
    -    {% include "chronos/partials/teachers.html" with teachers=el.teachers %}
    +    {% include "chronos/partials/teachers.html" with teachers=el.teachers.all %}
       </strong>
    -{% elif type == "extra_lesson" or type == "event" %}
    +{% elif el.teachers.all and not el.amends.teachers.all %}
       {% include "chronos/partials/teachers.html" with teachers=el.teachers.all %}
    +{% elif el.amends.teachers.all %}
    +  {% include "chronos/partials/teachers.html" with teachers=el.amends.teachers.all %}
     {% endif %}
    diff --git a/aleksis/apps/chronos/templates/chronos/substitutions_print.html b/aleksis/apps/chronos/templates/chronos/substitutions_print.html
    index 743a223..10243a1 100644
    --- a/aleksis/apps/chronos/templates/chronos/substitutions_print.html
    +++ b/aleksis/apps/chronos/templates/chronos/substitutions_print.html
    @@ -18,13 +18,13 @@
    
         {% include "core/partials/announcements.html" with announcements=c.announcements show_recipients=1 %}
    
    -    {% include "chronos/partials/headerbox.html" with affected_teachers=c.affected_teachers affected_groups=c.affected_groups absent_teachers=c.absent_teachers absent_groups=c.absent_groups print=1 %}
    +    {% include "chronos/partials/headerbox.html" with absent_teachers=c.absent_teachers absent_groups=c.absent_groups print=1 %}
    
         <table class="substitutions">
           <thead>
           <tr>
    -        <th><i class="material-icons iconify center" data-icon="mdi:account-multiple-outline"></i></th>
    -        <th><i class="material-icons iconify center" data-icon="mdi:clock-outline"></i></th>
    +        <th>{% blocktrans %}Groups{% endblocktrans %}</th>
    +        <th>{% blocktrans %}Time{% endblocktrans %}</th>
             <th>{% blocktrans %}Teachers{% endblocktrans %}</th>
             <th>{% blocktrans %}Subject{% endblocktrans %}</th>
             <th>{% blocktrans %}Room{% endblocktrans %}</th>
    @@ -47,7 +47,7 @@
    
           <tbody>
           {% for item in c.substitutions %}
    -        {% ifchanged item.el.lesson_period.lesson.groups_to_show_names %}
    +        {% ifchanged item.el.group_names %}
               </tbody>
               <tbody class="{% cycle "striped" "not-striped" %}">
             {% endifchanged %}
    @@ -66,7 +66,7 @@
                 {% include "chronos/partials/subs/subject.html" with type=item.type el=item.el %}
               </td>
               <td>
    -            {% include "chronos/partials/subs/room.html" with type=item.type el=item.el %}
    +            {% include "chronos/partials/subs/rooms.html" with type=item.type el=item.el %}
               </td>
               <td>
                 {% include "chronos/partials/subs/badge.html" with sub=item.el %}
    diff --git a/aleksis/apps/chronos/util/build.py b/aleksis/apps/chronos/util/build.py
    index 625998d..7946a3e 100644
    --- a/aleksis/apps/chronos/util/build.py
    +++ b/aleksis/apps/chronos/util/build.py
    @@ -3,6 +3,7 @@ from datetime import date
     from typing import Union
    
     from django.apps import apps
    +from django.db.models import Q
    
     from calendarweek import CalendarWeek
    
    @@ -10,6 +11,7 @@ from aleksis.apps.chronos.managers import TimetableType
     from aleksis.core.models import Group, Person, Room
    
     LessonPeriod = apps.get_model("chronos", "LessonPeriod")
    +LessonEvent = apps.get_model("chronos", "LessonEvent")
     TimePeriod = apps.get_model("chronos", "TimePeriod")
     Break = apps.get_model("chronos", "Break")
     Supervision = apps.get_model("chronos", "Supervision")
    @@ -383,84 +385,25 @@ def build_timetable(
     def build_substitutions_list(wanted_day: date) -> list[dict]:
         rows = []
    
    -    subs = LessonSubstitution.objects.on_day(wanted_day).order_by(
    -        "lesson_period__lesson__groups", "lesson_period__period"
    +    subs = (
    +        LessonEvent.objects.exclude(amends=None)
    +        .filter(Q(datetime_start__date=wanted_day) | Q(date_start=wanted_day))
    +        .order_by("datetime_start", "date_start")
         )
    
    -    start_period = None
         for i, sub in enumerate(subs):
    -        if not sub.cancelled_for_teachers:
    -            sort_a = sub.lesson_period.lesson.groups_to_show_names
    -        else:
    -            sort_a = f"Z.{sub.lesson_period.lesson.teacher_names}"
    -
    -        # Get next substitution
    -        next_sub = subs[i + 1] if i + 1 < len(subs) else None
    -
    -        # Check if next substitution is equal with this substitution
    -        if (
    -            next_sub
    -            and sub.comment == next_sub.comment
    -            and sub.cancelled == next_sub.cancelled
    -            and sub.subject == next_sub.subject
    -            and sub.room == next_sub.room
    -            and sub.lesson_period.lesson == next_sub.lesson_period.lesson
    -            and set(sub.teachers.all()) == set(next_sub.teachers.all())
    -        ):
    -            if not start_period:
    -                start_period = sub.lesson_period.period.period
    -            continue
    +        sort_a = sub.group_names
    +
    +        # FIXME? Looks hacky. sub.amends returns a CalendarEvent, but a LessonEvent is needed
    +        sub.amends = LessonEvent.objects.get(pk=sub.amends.pk)
    
             row = {
                 "type": "substitution",
                 "sort_a": sort_a,
    -            "sort_b": str(sub.lesson_period.period.period),
    +            "sort_b": str(sub.datetime_start if sub.datetime_start else sub.date_start),
                 "el": sub,
    -            "start_period": start_period if start_period else sub.lesson_period.period.period,
    -            "end_period": sub.lesson_period.period.period,
    -        }
    -
    -        if start_period:
    -            start_period = None
    -
    -        rows.append(row)
    -
    -    # Get supervision substitutions
    -    super_subs = SupervisionSubstitution.objects.filter(date=wanted_day)
    -
    -    for super_sub in super_subs:
    -        row = {
    -            "type": "supervision_substitution",
    -            "sort_a": f"Z.{super_sub.teacher}",
    -            "sort_b": str(super_sub.supervision.break_item.after_period_number),
    -            "el": super_sub,
    -        }
    -        rows.append(row)
    -
    -    # Get extra lessons
    -    extra_lessons = ExtraLesson.objects.on_day(wanted_day)
    -
    -    for extra_lesson in extra_lessons:
    -        row = {
    -            "type": "extra_lesson",
    -            "sort_a": str(extra_lesson.group_names),
    -            "sort_b": str(extra_lesson.period.period),
    -            "el": extra_lesson,
             }
    -        rows.append(row)
    -
    -    # Get events
    -    events = Event.objects.on_day(wanted_day).annotate_day(wanted_day)
    
    -    for event in events:
    -        sort_a = event.group_names if event.groups.all() else f"Z.{event.teacher_names}"
    -
    -        row = {
    -            "type": "event",
    -            "sort_a": sort_a,
    -            "sort_b": str(event.period_from_on_day),
    -            "el": event,
    -        }
             rows.append(row)
    
         # Sort all items
    diff --git a/aleksis/apps/chronos/util/chronos_helpers.py b/aleksis/apps/chronos/util/chronos_helpers.py
    index 8e16401..4c36d3a 100644
    --- a/aleksis/apps/chronos/util/chronos_helpers.py
    +++ b/aleksis/apps/chronos/util/chronos_helpers.py
    @@ -1,4 +1,4 @@
    -from datetime import datetime, timedelta
    +from datetime import date, datetime, timedelta
     from typing import TYPE_CHECKING, Optional
    
     from django.db.models import Count, Q
    @@ -160,10 +160,8 @@ def get_rooms(user: "User"):
    
     def get_substitutions_context_data(
    +    wanted_day: date,
         request: Optional[HttpRequest] = None,
    -    year: Optional[int] = None,
    -    month: Optional[int] = None,
    -    day: Optional[int] = None,
         is_print: bool = False,
         number_of_days: Optional[int] = None,
         show_header_box: Optional[bool] = None,
    @@ -171,12 +169,6 @@ def get_substitutions_context_data(
         """Get context data for the substitutions table."""
         context = {}
    
    -    if day:
    -        wanted_day = timezone.datetime(year=year, month=month, day=day).date()
    -        wanted_day = TimePeriod.get_next_relevant_day(wanted_day)
    -    else:
    -        wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), timezone.now().time())
    -
         day_number = (
             number_of_days or get_site_preferences()["chronos__substitutions_print_number_of_days"]
         )
    @@ -191,7 +183,7 @@ def get_substitutions_context_data(
             next_day = wanted_day
             for _i in range(day_number):
                 day_contexts[next_day] = {"day": next_day}
    -            next_day = TimePeriod.get_next_relevant_day(next_day + timedelta(days=1))
    +            next_day = next_day + timedelta(days=1)
         else:
             day_contexts = {wanted_day: {"day": wanted_day}}
    
    @@ -202,22 +194,9 @@ def get_substitutions_context_data(
             day_contexts[day]["announcements"] = Announcement.for_timetables().on_date(day)
    
             if show_header_box:
    -            subs = LessonSubstitution.objects.on_day(day).order_by(
    -                "lesson_period__lesson__groups", "lesson_period__period"
    -            )
                 absences = Absence.objects.on_day(day)
                 day_contexts[day]["absent_teachers"] = absences.absent_teachers()
                 day_contexts[day]["absent_groups"] = absences.absent_groups()
    -            day_contexts[day]["affected_teachers"] = subs.affected_teachers()
    -            affected_groups = subs.affected_groups()
    -            if get_site_preferences()["chronos__affected_groups_parent_groups"]:
    -                groups_with_parent_groups = affected_groups.filter(parent_groups__isnull=False)
    -                groups_without_parent_groups = affected_groups.filter(parent_groups__isnull=True)
    -                affected_groups = Group.objects.filter(
    -                    Q(child_groups__pk__in=groups_with_parent_groups.values_list("pk", flat=True))
    -                    | Q(pk__in=groups_without_parent_groups.values_list("pk", flat=True))
    -                ).distinct()
    -            day_contexts[day]["affected_groups"] = affected_groups
    
         if not is_print:
             context = day_contexts[wanted_day]
    @@ -226,10 +205,6 @@ def get_substitutions_context_data(
                 "dest": reverse("substitutions"),
             }
    
    -        context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day(
    -            wanted_day, "substitutions_by_date"
    -        )
    -
         else:
             context["days"] = day_contexts
    
    diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py
    index a45997c..ee01e35 100644
    --- a/aleksis/apps/chronos/views.py
    +++ b/aleksis/apps/chronos/views.py
    @@ -1,3 +1,4 @@
    +from datetime import date, datetime
     from typing import Optional
    
     from django.http import HttpRequest, HttpResponse
Loading