From df2c5b5a0b12c818073e4376eeacaceef355c2e8 Mon Sep 17 00:00:00 2001 From: Tom Teichler <tom.teichler@teckids.org> Date: Sun, 3 May 2020 16:10:33 +0200 Subject: [PATCH] [Reformat] black --- aleksis/apps/chronos/admin.py | 4 +- aleksis/apps/chronos/filters.py | 2 +- aleksis/apps/chronos/forms.py | 4 +- aleksis/apps/chronos/managers.py | 68 +- aleksis/apps/chronos/menus.py | 20 +- .../migrations/0005_remove_school_related.py | 84 +-- .../chronos/migrations/0006_extended_data.py | 10 +- .../0007_advanced_models_from_untis.py | 591 +++++++++++++----- .../chronos/migrations/0008_break_period.py | 53 +- .../chronos/migrations/0009_extended_data.py | 42 +- .../migrations/0010_absence_reason_name.py | 32 +- .../0011_absence_for_groups_and_rooms.py | 43 +- .../0012_event_remove_absence_reason.py | 7 +- .../migrations/0013_event_title_optional.py | 10 +- .../chronos/migrations/0014_extra_lesson.py | 91 ++- .../0015_rename_abbrev_to_short_name.py | 9 +- .../migrations/0016_add_globalpermissions.py | 29 +- aleksis/apps/chronos/model_extensions.py | 6 +- aleksis/apps/chronos/models.py | 359 ++++++++--- aleksis/apps/chronos/preferences.py | 8 +- aleksis/apps/chronos/rules.py | 17 +- aleksis/apps/chronos/tables.py | 16 +- aleksis/apps/chronos/templatetags/common.py | 7 +- .../apps/chronos/templatetags/week_helpers.py | 6 +- aleksis/apps/chronos/urls.py | 44 +- aleksis/apps/chronos/util/build.py | 16 +- aleksis/apps/chronos/views.py | 43 +- 27 files changed, 1145 insertions(+), 476 deletions(-) diff --git a/aleksis/apps/chronos/admin.py b/aleksis/apps/chronos/admin.py index 56878a6c..8c99c4b5 100644 --- a/aleksis/apps/chronos/admin.py +++ b/aleksis/apps/chronos/admin.py @@ -1,4 +1,4 @@ -#noqa +# noqa from django.contrib import admin from django.utils.html import format_html @@ -153,7 +153,7 @@ admin.site.register(Room, RoomAdmin) class SubjectAdmin(admin.ModelAdmin): def _colour(self, obj): - return colour_badge(obj.colour_fg, obj.colour_bg, obj.short_name, ) + return colour_badge(obj.colour_fg, obj.colour_bg, obj.short_name,) list_display = ("short_name", "name", "_colour") list_display_links = ("short_name", "name") diff --git a/aleksis/apps/chronos/filters.py b/aleksis/apps/chronos/filters.py index 8df8771d..dead4fc6 100644 --- a/aleksis/apps/chronos/filters.py +++ b/aleksis/apps/chronos/filters.py @@ -12,5 +12,5 @@ class HintForm(Form): class HintFilter(django_filters.FilterSet): class Meta: model = Hint - fields = ['from_date', "to_date", "classes", "teachers"] + fields = ["from_date", "to_date", "classes", "teachers"] form = HintForm diff --git a/aleksis/apps/chronos/forms.py b/aleksis/apps/chronos/forms.py index 685f67f7..1c56e201 100644 --- a/aleksis/apps/chronos/forms.py +++ b/aleksis/apps/chronos/forms.py @@ -22,4 +22,6 @@ class LessonSubstitutionForm(forms.ModelForm): } -AnnouncementForm.add_node_to_layout(Fieldset(_("Options for timetables"), "show_in_timetables")) +AnnouncementForm.add_node_to_layout( + Fieldset(_("Options for timetables"), "show_in_timetables") +) diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py index 52ae31a3..2f32a3e4 100644 --- a/aleksis/apps/chronos/managers.py +++ b/aleksis/apps/chronos/managers.py @@ -93,8 +93,10 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): """ Filter for all lessons within a calendar week. """ return self.within_dates( - wanted_week[0] + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), - wanted_week[0] + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), + wanted_week[0] + + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), + wanted_week[0] + + timedelta(days=1) * (F(self._period_path + "period__weekday") - 1), ).annotate_week(wanted_week) def on_day(self, day: date): @@ -129,7 +131,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): return self.filter( Q(**{self._period_path + "lesson__groups__members": person}) - | Q(**{self._period_path + "lesson__groups__parent_groups__members": person}) + | Q( + **{self._period_path + "lesson__groups__parent_groups__members": person} + ) ) def filter_group(self, group: Union[Group, int]): @@ -151,7 +155,12 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): """ Filter for all lessons given by a certain teacher. """ qs1 = self.filter(**{self._period_path + "lesson__teachers": teacher}) - qs2 = self.filter(**{self._subst_path + "teachers": teacher, self._subst_path + "week": F("_week"), }) + qs2 = self.filter( + **{ + self._subst_path + "teachers": teacher, + self._subst_path + "week": F("_week"), + } + ) return qs1.union(qs2) @@ -159,7 +168,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): """ Filter for all lessons taking part in a certain room. """ qs1 = self.filter(**{self._period_path + "room": room}) - qs2 = self.filter(**{self._subst_path + "room": room, self._subst_path + "week": F("_week"),}) + qs2 = self.filter( + **{self._subst_path + "room": room, self._subst_path + "week": F("_week"),} + ) return qs1.union(qs2) @@ -184,7 +195,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): return per_period - def filter_from_type(self, type_: TimetableType, pk: int) -> Optional[models.QuerySet]: + def filter_from_type( + self, type_: TimetableType, pk: int + ) -> Optional[models.QuerySet]: """Filter lesson data for a group, teacher or room by provided type.""" if type_ == TimetableType.GROUP: @@ -215,7 +228,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): # If no student or teacher return None - def daily_lessons_for_person(self, person: Person, wanted_day: date) -> Optional[models.QuerySet]: + def daily_lessons_for_person( + self, person: Person, wanted_day: date + ) -> Optional[models.QuerySet]: """Filter lesson data on a day by a person.""" if person.timetable_type is None: @@ -225,7 +240,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): return lesson_periods - def next(self, reference: "LessonPeriod", offset: Optional[int] = 1) -> "LessonPeriod": + def next( + self, reference: "LessonPeriod", offset: Optional[int] = 1 + ) -> "LessonPeriod": """ Get another lesson in an ordered set of lessons. By default, it returns the next lesson in the set. By passing the offset argument, @@ -260,7 +277,7 @@ class LessonSubstitutionQuerySet(LessonDataQuerySet): def affected_lessons(self): """ Return all lessons which are affected by selected substitutions """ - from .models import Lesson # noaq + from .models import Lesson # noaq return Lesson.objects.filter(lesson_periods__substitutions__in=self) @@ -307,8 +324,7 @@ class DateRangeQuerySet(models.QuerySet): now = when or datetime.now() return self.on_day(now.date()).filter( - period_from__time_start__lte=now.time(), - period_to__time_end__gte=now.time() + period_from__time_start__lte=now.time(), period_to__time_end__gte=now.time() ) @@ -316,17 +332,24 @@ class AbsenceQuerySet(DateRangeQuerySet): """QuerySet with custom query methods for absences.""" def absent_teachers(self): - return Person.objects.filter(absences__in=self).annotate(absences_count=Count("absences")) + return Person.objects.filter(absences__in=self).annotate( + absences_count=Count("absences") + ) def absent_groups(self): - return Group.objects.filter(absences__in=self).annotate(absences_count=Count("absences")) + return Group.objects.filter(absences__in=self).annotate( + absences_count=Count("absences") + ) def absent_rooms(self): - return Person.objects.filter(absences__in=self).annotate(absences_count=Count("absences")) + return Person.objects.filter(absences__in=self).annotate( + absences_count=Count("absences") + ) class HolidayQuerySet(DateRangeQuerySet): """QuerySet with custom query methods for holidays.""" + pass @@ -352,7 +375,10 @@ class SupervisionQuerySet(models.QuerySet, WeekQuerySetMixin): dates = [week[w] for w in range(0, 7)] - return self.filter(Q(substitutions__teacher=teacher, substitutions__date__in=dates) | Q(teacher=teacher)) + return self.filter( + Q(substitutions__teacher=teacher, substitutions__date__in=dates) + | Q(teacher=teacher) + ) return self @@ -398,7 +424,9 @@ class TimetableQuerySet(models.QuerySet): else: return self.filter(room=room) - def filter_from_type(self, type_: TimetableType, pk: int) -> Optional[models.QuerySet]: + def filter_from_type( + self, type_: TimetableType, pk: int + ) -> Optional[models.QuerySet]: """Filter data for a group, teacher or room by provided type.""" if type_ == TimetableType.GROUP: @@ -457,7 +485,7 @@ class ExtraLessonQuerySet(TimetableQuerySet): period__weekday__lte=end.weekday(), ) - def on_day(self, day:date): + def on_day(self, day: date): """Filter all extra lessons on a day.""" return self.within_dates(day, day) @@ -476,7 +504,11 @@ class GroupPropertiesMixin: @property def groups_to_show(self) -> models.QuerySet: groups = self.groups.all() - if groups.count() == 1 and groups[0].parent_groups.all() and get_site_preferences()["chronos__use_parent_groups"]: + if ( + groups.count() == 1 + and groups[0].parent_groups.all() + and get_site_preferences()["chronos__use_parent_groups"] + ): return groups[0].parent_groups.all() else: return groups diff --git a/aleksis/apps/chronos/menus.py b/aleksis/apps/chronos/menus.py index 592e6df9..4a07e4e8 100644 --- a/aleksis/apps/chronos/menus.py +++ b/aleksis/apps/chronos/menus.py @@ -17,7 +17,10 @@ MENUS = { "url": "my_timetable", "icon": "person", "validators": [ - ("aleksis.core.util.predicates.permission_validator", "chronos.view_my_timetable"), + ( + "aleksis.core.util.predicates.permission_validator", + "chronos.view_my_timetable", + ), ], }, { @@ -25,7 +28,10 @@ MENUS = { "url": "all_timetables", "icon": "grid_on", "validators": [ - ("aleksis.core.util.predicates.permission_validator", "chronos.view_timetable_overview"), + ( + "aleksis.core.util.predicates.permission_validator", + "chronos.view_timetable_overview", + ), ], }, { @@ -33,7 +39,10 @@ MENUS = { "url": "lessons_day", "icon": "calendar_today", "validators": [ - ("aleksis.core.util.predicates.permission_validator", "chronos.view_lessons_day"), + ( + "aleksis.core.util.predicates.permission_validator", + "chronos.view_lessons_day", + ), ], }, { @@ -41,7 +50,10 @@ MENUS = { "url": "substitutions", "icon": "update", "validators": [ - ("aleksis.core.util.predicates.permission_validator", "chronos.view_substitutions"), + ( + "aleksis.core.util.predicates.permission_validator", + "chronos.view_substitutions", + ), ], }, ], diff --git a/aleksis/apps/chronos/migrations/0005_remove_school_related.py b/aleksis/apps/chronos/migrations/0005_remove_school_related.py index f2ebba33..7d3ba123 100644 --- a/aleksis/apps/chronos/migrations/0005_remove_school_related.py +++ b/aleksis/apps/chronos/migrations/0005_remove_school_related.py @@ -6,69 +6,53 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('core', '0008_rename_fields_notification_activity'), - ('chronos', '0004_room_name_not_unique'), + ("core", "0008_rename_fields_notification_activity"), + ("chronos", "0004_room_name_not_unique"), ] operations = [ - migrations.RemoveField( - model_name='lesson', - name='school', - ), - migrations.RemoveField( - model_name='lessonperiod', - name='school', - ), + migrations.RemoveField(model_name="lesson", name="school",), + migrations.RemoveField(model_name="lessonperiod", name="school",), migrations.AlterField( - model_name='lesson', - name='teachers', - field=models.ManyToManyField(related_name='lessons_as_teacher', to='core.Person'), + model_name="lesson", + name="teachers", + field=models.ManyToManyField( + related_name="lessons_as_teacher", to="core.Person" + ), ), migrations.AlterField( - model_name='room', - name='short_name', - field=models.CharField(max_length=10, unique=True, verbose_name='Short name, e.g. room number'), + model_name="room", + name="short_name", + field=models.CharField( + max_length=10, unique=True, verbose_name="Short name, e.g. room number" + ), ), migrations.AlterField( - model_name='subject', - name='abbrev', - field=models.CharField(max_length=10, unique=True, verbose_name='Abbreviation of subject in timetable'), + model_name="subject", + name="abbrev", + field=models.CharField( + max_length=10, + unique=True, + verbose_name="Abbreviation of subject in timetable", + ), ), migrations.AlterField( - model_name='subject', - name='name', - field=models.CharField(max_length=30, unique=True, verbose_name='Long name of subject'), - ), - migrations.AlterUniqueTogether( - name='lessonsubstitution', - unique_together={('lesson_period', 'week')}, - ), - migrations.AlterUniqueTogether( - name='room', - unique_together=set(), + model_name="subject", + name="name", + field=models.CharField( + max_length=30, unique=True, verbose_name="Long name of subject" + ), ), migrations.AlterUniqueTogether( - name='subject', - unique_together=set(), + name="lessonsubstitution", unique_together={("lesson_period", "week")}, ), + migrations.AlterUniqueTogether(name="room", unique_together=set(),), + migrations.AlterUniqueTogether(name="subject", unique_together=set(),), migrations.AlterUniqueTogether( - name='timeperiod', - unique_together={('weekday', 'period')}, - ), - migrations.RemoveField( - model_name='lessonsubstitution', - name='school', - ), - migrations.RemoveField( - model_name='room', - name='school', - ), - migrations.RemoveField( - model_name='subject', - name='school', - ), - migrations.RemoveField( - model_name='timeperiod', - name='school', + name="timeperiod", unique_together={("weekday", "period")}, ), + migrations.RemoveField(model_name="lessonsubstitution", name="school",), + migrations.RemoveField(model_name="room", name="school",), + migrations.RemoveField(model_name="subject", name="school",), + migrations.RemoveField(model_name="timeperiod", name="school",), ] diff --git a/aleksis/apps/chronos/migrations/0006_extended_data.py b/aleksis/apps/chronos/migrations/0006_extended_data.py index 71785e3f..6cbea640 100644 --- a/aleksis/apps/chronos/migrations/0006_extended_data.py +++ b/aleksis/apps/chronos/migrations/0006_extended_data.py @@ -7,13 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('chronos', '0005_remove_school_related'), + ("chronos", "0005_remove_school_related"), ] operations = [ migrations.AddField( - model_name='lessonperiod', - name='extended_data', - field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False), + model_name="lessonperiod", + name="extended_data", + field=django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), ), ] diff --git a/aleksis/apps/chronos/migrations/0007_advanced_models_from_untis.py b/aleksis/apps/chronos/migrations/0007_advanced_models_from_untis.py index 87b517a8..ccefed73 100644 --- a/aleksis/apps/chronos/migrations/0007_advanced_models_from_untis.py +++ b/aleksis/apps/chronos/migrations/0007_advanced_models_from_untis.py @@ -9,272 +9,545 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('chronos', '0006_extended_data'), + ("chronos", "0006_extended_data"), ] operations = [ migrations.CreateModel( - name='Absence', + name="Absence", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('date_start', models.DateField(null=True, verbose_name='Effective start date of absence')), - ('date_end', models.DateField(null=True, verbose_name='Effective end date of absence')), - ('comment', models.TextField(verbose_name='Comment', null=True, blank=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "date_start", + models.DateField( + null=True, verbose_name="Effective start date of absence" + ), + ), + ( + "date_end", + models.DateField( + null=True, verbose_name="Effective end date of absence" + ), + ), + ( + "comment", + models.TextField(verbose_name="Comment", null=True, blank=True), + ), ], options={ - 'verbose_name': 'Absence', - 'verbose_name_plural': 'Absences', - 'ordering': ['date_start'], + "verbose_name": "Absence", + "verbose_name_plural": "Absences", + "ordering": ["date_start"], }, ), migrations.CreateModel( - name='AbsenceReason', + name="AbsenceReason", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('title', models.CharField(max_length=50, verbose_name='Title')), - ('description', models.TextField(verbose_name='Description', null=True, blank=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("title", models.CharField(max_length=50, verbose_name="Title")), + ( + "description", + models.TextField(verbose_name="Description", null=True, blank=True), + ), ], options={ - 'verbose_name': 'Absence reason', - 'verbose_name_plural': 'Absence reasons', + "verbose_name": "Absence reason", + "verbose_name_plural": "Absence reasons", }, ), migrations.CreateModel( - name='Event', + name="Event", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('title', models.CharField(max_length=50, verbose_name='Title')), - ('date_start', models.DateField(null=True, verbose_name='Effective start date of event')), - ('date_end', models.DateField(null=True, verbose_name='Effective end date of event')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("title", models.CharField(max_length=50, verbose_name="Title")), + ( + "date_start", + models.DateField( + null=True, verbose_name="Effective start date of event" + ), + ), + ( + "date_end", + models.DateField( + null=True, verbose_name="Effective end date of event" + ), + ), ], options={ - 'verbose_name': 'Events', - 'verbose_name_plural': 'Events', - 'ordering': ['date_start'], + "verbose_name": "Events", + "verbose_name_plural": "Events", + "ordering": ["date_start"], }, ), migrations.CreateModel( - name='Exam', + name="Exam", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('date', models.DateField(null=True, verbose_name='Date of exam')), - ('title', models.CharField(max_length=50, verbose_name='Title')), - ('comment', models.TextField(verbose_name='Comment', null=True, blank=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("date", models.DateField(null=True, verbose_name="Date of exam")), + ("title", models.CharField(max_length=50, verbose_name="Title")), + ( + "comment", + models.TextField(verbose_name="Comment", null=True, blank=True), + ), ], options={ - 'verbose_name': 'Exam', - 'verbose_name_plural': 'Exams', - 'ordering': ['date'], + "verbose_name": "Exam", + "verbose_name_plural": "Exams", + "ordering": ["date"], }, ), migrations.CreateModel( - name='Holiday', + name="Holiday", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('title', models.CharField(max_length=50, verbose_name='Title of the holidays')), - ('date_start', models.DateField(null=True, verbose_name='Effective start date of holidays')), - ('date_end', models.DateField(null=True, verbose_name='Effective end date of holidays')), - ('comments', models.TextField(verbose_name='Comments', null=True, blank=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "title", + models.CharField( + max_length=50, verbose_name="Title of the holidays" + ), + ), + ( + "date_start", + models.DateField( + null=True, verbose_name="Effective start date of holidays" + ), + ), + ( + "date_end", + models.DateField( + null=True, verbose_name="Effective end date of holidays" + ), + ), + ( + "comments", + models.TextField(verbose_name="Comments", null=True, blank=True), + ), ], options={ - 'verbose_name': 'Holiday', - 'verbose_name_plural': 'Holidays', - 'ordering': ['date_start'], + "verbose_name": "Holiday", + "verbose_name_plural": "Holidays", + "ordering": ["date_start"], }, ), migrations.CreateModel( - name='SupervisionArea', + name="SupervisionArea", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('short_name', models.CharField(max_length=10, verbose_name='Short name')), - ('name', models.CharField(max_length=50, verbose_name='Long name')), - ('colour_fg', colorfield.fields.ColorField(default='#000000', max_length=18)), - ('colour_bg', colorfield.fields.ColorField(default='#FFFFFF', max_length=18)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "short_name", + models.CharField(max_length=10, verbose_name="Short name"), + ), + ("name", models.CharField(max_length=50, verbose_name="Long name")), + ( + "colour_fg", + colorfield.fields.ColorField(default="#000000", max_length=18), + ), + ( + "colour_bg", + colorfield.fields.ColorField(default="#FFFFFF", max_length=18), + ), ], options={ - 'verbose_name': 'Supervision areas', - 'verbose_name_plural': 'Supervision areas', - 'ordering': ['name'], + "verbose_name": "Supervision areas", + "verbose_name_plural": "Supervision areas", + "ordering": ["name"], }, ), migrations.CreateModel( - name='Break', + name="Break", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('short_name', models.CharField(max_length=10, verbose_name='Short name')), - ('name', models.CharField(max_length=50, verbose_name='Long name')), - ('weekday', models.PositiveSmallIntegerField( - choices=[(0, 'Montag'), (1, 'Dienstag'), (2, 'Mittwoch'), (3, 'Donnerstag'), (4, 'Freitag'), - (5, 'Samstag'), (6, 'Sonntag')], verbose_name='Week day')), - ('time_start', models.TimeField(verbose_name='Start time')), - ('time_end', models.TimeField(verbose_name='End time')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "short_name", + models.CharField(max_length=10, verbose_name="Short name"), + ), + ("name", models.CharField(max_length=50, verbose_name="Long name")), + ( + "weekday", + models.PositiveSmallIntegerField( + choices=[ + (0, "Montag"), + (1, "Dienstag"), + (2, "Mittwoch"), + (3, "Donnerstag"), + (4, "Freitag"), + (5, "Samstag"), + (6, "Sonntag"), + ], + verbose_name="Week day", + ), + ), + ("time_start", models.TimeField(verbose_name="Start time")), + ("time_end", models.TimeField(verbose_name="End time")), ], options={ - 'verbose_name': 'Break', - 'verbose_name_plural': 'Breaks', - 'ordering': ['weekday', 'time_start'], + "verbose_name": "Break", + "verbose_name_plural": "Breaks", + "ordering": ["weekday", "time_start"], }, ), migrations.CreateModel( - name='Supervision', + name="Supervision", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), ], options={ - 'verbose_name': 'Supervision', - 'verbose_name_plural': 'Supervisions', - 'ordering': ['area', 'break_item'], + "verbose_name": "Supervision", + "verbose_name_plural": "Supervisions", + "ordering": ["area", "break_item"], }, ), migrations.CreateModel( - name='SupervisionSubstitution', + name="SupervisionSubstitution", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('date', models.DateField(verbose_name='Date')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ("date", models.DateField(verbose_name="Date")), ], options={ - 'verbose_name': 'Supervision substitution', - 'verbose_name_plural': 'Supervision substitutions', - 'ordering': ['date', 'supervision'], + "verbose_name": "Supervision substitution", + "verbose_name_plural": "Supervision substitutions", + "ordering": ["date", "supervision"], }, ), migrations.AddIndex( - model_name='holiday', - index=models.Index(fields=['date_start', 'date_end'], name='chronos_hol_date_st_a47004_idx'), + model_name="holiday", + index=models.Index( + fields=["date_start", "date_end"], name="chronos_hol_date_st_a47004_idx" + ), ), migrations.AddField( - model_name='exam', - name='lesson', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exams', to='chronos.Lesson'), + model_name="exam", + name="lesson", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="exams", + to="chronos.Lesson", + ), ), migrations.AddField( - model_name='exam', - name='period_from', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Effective start period of exam'), + model_name="exam", + name="period_from", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Effective start period of exam", + ), ), migrations.AddField( - model_name='exam', - name='period_to', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Effective end period of exam'), + model_name="exam", + name="period_to", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Effective end period of exam", + ), ), migrations.AddField( - model_name='event', - name='absence_reason', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='absence_reason', to='chronos.AbsenceReason', verbose_name='Absence reason'), + model_name="event", + name="absence_reason", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="absence_reason", + to="chronos.AbsenceReason", + verbose_name="Absence reason", + ), ), migrations.AddField( - model_name='event', - name='teachers', - field=models.ManyToManyField(related_name='events', to='core.Person', verbose_name='Teachers'), + model_name="event", + name="teachers", + field=models.ManyToManyField( + related_name="events", to="core.Person", verbose_name="Teachers" + ), ), migrations.AddField( - model_name='event', - name='period_from', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Effective start period of event'), + model_name="event", + name="period_from", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Effective start period of event", + ), ), migrations.AddField( - model_name='event', - name='period_to', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Effective end period of event'), + model_name="event", + name="period_to", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Effective end period of event", + ), ), migrations.AddField( - model_name='event', - name='rooms', - field=models.ManyToManyField(related_name='events', to='chronos.Room', verbose_name='Rooms'), + model_name="event", + name="rooms", + field=models.ManyToManyField( + related_name="events", to="chronos.Room", verbose_name="Rooms" + ), ), migrations.AddField( - model_name='absence', - name='period_from', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Effective start period of absence'), + model_name="absence", + name="period_from", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Effective start period of absence", + ), ), migrations.AddField( - model_name='absence', - name='period_to', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='chronos.TimePeriod', verbose_name='Effective end period of absence'), + model_name="absence", + name="period_to", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="chronos.TimePeriod", + verbose_name="Effective end period of absence", + ), ), migrations.AddField( - model_name='absence', - name='person', - field=models.ManyToManyField(related_name='absences', to='core.Person'), + model_name="absence", + name="person", + field=models.ManyToManyField(related_name="absences", to="core.Person"), ), migrations.AddField( - model_name='absence', - name='reason', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='chronos.AbsenceReason'), + model_name="absence", + name="reason", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="absences", + to="chronos.AbsenceReason", + ), ), migrations.AddIndex( - model_name='exam', - index=models.Index(fields=['date'], name='chronos_exa_date_5ba442_idx'), + model_name="exam", + index=models.Index(fields=["date"], name="chronos_exa_date_5ba442_idx"), ), migrations.AddIndex( - model_name='event', - index=models.Index(fields=['period_from', 'period_to', 'date_start', 'date_end'], name='chronos_eve_periodf_56eb18_idx'), + model_name="event", + index=models.Index( + fields=["period_from", "period_to", "date_start", "date_end"], + name="chronos_eve_periodf_56eb18_idx", + ), ), migrations.AddIndex( - model_name='absence', - index=models.Index(fields=['date_start', 'date_end'], name='chronos_abs_date_st_337ff5_idx'), + model_name="absence", + index=models.Index( + fields=["date_start", "date_end"], name="chronos_abs_date_st_337ff5_idx" + ), ), migrations.AddField( - model_name='lessonsubstitution', - name='cancelled_for_teachers', - field=models.BooleanField(default=False, verbose_name='Cancelled for teachers?'), + model_name="lessonsubstitution", + name="cancelled_for_teachers", + field=models.BooleanField( + default=False, verbose_name="Cancelled for teachers?" + ), ), migrations.AddField( - model_name='lessonsubstitution', - name='comment', - field=models.TextField(blank=True, null=True, verbose_name='Comment'), + model_name="lessonsubstitution", + name="comment", + field=models.TextField(blank=True, null=True, verbose_name="Comment"), ), migrations.AlterField( - model_name='lessonsubstitution', - name='cancelled', - field=models.BooleanField(default=False, verbose_name='Cancelled?'), + model_name="lessonsubstitution", + name="cancelled", + field=models.BooleanField(default=False, verbose_name="Cancelled?"), ), migrations.AddField( - model_name='event', - name='groups', - field=models.ManyToManyField(related_name='events', to='core.Group', verbose_name='Groups'), + model_name="event", + name="groups", + field=models.ManyToManyField( + related_name="events", to="core.Group", verbose_name="Groups" + ), ), migrations.AddField( - model_name='supervisionsubstitution', - name='supervision', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='substitutions', - to='chronos.Supervision', verbose_name='Supervision'), + model_name="supervisionsubstitution", + name="supervision", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="substitutions", + to="chronos.Supervision", + verbose_name="Supervision", + ), ), migrations.AddField( - model_name='supervisionsubstitution', - name='teacher', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - related_name='substituted_supervisions', to='core.Person', verbose_name='Teacher'), + model_name="supervisionsubstitution", + name="teacher", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="substituted_supervisions", + to="core.Person", + verbose_name="Teacher", + ), ), migrations.AddField( - model_name='supervision', - name='area', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supervisions', - to='chronos.SupervisionArea', verbose_name='Supervision area'), + model_name="supervision", + name="area", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="supervisions", + to="chronos.SupervisionArea", + verbose_name="Supervision area", + ), ), migrations.AddField( - model_name='supervision', - name='break_item', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supervisions', - to='chronos.Break', verbose_name='Break'), + model_name="supervision", + name="break_item", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="supervisions", + to="chronos.Break", + verbose_name="Break", + ), ), migrations.AddField( - model_name='supervision', - name='teacher', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supervisions', - to='core.Person', verbose_name='Teacher'), + model_name="supervision", + name="teacher", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="supervisions", + to="core.Person", + verbose_name="Teacher", + ), ), migrations.AddIndex( - model_name='break', - index=models.Index(fields=['weekday', 'time_start', 'time_end'], name='chronos_bre_weekday_165338_idx'), + model_name="break", + index=models.Index( + fields=["weekday", "time_start", "time_end"], + name="chronos_bre_weekday_165338_idx", + ), ), ] diff --git a/aleksis/apps/chronos/migrations/0008_break_period.py b/aleksis/apps/chronos/migrations/0008_break_period.py index 740fd91b..971432ab 100644 --- a/aleksis/apps/chronos/migrations/0008_break_period.py +++ b/aleksis/apps/chronos/migrations/0008_break_period.py @@ -7,38 +7,45 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('chronos', '0007_advanced_models_from_untis'), + ("chronos", "0007_advanced_models_from_untis"), ] operations = [ migrations.RemoveIndex( - model_name='break', - name='chronos_bre_weekday_165338_idx', - ), - migrations.RemoveField( - model_name='break', - name='time_end', - ), - migrations.RemoveField( - model_name='break', - name='time_start', - ), - migrations.RemoveField( - model_name='break', - name='weekday', + model_name="break", name="chronos_bre_weekday_165338_idx", ), + migrations.RemoveField(model_name="break", name="time_end",), + migrations.RemoveField(model_name="break", name="time_start",), + migrations.RemoveField(model_name="break", name="weekday",), migrations.AddField( - model_name='break', - name='after_period', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='break_after', to='chronos.TimePeriod', verbose_name='Effective start of break'), + model_name="break", + name="after_period", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="break_after", + to="chronos.TimePeriod", + verbose_name="Effective start of break", + ), ), migrations.AddField( - model_name='break', - name='before_period', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='break_before', to='chronos.TimePeriod', verbose_name='Effective end of break'), + model_name="break", + name="before_period", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="break_before", + to="chronos.TimePeriod", + verbose_name="Effective end of break", + ), ), migrations.AddIndex( - model_name='break', - index=models.Index(fields=['after_period', 'before_period'], name='chronos_bre_after_p_0f28d3_idx'), + model_name="break", + index=models.Index( + fields=["after_period", "before_period"], + name="chronos_bre_after_p_0f28d3_idx", + ), ), ] diff --git a/aleksis/apps/chronos/migrations/0009_extended_data.py b/aleksis/apps/chronos/migrations/0009_extended_data.py index 6c8ff264..ed65071f 100644 --- a/aleksis/apps/chronos/migrations/0009_extended_data.py +++ b/aleksis/apps/chronos/migrations/0009_extended_data.py @@ -7,33 +7,43 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('chronos', '0008_break_period'), + ("chronos", "0008_break_period"), ] operations = [ migrations.AddField( - model_name='lesson', - name='extended_data', - field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False), + model_name="lesson", + name="extended_data", + field=django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), ), migrations.AddField( - model_name='lessonsubstitution', - name='extended_data', - field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False), + model_name="lessonsubstitution", + name="extended_data", + field=django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), ), migrations.AddField( - model_name='room', - name='extended_data', - field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False), + model_name="room", + name="extended_data", + field=django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), ), migrations.AddField( - model_name='subject', - name='extended_data', - field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False), + model_name="subject", + name="extended_data", + field=django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), ), migrations.AddField( - model_name='timeperiod', - name='extended_data', - field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False), + model_name="timeperiod", + name="extended_data", + field=django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), ), ] diff --git a/aleksis/apps/chronos/migrations/0010_absence_reason_name.py b/aleksis/apps/chronos/migrations/0010_absence_reason_name.py index 7c57327a..95f05e8b 100644 --- a/aleksis/apps/chronos/migrations/0010_absence_reason_name.py +++ b/aleksis/apps/chronos/migrations/0010_absence_reason_name.py @@ -7,27 +7,29 @@ from django.db.models import F class Migration(migrations.Migration): dependencies = [ - ('chronos', '0009_extended_data'), + ("chronos", "0009_extended_data"), ] operations = [ migrations.AddField( - model_name='absencereason', - name='name', - field=models.CharField(default=F("description"), blank=True, max_length=255, null=True, verbose_name='Name'), + model_name="absencereason", + name="name", + field=models.CharField( + default=F("description"), + blank=True, + max_length=255, + null=True, + verbose_name="Name", + ), ), migrations.AddField( - model_name='absencereason', - name='short_name', - field=models.CharField(default=F("title"), max_length=255, verbose_name='Short name'), + model_name="absencereason", + name="short_name", + field=models.CharField( + default=F("title"), max_length=255, verbose_name="Short name" + ), preserve_default=False, ), - migrations.RemoveField( - model_name='absencereason', - name='description', - ), - migrations.RemoveField( - model_name='absencereason', - name='title', - ), + migrations.RemoveField(model_name="absencereason", name="description",), + migrations.RemoveField(model_name="absencereason", name="title",), ] diff --git a/aleksis/apps/chronos/migrations/0011_absence_for_groups_and_rooms.py b/aleksis/apps/chronos/migrations/0011_absence_for_groups_and_rooms.py index 008a723a..cf7df94c 100644 --- a/aleksis/apps/chronos/migrations/0011_absence_for_groups_and_rooms.py +++ b/aleksis/apps/chronos/migrations/0011_absence_for_groups_and_rooms.py @@ -7,27 +7,42 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('chronos', '0010_absence_reason_name'), + ("chronos", "0010_absence_reason_name"), ] operations = [ - migrations.RemoveField( - model_name='absence', - name='person', - ), + migrations.RemoveField(model_name="absence", name="person",), migrations.AddField( - model_name='absence', - name='group', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='core.Group'), + model_name="absence", + name="group", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="absences", + to="core.Group", + ), ), migrations.AddField( - model_name='absence', - name='room', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='chronos.Room'), + model_name="absence", + name="room", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="absences", + to="chronos.Room", + ), ), migrations.AddField( - model_name='absence', - name='teacher', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='core.Person'), + model_name="absence", + name="teacher", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="absences", + to="core.Person", + ), ), ] diff --git a/aleksis/apps/chronos/migrations/0012_event_remove_absence_reason.py b/aleksis/apps/chronos/migrations/0012_event_remove_absence_reason.py index 4e661196..5bdaaee5 100644 --- a/aleksis/apps/chronos/migrations/0012_event_remove_absence_reason.py +++ b/aleksis/apps/chronos/migrations/0012_event_remove_absence_reason.py @@ -6,12 +6,9 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('chronos', '0011_absence_for_groups_and_rooms'), + ("chronos", "0011_absence_for_groups_and_rooms"), ] operations = [ - migrations.RemoveField( - model_name='event', - name='absence_reason', - ), + migrations.RemoveField(model_name="event", name="absence_reason",), ] diff --git a/aleksis/apps/chronos/migrations/0013_event_title_optional.py b/aleksis/apps/chronos/migrations/0013_event_title_optional.py index 4bc05c39..6f18311e 100644 --- a/aleksis/apps/chronos/migrations/0013_event_title_optional.py +++ b/aleksis/apps/chronos/migrations/0013_event_title_optional.py @@ -6,13 +6,15 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('chronos', '0012_event_remove_absence_reason'), + ("chronos", "0012_event_remove_absence_reason"), ] operations = [ migrations.AlterField( - model_name='event', - name='title', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Title'), + model_name="event", + name="title", + field=models.CharField( + blank=True, max_length=255, null=True, verbose_name="Title" + ), ), ] diff --git a/aleksis/apps/chronos/migrations/0014_extra_lesson.py b/aleksis/apps/chronos/migrations/0014_extra_lesson.py index b0610a5e..d3a497d9 100644 --- a/aleksis/apps/chronos/migrations/0014_extra_lesson.py +++ b/aleksis/apps/chronos/migrations/0014_extra_lesson.py @@ -9,45 +9,88 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('chronos', '0013_event_title_optional'), + ("chronos", "0013_event_title_optional"), ] operations = [ migrations.CreateModel( - name='ExtraLesson', + name="ExtraLesson", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), - ('week', models.IntegerField(default=calendarweek.calendarweek.CalendarWeek.current_week, verbose_name='Week')), - ('comment', models.CharField(blank=True, max_length=255, null=True, verbose_name='Comment')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), + ( + "week", + models.IntegerField( + default=calendarweek.calendarweek.CalendarWeek.current_week, + verbose_name="Week", + ), + ), + ( + "comment", + models.CharField( + blank=True, max_length=255, null=True, verbose_name="Comment" + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False,}, ), migrations.AddField( - model_name='extralesson', - name='groups', - field=models.ManyToManyField(related_name='extra_lessons', to='core.Group', verbose_name='Groups'), + model_name="extralesson", + name="groups", + field=models.ManyToManyField( + related_name="extra_lessons", to="core.Group", verbose_name="Groups" + ), ), migrations.AddField( - model_name='extralesson', - name='period', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='extra_lessons', to='chronos.TimePeriod'), + model_name="extralesson", + name="period", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="extra_lessons", + to="chronos.TimePeriod", + ), ), migrations.AddField( - model_name='extralesson', - name='room', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='extra_lessons', to='chronos.Room', verbose_name='Room'), + model_name="extralesson", + name="room", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="extra_lessons", + to="chronos.Room", + verbose_name="Room", + ), ), migrations.AddField( - model_name='extralesson', - name='subject', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='extra_lessons', to='chronos.Subject', verbose_name='Subject'), + model_name="extralesson", + name="subject", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="extra_lessons", + to="chronos.Subject", + verbose_name="Subject", + ), ), migrations.AddField( - model_name='extralesson', - name='teachers', - field=models.ManyToManyField(related_name='extra_lessons_as_teacher', to='core.Person', verbose_name='Teachers'), + model_name="extralesson", + name="teachers", + field=models.ManyToManyField( + related_name="extra_lessons_as_teacher", + to="core.Person", + verbose_name="Teachers", + ), ), ] diff --git a/aleksis/apps/chronos/migrations/0015_rename_abbrev_to_short_name.py b/aleksis/apps/chronos/migrations/0015_rename_abbrev_to_short_name.py index 5d79636e..4912dd0d 100644 --- a/aleksis/apps/chronos/migrations/0015_rename_abbrev_to_short_name.py +++ b/aleksis/apps/chronos/migrations/0015_rename_abbrev_to_short_name.py @@ -7,17 +7,14 @@ from django.db.models import F class Migration(migrations.Migration): dependencies = [ - ('chronos', '0014_extra_lesson'), + ("chronos", "0014_extra_lesson"), ] operations = [ migrations.RenameField( - model_name='subject', - old_name='abbrev', - new_name='short_name', + model_name="subject", old_name="abbrev", new_name="short_name", ), migrations.AlterModelOptions( - name='subject', - options={'ordering': ['name', 'short_name']}, + name="subject", options={"ordering": ["name", "short_name"]}, ), ] diff --git a/aleksis/apps/chronos/migrations/0016_add_globalpermissions.py b/aleksis/apps/chronos/migrations/0016_add_globalpermissions.py index 785e2782..b43b2bf1 100644 --- a/aleksis/apps/chronos/migrations/0016_add_globalpermissions.py +++ b/aleksis/apps/chronos/migrations/0016_add_globalpermissions.py @@ -7,19 +7,36 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('chronos', '0015_rename_abbrev_to_short_name'), + ("chronos", "0015_rename_abbrev_to_short_name"), ] operations = [ migrations.CreateModel( - name='GlobalPermissions', + name="GlobalPermissions", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "extended_data", + django.contrib.postgres.fields.jsonb.JSONField( + default=dict, editable=False + ), + ), ], options={ - 'permissions': (('view_all_timetables', 'Can view all timetables'), ('view_timetable_overview', 'Can view timetable overview'), ('view_lessons_day', 'Can view all lessons per day')), - 'managed': False, + "permissions": ( + ("view_all_timetables", "Can view all timetables"), + ("view_timetable_overview", "Can view timetable overview"), + ("view_lessons_day", "Can view all lessons per day"), + ), + "managed": False, }, ), ] diff --git a/aleksis/apps/chronos/model_extensions.py b/aleksis/apps/chronos/model_extensions.py index 1a1bcd59..2877278e 100644 --- a/aleksis/apps/chronos/model_extensions.py +++ b/aleksis/apps/chronos/model_extensions.py @@ -93,4 +93,8 @@ def for_timetables(cls): Announcement.class_method(for_timetables) -Announcement.field(show_in_timetables=BooleanField(verbose_name=_("Show announcement in timetable views?"))) +Announcement.field( + show_in_timetables=BooleanField( + verbose_name=_("Show announcement in timetable views?") + ) +) diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index 556f3a1f..595ba172 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -3,9 +3,19 @@ from __future__ import annotations from datetime import date, datetime, timedelta, time from typing import Dict, Optional, Tuple, Union -from aleksis.apps.chronos.managers import GroupPropertiesMixin, TeacherPropertiesMixin, LessonSubstitutionManager, \ - LessonSubstitutionQuerySet, LessonPeriodManager, LessonPeriodQuerySet, AbsenceQuerySet, HolidayQuerySet, \ - SupervisionQuerySet, EventQuerySet, ExtraLessonQuerySet +from aleksis.apps.chronos.managers import ( + GroupPropertiesMixin, + TeacherPropertiesMixin, + LessonSubstitutionManager, + LessonSubstitutionQuerySet, + LessonPeriodManager, + LessonPeriodQuerySet, + AbsenceQuerySet, + HolidayQuerySet, + SupervisionQuerySet, + EventQuerySet, + ExtraLessonQuerySet, +) from django.core.exceptions import ValidationError from django.db import models from django.db.models import Max, Min, Q @@ -33,17 +43,16 @@ class TimePeriod(ExtensibleModel): WEEKDAY_CHOICES = list(enumerate(i18n_day_names_lazy())) WEEKDAY_CHOICES_SHORT = list(enumerate(i18n_day_abbrs_lazy())) - weekday = models.PositiveSmallIntegerField(verbose_name=_("Week day"), choices=WEEKDAY_CHOICES) + weekday = models.PositiveSmallIntegerField( + verbose_name=_("Week day"), choices=WEEKDAY_CHOICES + ) period = models.PositiveSmallIntegerField(verbose_name=_("Number of period")) time_start = models.TimeField(verbose_name=_("Start time")) time_end = models.TimeField(verbose_name=_("End time")) def __str__(self) -> str: - return "{}, {}.".format( - self.get_weekday_display(), - self.period, - ) + return "{}, {}.".format(self.get_weekday_display(), self.period,) @classmethod def get_times_dict(cls) -> Dict[int, Tuple[datetime, datetime]]: @@ -68,7 +77,9 @@ class TimePeriod(ExtensibleModel): return wanted_week[self.weekday] @classmethod - def get_next_relevant_day(cls, day: Optional[date] = None, time: Optional[time] = None, prev: bool = False) -> date: + def get_next_relevant_day( + cls, day: Optional[date] = None, time: Optional[time] = None, prev: bool = False + ) -> date: """ Returns next (previous) day with lessons depending on date and time """ if day is None: @@ -109,11 +120,15 @@ class TimePeriod(ExtensibleModel): @classproperty def period_min(cls) -> int: - return cls.objects.aggregate(period__min=Coalesce(Min("period"), 1)).get("period__min") + return cls.objects.aggregate(period__min=Coalesce(Min("period"), 1)).get( + "period__min" + ) @classproperty def period_max(cls) -> int: - return cls.objects.aggregate(period__max=Coalesce(Max("period"), 7)).get("period__max") + return cls.objects.aggregate(period__max=Coalesce(Max("period"), 7)).get( + "period__max" + ) @classproperty def time_min(cls) -> Optional[time]: @@ -125,11 +140,15 @@ class TimePeriod(ExtensibleModel): @classproperty def weekday_min(cls) -> int: - return cls.objects.aggregate(weekday__min=Coalesce(Min("weekday"), 0)).get("weekday__min") + return cls.objects.aggregate(weekday__min=Coalesce(Min("weekday"), 0)).get( + "weekday__min" + ) @classproperty def weekday_max(cls) -> int: - return cls.objects.aggregate(weekday__max=Coalesce(Max("weekday"), 6)).get("weekday__max") + return cls.objects.aggregate(weekday__max=Coalesce(Max("weekday"), 6)).get( + "weekday__max" + ) class Meta: unique_together = [["weekday", "period"]] @@ -140,7 +159,9 @@ class TimePeriod(ExtensibleModel): class Subject(ExtensibleModel): - short_name = models.CharField(verbose_name=_("Short name"), max_length=255, unique=True) + short_name = models.CharField( + verbose_name=_("Short name"), max_length=255, unique=True + ) name = models.CharField(verbose_name=_("Long name"), max_length=255, unique=True) colour_fg = ColorField(verbose_name=_("Foreground colour"), blank=True) @@ -156,7 +177,9 @@ class Subject(ExtensibleModel): class Room(ExtensibleModel): - short_name = models.CharField(verbose_name=_("Short name"), max_length=255, unique=True) + short_name = models.CharField( + verbose_name=_("Short name"), max_length=255, unique=True + ) name = models.CharField(verbose_name=_("Long name"), max_length=255) def __str__(self) -> str: @@ -168,13 +191,25 @@ class Room(ExtensibleModel): verbose_name_plural = _("Rooms") - - class Lesson(ExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin): - subject = models.ForeignKey("Subject", on_delete=models.CASCADE, related_name="lessons", verbose_name=_("Subject")) - teachers = models.ManyToManyField("core.Person", related_name="lessons_as_teacher", verbose_name=_("Teachers")) - periods = models.ManyToManyField("TimePeriod", related_name="lessons", through="LessonPeriod", verbose_name=_("Periods")) - groups = models.ManyToManyField("core.Group", related_name="lessons", verbose_name=_("Groups")) + subject = models.ForeignKey( + "Subject", + on_delete=models.CASCADE, + related_name="lessons", + verbose_name=_("Subject"), + ) + teachers = models.ManyToManyField( + "core.Person", related_name="lessons_as_teacher", verbose_name=_("Teachers") + ) + periods = models.ManyToManyField( + "TimePeriod", + related_name="lessons", + through="LessonPeriod", + verbose_name=_("Periods"), + ) + groups = models.ManyToManyField( + "core.Group", related_name="lessons", verbose_name=_("Groups") + ) date_start = models.DateField(verbose_name=_("Start date"), null=True) date_end = models.DateField(verbose_name=_("End date"), null=True) @@ -188,9 +223,7 @@ class Lesson(ExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin): def __str__(self): return "{}, {}, {}".format( - format_m2m(self.groups), - self.subject.short_name, - format_m2m(self.teachers), + format_m2m(self.groups), self.subject.short_name, format_m2m(self.teachers), ) class Meta: @@ -203,9 +236,13 @@ class Lesson(ExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin): class LessonSubstitution(ExtensibleModel): objects = LessonSubstitutionManager.from_queryset(LessonSubstitutionQuerySet)() - week = models.IntegerField(verbose_name=_("Week"), default=CalendarWeek.current_week) + week = models.IntegerField( + verbose_name=_("Week"), default=CalendarWeek.current_week + ) - lesson_period = models.ForeignKey("LessonPeriod", models.CASCADE, "substitutions", verbose_name=_("Lesson period")) + lesson_period = models.ForeignKey( + "LessonPeriod", models.CASCADE, "substitutions", verbose_name=_("Lesson period") + ) subject = models.ForeignKey( "Subject", @@ -216,18 +253,27 @@ class LessonSubstitution(ExtensibleModel): verbose_name=_("Subject"), ) teachers = models.ManyToManyField( - "core.Person", related_name="lesson_substitutions", blank=True, verbose_name=_("Teachers") + "core.Person", + related_name="lesson_substitutions", + blank=True, + verbose_name=_("Teachers"), + ) + room = models.ForeignKey( + "Room", models.CASCADE, null=True, blank=True, verbose_name=_("Room") ) - room = models.ForeignKey("Room", models.CASCADE, null=True, blank=True, verbose_name=_("Room")) cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled?")) - cancelled_for_teachers = models.BooleanField(default=False, verbose_name=_("Cancelled for teachers?")) + cancelled_for_teachers = models.BooleanField( + default=False, verbose_name=_("Cancelled for teachers?") + ) comment = models.TextField(verbose_name=_("Comment"), blank=True, null=True) def clean(self) -> None: if self.subject and self.cancelled: - raise ValidationError(_("Lessons can only be either substituted or cancelled.")) + raise ValidationError( + _("Lessons can only be either substituted or cancelled.") + ) @property def date(self): @@ -260,10 +306,26 @@ class LessonPeriod(ExtensibleModel): objects = LessonPeriodManager.from_queryset(LessonPeriodQuerySet)() - lesson = models.ForeignKey("Lesson", models.CASCADE, related_name="lesson_periods", verbose_name=_("Lesson")) - period = models.ForeignKey("TimePeriod", models.CASCADE, related_name="lesson_periods", verbose_name=_("Time period")) + lesson = models.ForeignKey( + "Lesson", + models.CASCADE, + related_name="lesson_periods", + verbose_name=_("Lesson"), + ) + period = models.ForeignKey( + "TimePeriod", + models.CASCADE, + related_name="lesson_periods", + verbose_name=_("Time period"), + ) - room = models.ForeignKey("Room", models.CASCADE, null=True, related_name="lesson_periods", verbose_name=_("Room")) + room = models.ForeignKey( + "Room", + models.CASCADE, + null=True, + related_name="lesson_periods", + verbose_name=_("Room"), + ) def get_substitution(self, week: Optional[int] = None) -> LessonSubstitution: wanted_week = week or getattr(self, "_week", None) or CalendarWeek().week @@ -301,13 +363,15 @@ class LessonPeriod(ExtensibleModel): return self.lesson.groups def __str__(self) -> str: - return "{}, {}".format( - str(self.period), - str(self.lesson) - ) + return "{}, {}".format(str(self.period), str(self.lesson)) class Meta: - ordering = ["lesson__date_start", "period__weekday", "period__period", "lesson__subject"] + ordering = [ + "lesson__date_start", + "period__weekday", + "period__period", + "lesson__subject", + ] indexes = [models.Index(fields=["lesson", "period"])] verbose_name = _("Lesson period") verbose_name_plural = _("Lesson periods") @@ -317,11 +381,13 @@ class TimetableWidget(DashboardWidget): template = "chronos/widget.html" def get_context(self): - from aleksis.apps.chronos.util.build import build_timetable # noqa + from aleksis.apps.chronos.util.build import build_timetable # noqa request = get_request() context = {"has_plan": True} - wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) if has_person(request.user): person = request.user.person @@ -345,9 +411,7 @@ class TimetableWidget(DashboardWidget): return context - media = Media(css={ - "all": ("css/chronos/timetable.css",) - }) + media = Media(css={"all": ("css/chronos/timetable.css",)}) class Meta: proxy = True @@ -357,7 +421,9 @@ class TimetableWidget(DashboardWidget): class AbsenceReason(ExtensibleModel): short_name = models.CharField(verbose_name=_("Short name"), max_length=255) - name = models.CharField(verbose_name=_("Name"), blank=True, null=True, max_length=255) + name = models.CharField( + verbose_name=_("Name"), blank=True, null=True, max_length=255 + ) def __str__(self): if self.name: @@ -373,16 +439,56 @@ class AbsenceReason(ExtensibleModel): class Absence(ExtensibleModel): objects = models.Manager.from_queryset(AbsenceQuerySet)() - reason = models.ForeignKey("AbsenceReason", on_delete=models.SET_NULL, related_name="absences", blank=True, null=True, verbose_name=_("Absence reason")) + reason = models.ForeignKey( + "AbsenceReason", + on_delete=models.SET_NULL, + related_name="absences", + blank=True, + null=True, + verbose_name=_("Absence reason"), + ) - teacher = models.ForeignKey("core.Person", on_delete=models.CASCADE, related_name="absences", null=True, blank=True, verbose_name=_("Teacher")) - group = models.ForeignKey("core.Group", on_delete=models.CASCADE, related_name="absences", null=True, blank=True, verbose_name=_("Group")) - room = models.ForeignKey("Room", on_delete=models.CASCADE, related_name="absences", null=True, blank=True, verbose_name=_("Room")) + teacher = models.ForeignKey( + "core.Person", + on_delete=models.CASCADE, + related_name="absences", + null=True, + blank=True, + verbose_name=_("Teacher"), + ) + group = models.ForeignKey( + "core.Group", + on_delete=models.CASCADE, + related_name="absences", + null=True, + blank=True, + verbose_name=_("Group"), + ) + room = models.ForeignKey( + "Room", + on_delete=models.CASCADE, + related_name="absences", + null=True, + blank=True, + verbose_name=_("Room"), + ) date_start = models.DateField(verbose_name=_("Start date"), null=True) date_end = models.DateField(verbose_name=_("End date"), null=True) - period_from = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, verbose_name=_("Start period"), null=True, related_name="+") - period_to = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, verbose_name=_("End period"), null=True, related_name="+") + period_from = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("Start period"), + null=True, + related_name="+", + ) + period_to = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("End period"), + null=True, + related_name="+", + ) comment = models.TextField(verbose_name=_("Comment"), blank=True, null=True) def __str__(self): @@ -403,11 +509,28 @@ class Absence(ExtensibleModel): class Exam(ExtensibleModel): - lesson = models.ForeignKey("Lesson", on_delete=models.CASCADE, related_name="exams", verbose_name=_("Lesson")) + lesson = models.ForeignKey( + "Lesson", + on_delete=models.CASCADE, + related_name="exams", + verbose_name=_("Lesson"), + ) date = models.DateField(verbose_name=_("Date of exam"), null=True) - period_from = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, verbose_name=_("Start period"), null=True, related_name="+") - period_to = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, verbose_name=_("End period"), null=True, related_name="+") + period_from = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("Start period"), + null=True, + related_name="+", + ) + period_to = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("End period"), + null=True, + related_name="+", + ) title = models.CharField(verbose_name=_("Title"), max_length=255) comment = models.TextField(verbose_name=_("Comment"), blank=True, null=True) @@ -476,12 +599,22 @@ class Break(ExtensibleModel): short_name = models.CharField(verbose_name=_("Short name"), max_length=255) name = models.CharField(verbose_name=_("Long name"), max_length=255) - after_period = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, - verbose_name=_("Time period after break starts"), - related_name="break_after", blank=True, null=True) - before_period = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, - verbose_name=_("Time period before break ends"), - related_name="break_before", blank=True, null=True) + after_period = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("Time period after break starts"), + related_name="break_after", + blank=True, + null=True, + ) + before_period = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("Time period before break ends"), + related_name="break_before", + blank=True, + null=True, + ) @property def weekday(self): @@ -536,9 +669,21 @@ class Break(ExtensibleModel): class Supervision(ExtensibleModel): objects = models.Manager.from_queryset(SupervisionQuerySet)() - area = models.ForeignKey(SupervisionArea, models.CASCADE, verbose_name=_("Supervision area"), related_name="supervisions") - break_item = models.ForeignKey(Break, models.CASCADE, verbose_name=_("Break"), related_name="supervisions") - teacher = models.ForeignKey("core.Person", models.CASCADE, related_name="supervisions", verbose_name=_("Teacher")) + area = models.ForeignKey( + SupervisionArea, + models.CASCADE, + verbose_name=_("Supervision area"), + related_name="supervisions", + ) + break_item = models.ForeignKey( + Break, models.CASCADE, verbose_name=_("Break"), related_name="supervisions" + ) + teacher = models.ForeignKey( + "core.Person", + models.CASCADE, + related_name="supervisions", + verbose_name=_("Teacher"), + ) def get_substitution( self, week: Optional[int] = None @@ -563,14 +708,24 @@ class Supervision(ExtensibleModel): class Meta: ordering = ["area", "break_item"] - verbose_name= _("Supervision") + verbose_name = _("Supervision") verbose_name_plural = _("Supervisions") class SupervisionSubstitution(ExtensibleModel): date = models.DateField(verbose_name=_("Date")) - supervision = models.ForeignKey(Supervision, models.CASCADE, verbose_name=_("Supervision"), related_name="substitutions") - teacher = models.ForeignKey("core.Person", models.CASCADE, related_name="substituted_supervisions", verbose_name=_("Teacher")) + supervision = models.ForeignKey( + Supervision, + models.CASCADE, + verbose_name=_("Supervision"), + related_name="substitutions", + ) + teacher = models.ForeignKey( + "core.Person", + models.CASCADE, + related_name="substituted_supervisions", + verbose_name=_("Teacher"), + ) @property def teachers(self): @@ -590,17 +745,35 @@ class Event(ExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin): objects = models.Manager.from_queryset(EventQuerySet)() - title = models.CharField(verbose_name=_("Title"), max_length=255, blank=True, null=True) + title = models.CharField( + verbose_name=_("Title"), max_length=255, blank=True, null=True + ) date_start = models.DateField(verbose_name=_("Start date"), null=True) date_end = models.DateField(verbose_name=_("End date"), null=True) - period_from = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, verbose_name=_("Start time period"), related_name="+") - period_to = models.ForeignKey("TimePeriod", on_delete=models.CASCADE, verbose_name=_("End time period"), related_name="+") + period_from = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("Start time period"), + related_name="+", + ) + period_to = models.ForeignKey( + "TimePeriod", + on_delete=models.CASCADE, + verbose_name=_("End time period"), + related_name="+", + ) - groups = models.ManyToManyField("core.Group", related_name="events", verbose_name=_("Groups")) - rooms = models.ManyToManyField("Room", related_name="events", verbose_name=_("Rooms")) - teachers = models.ManyToManyField("core.Person", related_name="events", verbose_name=_("Teachers")) + groups = models.ManyToManyField( + "core.Group", related_name="events", verbose_name=_("Groups") + ) + rooms = models.ManyToManyField( + "Room", related_name="events", verbose_name=_("Rooms") + ) + teachers = models.ManyToManyField( + "core.Person", related_name="events", verbose_name=_("Teachers") + ) def __str__(self): if self.title: @@ -626,7 +799,9 @@ class Event(ExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin): class Meta: ordering = ["date_start"] - indexes = [models.Index(fields=["period_from", "period_to", "date_start", "date_end"])] + indexes = [ + models.Index(fields=["period_from", "period_to", "date_start", "date_end"]) + ] verbose_name = _("Event") verbose_name_plural = _("Events") @@ -636,15 +811,41 @@ class ExtraLesson(ExtensibleModel, GroupPropertiesMixin): objects = models.Manager.from_queryset(ExtraLessonQuerySet)() - week = models.IntegerField(verbose_name=_("Week"), default=CalendarWeek.current_week) - period = models.ForeignKey("TimePeriod", models.CASCADE, related_name="extra_lessons", verbose_name=_("Time period")) + week = models.IntegerField( + verbose_name=_("Week"), default=CalendarWeek.current_week + ) + period = models.ForeignKey( + "TimePeriod", + models.CASCADE, + related_name="extra_lessons", + verbose_name=_("Time period"), + ) - subject = models.ForeignKey("Subject", on_delete=models.CASCADE, related_name="extra_lessons", verbose_name=_("Subject")) - groups = models.ManyToManyField("core.Group", related_name="extra_lessons", verbose_name=_("Groups")) - teachers = models.ManyToManyField("core.Person", related_name="extra_lessons_as_teacher", verbose_name=_("Teachers")) - room = models.ForeignKey("Room", models.CASCADE, null=True, related_name="extra_lessons", verbose_name=_("Room")) + subject = models.ForeignKey( + "Subject", + on_delete=models.CASCADE, + related_name="extra_lessons", + verbose_name=_("Subject"), + ) + groups = models.ManyToManyField( + "core.Group", related_name="extra_lessons", verbose_name=_("Groups") + ) + teachers = models.ManyToManyField( + "core.Person", + related_name="extra_lessons_as_teacher", + verbose_name=_("Teachers"), + ) + room = models.ForeignKey( + "Room", + models.CASCADE, + null=True, + related_name="extra_lessons", + verbose_name=_("Room"), + ) - comment = models.CharField(verbose_name=_("Comment"), blank=True, null=True, max_length=255) + comment = models.CharField( + verbose_name=_("Comment"), blank=True, null=True, max_length=255 + ) def __str__(self): return "{}, {}, {}".format(self.week, self.period, self.subject) diff --git a/aleksis/apps/chronos/preferences.py b/aleksis/apps/chronos/preferences.py index 69b435a4..c0a4294d 100644 --- a/aleksis/apps/chronos/preferences.py +++ b/aleksis/apps/chronos/preferences.py @@ -3,7 +3,10 @@ from django.utils.translation import gettext as _ from dynamic_preferences.preferences import Section from dynamic_preferences.types import BooleanPreference, IntegerPreference -from aleksis.core.registries import site_preferences_registry, person_preferences_registry +from aleksis.core.registries import ( + site_preferences_registry, + person_preferences_registry, +) chronos = Section("chronos", verbose_name=_("Chronos")) @@ -50,10 +53,11 @@ class SubstitutionsPrintNumberOfDays(IntegerPreference): default = 2 verbose_name = _("Number of days shown on substitutions print view") + @site_preferences_registry.register class SubstitutionsShowHeaderBox(BooleanPreference): section = chronos name = "substitutions_show_header_box" default = True verbose_name = _("Show header box in substitution views") - help_text = _("The header box shows affected teachers/groups.") + help_text = _("The header box shows affected teachers/groups.") diff --git a/aleksis/apps/chronos/rules.py b/aleksis/apps/chronos/rules.py index ddc398cd..dc0369b0 100644 --- a/aleksis/apps/chronos/rules.py +++ b/aleksis/apps/chronos/rules.py @@ -7,12 +7,12 @@ from aleksis.core.util.predicates import ( has_object_perm, ) from .models import LessonSubstitution -from .util.predicates import ( - has_timetable_perm -) +from .util.predicates import has_timetable_perm # View timetable overview -view_timetable_overview_predicate = has_person & has_global_perm("chronos.view_timetable_overview") +view_timetable_overview_predicate = has_person & has_global_perm( + "chronos.view_timetable_overview" +) add_perm("chronos.view_timetable_overview", view_timetable_overview_predicate) # View my timetable @@ -30,18 +30,21 @@ add_perm("chronos.view_lessons_day", view_lessons_day_predicate) # Edit substition edit_substitution_predicate = has_person & ( - has_global_perm("chronos.change_lessonsubstitution") | has_object_perm("chronos.change_lessonsubstitution") + has_global_perm("chronos.change_lessonsubstitution") + | has_object_perm("chronos.change_lessonsubstitution") ) add_perm("chronos.edit_substitution", edit_substitution_predicate) # Delete substitution delete_substitution_predicate = has_person & ( - has_global_perm("chronos.delete_lessonsubstitution") | has_object_perm("chronos.delete_lessonsubstitution") + has_global_perm("chronos.delete_lessonsubstitution") + | has_object_perm("chronos.delete_lessonsubstitution") ) add_perm("chronos.delete_substitution", delete_substitution_predicate) # View substitutions view_substitutions_predicate = has_person & ( - has_global_perm("chronos.view_lessonsubstitution") | has_any_object("chronos.view_lessonsubstitution", LessonSubstitution) + has_global_perm("chronos.view_lessonsubstitution") + | has_any_object("chronos.view_lessonsubstitution", LessonSubstitution) ) add_perm("chronos.view_substitutions", view_substitutions_predicate) diff --git a/aleksis/apps/chronos/tables.py b/aleksis/apps/chronos/tables.py index 9915dd47..92a966fe 100644 --- a/aleksis/apps/chronos/tables.py +++ b/aleksis/apps/chronos/tables.py @@ -25,16 +25,24 @@ def _css_class_from_lesson_state( class LessonsTable(tables.Table): """Table for daily lessons and management of substitutions.""" + class Meta: attrs = {"class": "highlight"} row_attrs = {"class": _css_class_from_lesson_state} period__period = tables.Column(accessor="period__period") - lesson__groups = tables.Column(accessor="lesson__group_names", verbose_name=_("Groups")) - lesson__teachers = tables.Column(accessor="lesson__teacher_names", verbose_name=_("Teachers")) + lesson__groups = tables.Column( + accessor="lesson__group_names", verbose_name=_("Groups") + ) + lesson__teachers = tables.Column( + accessor="lesson__teacher_names", verbose_name=_("Teachers") + ) lesson__subject = tables.Column(accessor="lesson__subject") room = tables.Column(accessor="room") edit_substitution = tables.LinkColumn( - "edit_substitution", args=[A("id"), A("_week")], text=_("Substitution"), - attrs={"a": {"class": "btn-flat waves-effect waves-orange"}}, verbose_name=_("Manage substitution") + "edit_substitution", + args=[A("id"), A("_week")], + text=_("Substitution"), + attrs={"a": {"class": "btn-flat waves-effect waves-orange"}}, + verbose_name=_("Manage substitution"), ) diff --git a/aleksis/apps/chronos/templatetags/common.py b/aleksis/apps/chronos/templatetags/common.py index 2a33c1b0..cfdec15c 100644 --- a/aleksis/apps/chronos/templatetags/common.py +++ b/aleksis/apps/chronos/templatetags/common.py @@ -4,7 +4,6 @@ register = template.Library() class SetVarNode(template.Node): - def __init__(self, var_name, var_value): self.var_name = var_name self.var_value = var_value @@ -19,13 +18,15 @@ class SetVarNode(template.Node): return u"" -@register.tag(name='set') +@register.tag(name="set") def set_var(parser, token): """ {% set some_var = '123' %} """ parts = token.split_contents() if len(parts) < 4: - raise template.TemplateSyntaxError("'set' tag must be of the form: {% set <var_name> = <var_value> %}") + raise template.TemplateSyntaxError( + "'set' tag must be of the form: {% set <var_name> = <var_value> %}" + ) return SetVarNode(parts[1], parts[3]) diff --git a/aleksis/apps/chronos/templatetags/week_helpers.py b/aleksis/apps/chronos/templatetags/week_helpers.py index acfb3a3a..054d3f9e 100644 --- a/aleksis/apps/chronos/templatetags/week_helpers.py +++ b/aleksis/apps/chronos/templatetags/week_helpers.py @@ -4,7 +4,11 @@ from typing import Optional, Union from django import template from django.db.models.query import QuerySet -from aleksis.apps.chronos.util.date import CalendarWeek, week_period_to_date, week_weekday_to_date +from aleksis.apps.chronos.util.date import ( + CalendarWeek, + week_period_to_date, + week_weekday_to_date, +) register = template.Library() diff --git a/aleksis/apps/chronos/urls.py b/aleksis/apps/chronos/urls.py index d5311f49..3d68c3a1 100644 --- a/aleksis/apps/chronos/urls.py +++ b/aleksis/apps/chronos/urls.py @@ -5,12 +5,28 @@ from . import views urlpatterns = [ path("", views.all_timetables, name="all_timetables"), path("timetable/my/", views.my_timetable, name="my_timetable"), - path("timetable/my/<int:year>/<int:month>/<int:day>/", views.my_timetable, name="my_timetable_by_date"), + path( + "timetable/my/<int:year>/<int:month>/<int:day>/", + views.my_timetable, + name="my_timetable_by_date", + ), path("timetable/<str:type_>/<int:pk>/", views.timetable, name="timetable"), - path("timetable/<str:type_>/<int:pk>/<int:year>/<int:week>/", views.timetable, name="timetable_by_week"), - path("timetable/<str:type_>/<int:pk>/<str:regular>/", views.timetable, name="timetable_regular"), + path( + "timetable/<str:type_>/<int:pk>/<int:year>/<int:week>/", + views.timetable, + name="timetable_by_week", + ), + path( + "timetable/<str:type_>/<int:pk>/<str:regular>/", + views.timetable, + name="timetable_regular", + ), path("lessons/", views.lessons_day, name="lessons_day"), - path("lessons/<int:year>/<int:month>/<int:day>/", views.lessons_day, name="lessons_day_by_date"), + path( + "lessons/<int:year>/<int:month>/<int:day>/", + views.lessons_day, + name="lessons_day_by_date", + ), path( "lessons/<int:id_>/<int:week>/substition/", views.edit_substitution, @@ -22,7 +38,21 @@ urlpatterns = [ name="delete_substitution", ), path("substitutions/", views.substitutions, name="substitutions"), - path("substitutions/print/", views.substitutions, {"is_print": True}, name="substitutions_print"), - path("substitutions/<int:year>/<int:month>/<int:day>/", views.substitutions, name="substitutions_by_date"), - path("substitutions/<int:year>/<int:month>/<int:day>/print/", views.substitutions, {"is_print": True}, name="substitutions_print_by_date"), + path( + "substitutions/print/", + views.substitutions, + {"is_print": True}, + name="substitutions_print", + ), + path( + "substitutions/<int:year>/<int:month>/<int:day>/", + views.substitutions, + name="substitutions_by_date", + ), + path( + "substitutions/<int:year>/<int:month>/<int:day>/print/", + views.substitutions, + {"is_print": True}, + name="substitutions_print_by_date", + ), ] diff --git a/aleksis/apps/chronos/util/build.py b/aleksis/apps/chronos/util/build.py index 9fbc4ce5..a73798e9 100644 --- a/aleksis/apps/chronos/util/build.py +++ b/aleksis/apps/chronos/util/build.py @@ -21,7 +21,9 @@ ExtraLesson = apps.get_model("chronos", "ExtraLesson") def build_timetable( - type_: Union[TimetableType, 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 = [] @@ -59,7 +61,9 @@ def build_timetable( if is_person: extra_lessons = ExtraLesson.objects.on_day(date_ref).filter_from_person(obj) else: - extra_lessons = ExtraLesson.objects.filter(week=date_ref.week).filter_from_type(type_, obj) + extra_lessons = ExtraLesson.objects.filter(week=date_ref.week).filter_from_type( + type_, obj + ) # Sort lesson periods in a dict extra_lessons_per_period = extra_lessons.group_by_periods(is_person=is_person) @@ -108,7 +112,7 @@ def build_timetable( # If not end day, use max period period_to = TimePeriod.period_max - for period in range(period_from, period_to +1): + for period in range(period_from, period_to + 1): if period not in events_per_period: events_per_period[period] = [] if is_person else {} @@ -126,7 +130,9 @@ def build_timetable( week = CalendarWeek.from_date(date_ref) else: week = date_ref - supervisions = Supervision.objects.all().annotate_week(week).filter_by_teacher(obj) + supervisions = ( + Supervision.objects.all().annotate_week(week).filter_by_teacher(obj) + ) if is_person: supervisions.filter_by_weekday(date_ref.weekday()) @@ -280,7 +286,7 @@ def build_substitutions_list(wanted_day: date) -> List[dict]: "type": "supervision_substitution", "sort_a": "Z.{}".format(super_sub.teacher), "sort_b": "{}".format(super_sub.supervision.break_item.after_period_number), - "el": super_sub + "el": super_sub, } rows.append(row) diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py index 72821e75..532d0ed9 100644 --- a/aleksis/apps/chronos/views.py +++ b/aleksis/apps/chronos/views.py @@ -64,7 +64,9 @@ def my_timetable( 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(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) if has_person(request.user): person = request.user.person @@ -86,7 +88,9 @@ def my_timetable( context["day"] = wanted_day context["periods"] = TimePeriod.get_times_dict() context["smart"] = True - context["announcements"] = Announcement.for_timetables().on_date(wanted_day).for_person(person) + context["announcements"] = ( + Announcement.for_timetables().on_date(wanted_day).for_person(person) + ) context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( wanted_day, "my_timetable_by_date" @@ -148,7 +152,9 @@ def timetable( # Build lists with weekdays and corresponding dates (long and short variant) context["weekdays"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES, wanted_week) - context["weekdays_short"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES_SHORT, wanted_week) + context["weekdays_short"] = build_weekdays( + TimePeriod.WEEKDAY_CHOICES_SHORT, wanted_week + ) context["weeks"] = get_weeks_for_year(year=wanted_week.year) context["week"] = wanted_week @@ -158,13 +164,15 @@ def timetable( context["smart"] = is_smart context["week_select"] = { "year": wanted_week.year, - "dest": reverse("timetable", args=[type_, pk]) + "dest": reverse("timetable", args=[type_, pk]), } if is_smart: start = wanted_week[TimePeriod.weekday_min] stop = wanted_week[TimePeriod.weekday_max] - context["announcements"] = Announcement.for_timetables().relevant_for(el).within_days(start, stop) + context["announcements"] = ( + Announcement.for_timetables().relevant_for(el).within_days(start, stop) + ) week_prev = wanted_week - 1 week_next = wanted_week + 1 @@ -193,7 +201,9 @@ def lessons_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(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) # Get lessons lesson_periods = LessonPeriod.objects.on_day(wanted_day) @@ -208,7 +218,7 @@ def lessons_day( context["datepicker"] = { "date": date_unix(wanted_day), - "dest": reverse("lessons_day") + "dest": reverse("lessons_day"), } context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( @@ -257,8 +267,7 @@ def edit_substitution(request: HttpRequest, id_: int, week: int) -> HttpResponse date = wanted_week[lesson_period.period.weekday] return redirect( - "lessons_day_by_date", - year=date.year, month=date.month, day=date.day + "lessons_day_by_date", year=date.year, month=date.month, day=date.day ) context["edit_substitution_form"] = edit_substitution_form @@ -281,8 +290,7 @@ def delete_substitution(request: HttpRequest, id_: int, week: int) -> HttpRespon date = wanted_week[lesson_period.period.weekday] return redirect( - "lessons_day_by_date", - year=date.year, month=date.month, day=date.day + "lessons_day_by_date", year=date.year, month=date.month, day=date.day ) @@ -301,7 +309,9 @@ def substitutions( 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(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day( + timezone.now().date(), datetime.now().time() + ) day_number = get_site_preferences()["chronos__substitutions_print_number_of_days"] day_contexts = {} @@ -318,11 +328,14 @@ def substitutions( subs = build_substitutions_list(day) day_contexts[day]["substitutions"] = subs - day_contexts[day]["announcements"] = Announcement.for_timetables().on_date(day).filter(show_in_timetables=True) + day_contexts[day]["announcements"] = ( + Announcement.for_timetables().on_date(day).filter(show_in_timetables=True) + ) if get_site_preferences()["chronos__substitutions_show_header_box"]: - subs = LessonSubstitution.objects.on_day(day).order_by("lesson_period__lesson__groups", - "lesson_period__period") + 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() -- GitLab