diff --git a/aleksis/apps/chronos/model_extensions.py b/aleksis/apps/chronos/model_extensions.py index 31bdbab5eb0400b70ebb94fab1f7f86801b21866..afad135f17191cfc6a329c439572619729d61de1 100644 --- a/aleksis/apps/chronos/model_extensions.py +++ b/aleksis/apps/chronos/model_extensions.py @@ -5,7 +5,7 @@ from jsonstore import BooleanField from aleksis.core.models import Person, Group, Announcement -from .models import Lesson, LessonPeriod +from .models import Lesson, LessonPeriod, TimetableType @Person.property @@ -16,13 +16,13 @@ def is_teacher(self): @Person.property -def timetable_type(self) -> Optional[str]: +def timetable_type(self) -> Optional[TimetableType]: """ Return which type of timetable this user has """ if self.is_teacher: - return "teacher" + return TimetableType.TEACHER elif self.primary_group: - return "group" + return TimetableType.GROUP else: return None @@ -33,9 +33,9 @@ def timetable_object(self) -> Optional[Union[Group, Person]]: type_ = self.timetable_type - if type_ == "teacher": + if type_ == TimetableType.TEACHER: return self - elif type_ == "group": + elif type_ == TimetableType.GROUP: return self.primary_group else: return None diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index d2dc9fa1b3097d50b38cfa24dcc77895e96480e9..dc84b5cf90d3c0a424d8415200a35f82a348c3d9 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -2,6 +2,7 @@ from __future__ import annotations from collections import OrderedDict from datetime import date, datetime, timedelta, time +from enum import Enum from typing import Dict, Optional, Tuple, Union from constance import config @@ -31,6 +32,16 @@ from aleksis.apps.chronos.util.date import week_weekday_from_date from aleksis.core.util.core_helpers import has_person +class TimetableType(Enum): + GROUP = "group" + TEACHER = "teacher" + ROOM = "room" + + @classmethod + def from_string(cls, s: Optional[str]): + return cls.__members__.get(s.upper()) + + class LessonPeriodManager(models.Manager): """ Manager adding specific methods to lesson periods. """ @@ -208,12 +219,12 @@ class LessonPeriodQuerySet(LessonDataQuerySet): if query_data.get("room", None): return self.filter_room(int(query_data["room"])) - def filter_from_type(self, type_: str, pk: int) -> Optional[models.QuerySet]: - if type_ == "group": + def filter_from_type(self, type_: TimetableType, pk: int) -> Optional[models.QuerySet]: + if type_ == TimetableType.GROUP: return self.filter_group(pk) - elif type_ == "teacher": + elif type_ == TimetableType.TEACHER: return self.filter_teacher(pk) - elif type_ == "room": + elif type_ == TimetableType.ROOM: return self.filter_room(pk) else: return None @@ -221,12 +232,12 @@ class LessonPeriodQuerySet(LessonDataQuerySet): def filter_from_person(self, person: Person) -> Optional[models.QuerySet]: type_ = person.timetable_type - if type_ == "teacher": + if type_ == TimetableType.TEACHER: # Teacher return self.filter_teacher(person) - elif type_ == "group": + elif type_ == TimetableType.GROUP: # Student return self.filter(lesson__groups__members=person) @@ -509,15 +520,6 @@ class LessonSubstitution(ExtensibleModel): if self.subject and self.cancelled: raise ValidationError(_("Lessons can only be either substituted or cancelled.")) - @property - def type_(self): - if self.cancelled: - return "cancellation" - elif self.cancelled_for_teachers: - return "cancellation_for_teachers" - else: - return "substitution" - @property def date(self): week = CalendarWeek(week=self.week) @@ -989,12 +991,12 @@ class TimetableQuerySet(models.QuerySet): else: return self.filter(room=room) - def filter_from_type(self, type_: str, pk: int) -> Optional[models.QuerySet]: - if type_ == "group": + def filter_from_type(self, type_: TimetableType, pk: int) -> Optional[models.QuerySet]: + if type_ == TimetableType.GROUP: return self.filter_group(pk) - elif type_ == "teacher": + elif type_ == TimetableType.TEACHER: return self.filter_teacher(pk) - elif type_ == "room": + elif type_ == TimetableType.ROOM: return self.filter_room(pk) else: return None @@ -1002,12 +1004,12 @@ class TimetableQuerySet(models.QuerySet): def filter_from_person(self, person: Person) -> Optional[models.QuerySet]: type_ = person.timetable_type - if type_ == "teacher": + if type_ == TimetableType.TEACHER: # Teacher return self.filter_teacher(person) - elif type_ == "group": + elif type_ == TimetableType.GROUP: # Student return self.filter_participant(person) diff --git a/aleksis/apps/chronos/templates/chronos/my_timetable.html b/aleksis/apps/chronos/templates/chronos/my_timetable.html index cc9b03c973e664b89001ed8932f278da16493f58..ed55cc19014b061b0a2f956ae8dabfd55d5083e4 100644 --- a/aleksis/apps/chronos/templates/chronos/my_timetable.html +++ b/aleksis/apps/chronos/templates/chronos/my_timetable.html @@ -18,7 +18,7 @@ {% trans "My timetable" %} <i>{{ el }}</i> <span class="badge new primary-color ">{% trans "SMART PLAN" %}</span> </h4> - <a class="btn-flat waves-effect waves-light" href="{% url "timetable" super.type super.el.pk %}"> + <a class="btn-flat waves-effect waves-light" href="{% url "timetable" super.type.value super.el.pk %}"> {% trans "Show week timetable for" %} {{ super.el.short_name }} </a> </div> diff --git a/aleksis/apps/chronos/templates/chronos/partials/event.html b/aleksis/apps/chronos/templates/chronos/partials/event.html index 3ca850407977fd5a75a5e1b824086002c26943fc..3aa6b797639598c0e24051053f040fcd3f1aead4 100644 --- a/aleksis/apps/chronos/templates/chronos/partials/event.html +++ b/aleksis/apps/chronos/templates/chronos/partials/event.html @@ -1,27 +1,27 @@ <div class="lesson-with-event"> <p> {# Teacher or room > Display groups #} - {% if type == "teacher" or type == "room" %} + {% if type.value == "teacher" or type.value == "room" %} {% include "chronos/partials/groups.html" with groups=event.groups.all %} {% endif %} {# Class or room > Display teachers #} - {% if type == "room" or type == "group" %} + {% if type.value == "room" or type.value == "group" %} {% include "chronos/partials/teachers.html" with teachers=event.teachers.all %} {% endif %} {# Teacher or class > Display rooms #} - {% if type == "teacher" or type == "group" %} + {% if type.value == "teacher" or type.value == "group" %} {% for room in event.rooms.all %} {% include "chronos/partials/room.html" with room=room %}{% if not forloop.last %},{% endif %} {% endfor %} {% endif %} - {% if type == "teacher" and not event.groups.all and not event.rooms.all and event.title %} + {% if type.value == "teacher" and not event.groups.all and not event.rooms.all and event.title %} <em>{{ event.title }}</em> - {% elif type == "group" and not event.teachers.all and not event.groups.all and event.title %} + {% elif type.value == "group" and not event.teachers.all and not event.groups.all and event.title %} <em>{{ event.title }}</em> - {% elif type == "room" and not event.teachers.all and not event.groups.all and event.title %} + {% elif type.value == "room" and not event.teachers.all and not event.groups.all and event.title %} <em>{{ event.title }}</em> {% elif event.title %} <br/> diff --git a/aleksis/apps/chronos/templates/chronos/partials/extra_lesson.html b/aleksis/apps/chronos/templates/chronos/partials/extra_lesson.html index 167fdab44694c078a63aa3657215f00ba511ffb1..1113f011f0164be5a92f1dbe7ef3b32e8db07ed5 100644 --- a/aleksis/apps/chronos/templates/chronos/partials/extra_lesson.html +++ b/aleksis/apps/chronos/templates/chronos/partials/extra_lesson.html @@ -2,19 +2,19 @@ style="{% include "chronos/partials/subject_colour.html" with subject=extra_lesson.subject %}"> <p> {# Teacher or room > Display groups #} - {% if type == "teacher" or type == "room" %} + {% if type.value == "teacher" or type.value == "room" %} {% include "chronos/partials/groups.html" with groups=extra_lesson.groups.all %} {% endif %} {# Class or room > Display teachers #} - {% if type == "room" or type == "group" %} + {% if type.value == "room" or type.value == "group" %} {% include "chronos/partials/teachers.html" with teachers=extra_lesson.teachers.all %} {% endif %} {% include "chronos/partials/subject.html" with subject=extra_lesson.subject %} {# Teacher or class > Display rooms #} - {% if type == "teacher" or type == "group" %} + {% if type.value == "teacher" or type.value == "group" %} {% include "chronos/partials/room.html" with room=extra_lesson.room %} {% endif %} diff --git a/aleksis/apps/chronos/templates/chronos/partials/lesson.html b/aleksis/apps/chronos/templates/chronos/partials/lesson.html index dd0ac1c30cfa47909ef0636a0f7339a1b97361a7..5230c94536125ed3d20f0757b63df90c297cfd53 100644 --- a/aleksis/apps/chronos/templates/chronos/partials/lesson.html +++ b/aleksis/apps/chronos/templates/chronos/partials/lesson.html @@ -3,7 +3,7 @@ <div style=" {# Display background color only if lesson is not cancelled and it is not the old room #} {% if not lesson_period.get_substitution.cancelled and not lesson_period.get_substitution.cancelled_for_teachers %} - {% if not type == "room" or lesson_period.room == lesson_period.get_room or lesson_period.get_room == el %} + {% if not type.value == "room" or lesson_period.room == lesson_period.get_room or lesson_period.get_room == el %} {% include "chronos/partials/subject_colour.html" with subject=lesson_period.lesson.subject %} {% endif %} {% endif %} @@ -17,14 +17,14 @@ {% elif lesson_period.get_substitution and smart %} {% with sub=lesson_period.get_substitution %} {# SUBSTITUTION #} - {% if type == "room" and lesson_period.room != lesson_period.get_room and lesson_period.get_room != el %} + {% if type.value == "room" and lesson_period.room != lesson_period.get_room and lesson_period.get_room != el %} {# When it's the old room, let it empty #} {% elif sub.cancelled or sub.cancelled_for_teachers %} {# When a badge (cancellation, etc.) exists, then display it with the teacher#} {# Class or room > Display teacher #} - {% if type == "group" or type == "room" and lesson_period.lesson.teachers.all %} + {% if type.value == "group" or type.value == "room" and lesson_period.lesson.teachers.all %} {% include "chronos/partials/teachers.html" with teachers=lesson_period.lesson.teachers.all %}<br/> {% endif %} @@ -35,7 +35,7 @@ {# Display sub #} {# Teacher or room > display classes #} - {% if type == "teacher" or type == "room" %} + {% if type.value == "teacher" or type.value == "room" %} {% include "chronos/partials/groups.html" with groups=lesson_period.lesson.groups.all %} {% endif %} @@ -46,7 +46,7 @@ {% include "chronos/partials/subs/subject.html" with type="substitution" el=sub %} {# Teacher or class > display room #} - {% if type == "teacher" or type == "group" %} + {% if type.value == "teacher" or type.value == "group" %} {% include "chronos/partials/subs/room.html" with type="substitution" el=sub %} {% endif %} {% endif %} @@ -66,7 +66,7 @@ {# Normal plan #} {# Teacher or room > Display classes #} - {% if type == "teacher" or type == "room" %} + {% if type.value == "teacher" or type.value == "room" %} {# {{ element_container.element.classes }}#} {% if lesson_period.lesson.groups %} {% include "chronos/partials/groups.html" with groups=lesson_period.lesson.groups.all %} @@ -74,7 +74,7 @@ {% endif %} {# Class or room > Display teacher #} - {% if type == "room" or type == "group" %} + {% if type.value == "room" or type.value == "group" %} {% include "chronos/partials/teachers.html" with teachers=lesson_period.lesson.teachers.all %} {% endif %} @@ -82,7 +82,7 @@ {% include "chronos/partials/subject.html" with subject=lesson_period.lesson.subject %} {# Teacher or class > Display room #} - {% if type == "teacher" or type == "group" %} + {% if type.value == "teacher" or type.value == "group" %} {% if lesson_period.room %} {% include "chronos/partials/room.html" with room=lesson_period.room %} {% endif %} diff --git a/aleksis/apps/chronos/templates/chronos/timetable.html b/aleksis/apps/chronos/templates/chronos/timetable.html index 88b02be677b238d9b05d71e52104f19a12de47bb..341d35c32e00feddf9cbcbb9b2aaabf881aab410 100644 --- a/aleksis/apps/chronos/templates/chronos/timetable.html +++ b/aleksis/apps/chronos/templates/chronos/timetable.html @@ -24,7 +24,7 @@ </h4> {# Show class teacher and deputy class teacher #} - {% if type == "group" and el.owners.all %} + {% if type.value == "group" and el.owners.all %} <h5>{% trans "Group teachers:" %} {% for teacher in el.owners.all %} <span data-position="bottom" class="tooltipped" @@ -50,7 +50,7 @@ <span class="badge new primary-color left smart-plan-badge">{% trans "SMART PLAN" %}</span> <a class="waves-effect waves-light btn-flat no-print" - href="{% url "timetable_regular" type pk "regular" %}"> + href="{% url "timetable_regular" type.value pk "regular" %}"> <i class="material-icons left">slideshow</i> {% trans "Show regular timetable" %} </a> @@ -62,7 +62,7 @@ {% else %} {# Show if regular #} <a class="waves-effect waves-light btn-flat no-print" - href="{% url "timetable" type pk %}"> + href="{% url "timetable" type.value pk %}"> <i class="material-icons left">slideshow</i> {% trans "Show SMART PLAN" %} </a> diff --git a/aleksis/apps/chronos/util/build.py b/aleksis/apps/chronos/util/build.py index 6b3668cb1689d2081c1b0a362c2136f1ed829976..47f6dc319d5b18ad84354f00607cdf8b943ad38e 100644 --- a/aleksis/apps/chronos/util/build.py +++ b/aleksis/apps/chronos/util/build.py @@ -6,6 +6,7 @@ from calendarweek import CalendarWeek from django.apps import apps from django.db.models import QuerySet +from aleksis.apps.chronos.models import TimetableType from aleksis.core.models import Person LessonPeriod = apps.get_model("chronos", "LessonPeriod") @@ -39,7 +40,7 @@ def group_by_periods(objs: QuerySet, is_person: bool =False) -> dict: def build_timetable( - type_: str, obj: Union[int, Person], date_ref: Union[CalendarWeek, date] + type_: Union[TimetableType, str], obj: Union[int, Person], date_ref: Union[CalendarWeek, date] ): needed_breaks = [] @@ -138,7 +139,7 @@ def build_timetable( else: events_per_period[period][weekday].append(event) - if type_ == "teacher": + if type_ == TimetableType.TEACHER: # Get matching supervisions if is_person: week = CalendarWeek.from_date(date_ref) @@ -175,7 +176,7 @@ def build_timetable( rows = [] for period, break_ in breaks.items(): # period is period after break # Break - if type_ == "teacher" and period in needed_breaks: + if type_ == TimetableType.TEACHER and period in needed_breaks: row = { "type": "break", "after_period": break_.after_period_number, diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py index fe335b48e1e66743f2c725541017233691ef57fc..9ebe7de9b927262a372ec68c581c9eef45eb693b 100644 --- a/aleksis/apps/chronos/views.py +++ b/aleksis/apps/chronos/views.py @@ -16,7 +16,7 @@ from aleksis.core.decorators import admin_required from aleksis.core.models import Person, Group, Announcement from aleksis.core.util import messages from .forms import LessonSubstitutionForm -from .models import LessonPeriod, LessonSubstitution, TimePeriod, Room, Holiday, Absence +from .models import LessonPeriod, LessonSubstitution, TimePeriod, Room, Holiday, Absence, TimetableType from .tables import LessonsTable from .util.build import build_timetable, build_substitutions_list, build_weekdays from .util.js import date_unix @@ -108,15 +108,17 @@ def timetable( is_smart = regular != "regular" - if type_ == "group": + if type_ == TimetableType.GROUP.value: el = get_object_or_404(Group, pk=pk) - elif type_ == "teacher": + elif type_ == TimetableType.TEACHER.value: el = get_object_or_404(Person, pk=pk) - elif type_ == "room": + elif type_ == TimetableType.ROOM.value: el = get_object_or_404(Room, pk=pk) else: return HttpResponseNotFound() + type_ = TimetableType.from_string(type_) + if year and week: wanted_week = CalendarWeek(year=year, week=week) else: