-
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
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
chronos_helpers.py 6.20 KiB
from datetime import date, datetime, timedelta
from typing import TYPE_CHECKING, Optional
from django.db.models import Count, Q
from django.http import HttpRequest, HttpResponseNotFound
from django.shortcuts import get_object_or_404
from django.urls import reverse
from guardian.core import ObjectPermissionChecker
from aleksis.core.models import Announcement, Group, Person, Room
from aleksis.core.util.core_helpers import get_site_preferences
from aleksis.core.util.predicates import check_global_permission
from ..managers import TimetableType
from ..models import (
Absence,
LessonPeriod,
LessonSubstitution,
Supervision,
SupervisionSubstitution,
)
from .build import build_substitutions_list
from .js import date_unix
if TYPE_CHECKING:
from django.contrib.auth import get_user_model
User = get_user_model() # noqa
def get_el_by_pk(
request: HttpRequest,
type_: str,
pk: int,
prefetch: bool = False,
*args,
**kwargs,
):
if type_ == TimetableType.GROUP.value:
return get_object_or_404(
Group.objects.prefetch_related("owners", "parent_groups") if prefetch else Group,
pk=pk,
)
elif type_ == TimetableType.TEACHER.value:
return get_object_or_404(Person, pk=pk)
elif type_ == TimetableType.ROOM.value:
return get_object_or_404(Room, pk=pk)
else:
return HttpResponseNotFound()
def get_substitution_by_id(request: HttpRequest, id_: int, week: int):
lesson_period = get_object_or_404(LessonPeriod, pk=id_)
wanted_week = lesson_period.lesson.get_calendar_week(week)
return LessonSubstitution.objects.filter(
week=wanted_week.week, year=wanted_week.year, lesson_period=lesson_period
).first()
def get_supervision_substitution_by_id(request: HttpRequest, id_: int, date: datetime.date):
supervision = get_object_or_404(Supervision, pk=id_)
return SupervisionSubstitution.objects.filter(date=date, supervision=supervision).first()
def get_teachers(user: "User"):
"""Get the teachers whose timetables are allowed to be seen by current user."""
checker = ObjectPermissionChecker(user)
teachers = (
Person.objects.annotate(lessons_count=Count("lesson_events_as_teacher"))
.filter(lessons_count__gt=0)
.order_by("short_name", "last_name")
)
if not check_global_permission(user, "chronos.view_all_person_timetables"):
checker.prefetch_perms(teachers)
wanted_teachers = set()
for teacher in teachers:
if checker.has_perm("core.view_person_timetable", teacher):
wanted_teachers.add(teacher.pk)
teachers = teachers.filter(Q(pk=user.person.pk) | Q(pk__in=wanted_teachers))
teachers = teachers.distinct()
return teachers
def get_groups(user: "User"):
"""Get the groups whose timetables are allowed to be seen by current user."""
checker = ObjectPermissionChecker(user)
groups = (
Group.objects.for_current_school_term_or_all()
.annotate(
lessons_count=Count("lesson_events"),
child_lessons_count=Count("child_groups__lesson_events"),
)
.filter(Q(lessons_count__gt=0) | Q(child_lessons_count__gt=0))
)
group_types = get_site_preferences()["chronos__group_types_timetables"]
if group_types:
groups = groups.filter(group_type__in=group_types)
groups = groups.order_by("short_name", "name")
if not check_global_permission(user, "chronos.view_all_group_timetables"):
checker.prefetch_perms(groups)
wanted_classes = set()
for _class in groups:
if checker.has_perm("core.view_group_timetable", _class):
wanted_classes.add(_class.pk)
groups = groups.filter(
Q(pk__in=wanted_classes) | Q(members=user.person) | Q(owners=user.person)
)
if user.person.primary_group:
groups = groups.filter(Q(pk=user.person.primary_group.pk))
groups = groups.distinct()
return groups
def get_rooms(user: "User"):
"""Get the rooms whose timetables are allowed to be seen by current user."""
checker = ObjectPermissionChecker(user)
rooms = (
Room.objects.annotate(lessons_count=Count("lesson_events"))
.filter(lessons_count__gt=0)
.order_by("short_name", "name")
)
if not check_global_permission(user, "chronos.view_all_room_timetables"):
checker.prefetch_perms(rooms)
wanted_rooms = set()
for room in rooms:
if checker.has_perm("core.view_room_timetable", room):
wanted_rooms.add(room.pk)
rooms = rooms.filter(Q(pk__in=wanted_rooms))
rooms = rooms.distinct()
return rooms
def get_substitutions_context_data(
wanted_day: date,
request: Optional[HttpRequest] = None,
is_print: bool = False,
number_of_days: Optional[int] = None,
show_header_box: Optional[bool] = None,
):
"""Get context data for the substitutions table."""
context = {}
day_number = (
number_of_days or get_site_preferences()["chronos__substitutions_print_number_of_days"]
)
show_header_box = (
show_header_box
if show_header_box is not None
else get_site_preferences()["chronos__substitutions_show_header_box"]
)
day_contexts = {}
if is_print:
next_day = wanted_day
for _i in range(day_number):
day_contexts[next_day] = {"day": next_day}
next_day = next_day + timedelta(days=1)
else:
day_contexts = {wanted_day: {"day": wanted_day}}
for day in day_contexts:
subs = build_substitutions_list(day)
day_contexts[day]["substitutions"] = subs
day_contexts[day]["announcements"] = Announcement.for_timetables().on_date(day)
if show_header_box:
absences = Absence.objects.on_day(day)
day_contexts[day]["absent_teachers"] = absences.absent_teachers()
day_contexts[day]["absent_groups"] = absences.absent_groups()
if not is_print:
context = day_contexts[wanted_day]
context["datepicker"] = {
"date": date_unix(wanted_day),
"dest": reverse("substitutions"),
}
else:
context["days"] = day_contexts
return context