From f9991cec416c7d16bfe3c47397a9c7c1eba7f03d Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Sun, 10 Jan 2021 16:56:33 +0100 Subject: [PATCH] Update LessonDocumentation and PersonalNote to link also to events and extra lessons --- .../migrations/0008_events_extra_lessons.py | 91 +++++++++++++++++++ aleksis/apps/alsijil/models.py | 67 ++++++++++++-- 2 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 aleksis/apps/alsijil/migrations/0008_events_extra_lessons.py diff --git a/aleksis/apps/alsijil/migrations/0008_events_extra_lessons.py b/aleksis/apps/alsijil/migrations/0008_events_extra_lessons.py new file mode 100644 index 000000000..606a92161 --- /dev/null +++ b/aleksis/apps/alsijil/migrations/0008_events_extra_lessons.py @@ -0,0 +1,91 @@ +# Generated by Django 3.1.5 on 2021-01-10 15:48 + +import aleksis.apps.chronos.util.date +import django.contrib.sites.managers +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('chronos', '0004_substitution_extra_lesson_year'), + ('alsijil', '0007_personal_note_lesson_documentation_year'), + ] + + operations = [ + migrations.AlterModelOptions( + name='lessondocumentation', + options={'ordering': ['year', 'week', 'lesson_period__period__weekday', 'lesson_period__period__period'], 'verbose_name': 'Lesson documentation', 'verbose_name_plural': 'Lesson documentations'}, + ), + migrations.AlterModelOptions( + name='personalnote', + options={'ordering': ['year', 'week', 'lesson_period__period__weekday', 'lesson_period__period__period', 'person__last_name', 'person__first_name'], 'verbose_name': 'Personal note', 'verbose_name_plural': 'Personal notes'}, + ), + migrations.AddField( + model_name='lessondocumentation', + name='event', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='documentations', to='chronos.event'), + ), + migrations.AddField( + model_name='lessondocumentation', + name='extra_lesson', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='documentations', to='chronos.extralesson'), + ), + migrations.AddField( + model_name='personalnote', + name='event', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='personal_notes', to='chronos.event'), + ), + migrations.AddField( + model_name='personalnote', + name='extra_lesson', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='personal_notes', to='chronos.extralesson'), + ), + migrations.AlterField( + model_name='lessondocumentation', + name='lesson_period', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='documentations', to='chronos.lessonperiod'), + ), + migrations.AlterField( + model_name='lessondocumentation', + name='week', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='lessondocumentation', + name='year', + field=models.IntegerField(blank=True, default=aleksis.apps.chronos.util.date.get_current_year, null=True, verbose_name='Year'), + ), + migrations.AlterField( + model_name='personalnote', + name='lesson_period', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='personal_notes', to='chronos.lessonperiod'), + ), + migrations.AlterField( + model_name='personalnote', + name='week', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AlterField( + model_name='personalnote', + name='year', + field=models.IntegerField(blank=True, default=aleksis.apps.chronos.util.date.get_current_year, null=True, verbose_name='Year'), + ), + migrations.AlterUniqueTogether( + name='lessondocumentation', + unique_together=set(), + ), + migrations.AlterUniqueTogether( + name='personalnote', + unique_together=set(), + ), + migrations.AddConstraint( + model_name='lessondocumentation', + constraint=models.CheckConstraint(check=models.Q(models.Q(('event__isnull', True), ('extra_lesson__isnull', True), ('lesson_period__isnull', False), ('week__isnull', False), ('year__isnull', False)), models.Q(('event__isnull', False), ('extra_lesson__isnull', True), ('lesson_period__isnull', True), ('week__isnull', True), ('year__isnull', True)), models.Q(('event__isnull', True), ('extra_lesson__isnull', False), ('lesson_period__isnull', True), ('week__isnull', True), ('year__isnull', True)), _connector='OR'), name='one_relation_only_lesson_documentation'), + ), + migrations.AddConstraint( + model_name='personalnote', + constraint=models.CheckConstraint(check=models.Q(models.Q(('event__isnull', True), ('extra_lesson__isnull', True), ('lesson_period__isnull', False), ('week__isnull', False), ('year__isnull', False)), models.Q(('event__isnull', False), ('extra_lesson__isnull', True), ('lesson_period__isnull', True), ('week__isnull', True), ('year__isnull', True)), models.Q(('event__isnull', True), ('extra_lesson__isnull', False), ('lesson_period__isnull', True), ('week__isnull', True), ('year__isnull', True)), _connector='OR'), name='one_relation_only_personal_note'), + ), + ] diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index dc92c009f..38526f78b 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -1,4 +1,6 @@ from django.db import models +from django.db.models.constraints import CheckConstraint +from django.db.models.query_utils import Q from django.urls import reverse from django.utils.formats import date_format from django.utils.translation import gettext_lazy as _ @@ -46,6 +48,31 @@ class ExcuseType(ExtensibleModel): verbose_name_plural = _("Excuse types") +lesson_related_constraint_q = ( + Q( + lesson_period__isnull=False, + event__isnull=True, + extra_lesson__isnull=True, + week__isnull=False, + year__isnull=False, + ) + | Q( + lesson_period__isnull=True, + event__isnull=False, + extra_lesson__isnull=True, + week__isnull=True, + year__isnull=True, + ) + | Q( + lesson_period__isnull=True, + event__isnull=True, + extra_lesson__isnull=False, + week__isnull=True, + year__isnull=True, + ) +) + + class PersonalNote(ExtensibleModel, WeekRelatedMixin): """A personal note about a single person. @@ -65,11 +92,19 @@ class PersonalNote(ExtensibleModel, WeekRelatedMixin): person = models.ForeignKey("core.Person", models.CASCADE, related_name="personal_notes") groups_of_person = models.ManyToManyField("core.Group", related_name="+") - week = models.IntegerField() - year = models.IntegerField(verbose_name=_("Year"), default=get_current_year) + week = models.IntegerField(blank=True, null=True) + year = models.IntegerField( + verbose_name=_("Year"), default=get_current_year, blank=True, null=True + ) lesson_period = models.ForeignKey( - "chronos.LessonPeriod", models.CASCADE, related_name="personal_notes" + "chronos.LessonPeriod", models.CASCADE, related_name="personal_notes", blank=True, null=True + ) + event = models.ForeignKey( + "chronos.Event", models.CASCADE, related_name="personal_notes", blank=True, null=True + ) + extra_lesson = models.ForeignKey( + "chronos.ExtraLesson", models.CASCADE, related_name="personal_notes", blank=True, null=True ) absent = models.BooleanField(default=False) @@ -123,7 +158,6 @@ class PersonalNote(ExtensibleModel, WeekRelatedMixin): class Meta: verbose_name = _("Personal note") verbose_name_plural = _("Personal notes") - unique_together = [["lesson_period", "week", "person"]] ordering = [ "year", "week", @@ -132,6 +166,11 @@ class PersonalNote(ExtensibleModel, WeekRelatedMixin): "person__last_name", "person__first_name", ] + constraints = [ + CheckConstraint( + check=lesson_related_constraint_q, name="one_relation_only_personal_note" + ) + ] class LessonDocumentation(ExtensibleModel, WeekRelatedMixin): @@ -142,11 +181,19 @@ class LessonDocumentation(ExtensibleModel, WeekRelatedMixin): data_checks = [LessonDocumentationOnHolidaysDataCheck] - week = models.IntegerField() - year = models.IntegerField(verbose_name=_("Year"), default=get_current_year) + week = models.IntegerField(blank=True, null=True) + year = models.IntegerField( + verbose_name=_("Year"), default=get_current_year, blank=True, null=True + ) lesson_period = models.ForeignKey( - "chronos.LessonPeriod", models.CASCADE, related_name="documentations" + "chronos.LessonPeriod", models.CASCADE, related_name="documentations", blank=True, null=True + ) + event = models.ForeignKey( + "chronos.Event", models.CASCADE, related_name="documentations", blank=True, null=True + ) + extra_lesson = models.ForeignKey( + "chronos.ExtraLesson", models.CASCADE, related_name="documentations", blank=True, null=True ) topic = models.CharField(verbose_name=_("Lesson topic"), max_length=200, blank=True) @@ -203,13 +250,17 @@ class LessonDocumentation(ExtensibleModel, WeekRelatedMixin): class Meta: verbose_name = _("Lesson documentation") verbose_name_plural = _("Lesson documentations") - unique_together = [["lesson_period", "week"]] ordering = [ "year", "week", "lesson_period__period__weekday", "lesson_period__period__period", ] + constraints = [ + CheckConstraint( + check=lesson_related_constraint_q, name="one_relation_only_lesson_documentation", + ) + ] class ExtraMark(ExtensibleModel): -- GitLab