From 2013968ab6cac6243974109184e1d926b547e149 Mon Sep 17 00:00:00 2001
From: magicfelix <felix@felix-zauberer.de>
Date: Thu, 18 Apr 2024 16:49:57 +0200
Subject: [PATCH] Make ParticipationStatus a CalendarEvent and clean up
 migrations

---
 ...020_add_documentation_and_participation.py | 148 ------------------
 ...umentation_extramark_colour_bg_and_more.py |  96 ++++++++++++
 .../migrations/0021_participationstatus.py    | 113 -------------
 .../migrations/0022_documentation_teachers.py |  24 ---
 ..._colour_bg_extramark_colour_fg_and_more.py |  42 -----
 aleksis/apps/alsijil/models.py                |  21 +--
 6 files changed, 102 insertions(+), 342 deletions(-)
 delete mode 100644 aleksis/apps/alsijil/migrations/0020_add_documentation_and_participation.py
 create mode 100644 aleksis/apps/alsijil/migrations/0020_documentation_extramark_colour_bg_and_more.py
 delete mode 100644 aleksis/apps/alsijil/migrations/0021_participationstatus.py
 delete mode 100644 aleksis/apps/alsijil/migrations/0022_documentation_teachers.py
 delete mode 100644 aleksis/apps/alsijil/migrations/0023_extramark_colour_bg_extramark_colour_fg_and_more.py

diff --git a/aleksis/apps/alsijil/migrations/0020_add_documentation_and_participation.py b/aleksis/apps/alsijil/migrations/0020_add_documentation_and_participation.py
deleted file mode 100644
index 4d910b912..000000000
--- a/aleksis/apps/alsijil/migrations/0020_add_documentation_and_participation.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Generated by Django 4.2.4 on 2023-08-13 14:53
-
-import aleksis.apps.alsijil.models
-import aleksis.core.managers
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("chronos", "0016_lessonevent"),
-        ("core", "0052_site_related_name"),
-        ("cursus", "0001_initial"),
-        ("alsijil", "0019_drop_sites"),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name="Documentation",
-            fields=[
-                (
-                    "calendarevent_ptr",
-                    models.OneToOneField(
-                        auto_created=True,
-                        on_delete=django.db.models.deletion.CASCADE,
-                        parent_link=True,
-                        primary_key=True,
-                        serialize=False,
-                        to="core.calendarevent",
-                    ),
-                ),
-                (
-                    "topic",
-                    models.CharField(blank=True, max_length=255, verbose_name="Lesson topic"),
-                ),
-                ("homework", models.CharField(blank=True, max_length=255, verbose_name="Homework")),
-                (
-                    "group_note",
-                    models.CharField(blank=True, max_length=255, verbose_name="Group note"),
-                ),
-                (
-                    "course",
-                    models.ForeignKey(
-                        blank=True,
-                        null=True,
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="documentations",
-                        to="cursus.course",
-                    ),
-                ),
-                (
-                    "lesson_event",
-                    models.ForeignKey(
-                        blank=True,
-                        null=True,
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="documentation",
-                        to="chronos.lessonevent",
-                    ),
-                ),
-                (
-                    "subject",
-                    models.ForeignKey(
-                        blank=True,
-                        null=True,
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="+",
-                        to="cursus.subject",
-                    ),
-                ),
-            ],
-            options={
-                "verbose_name": "Documentation",
-                "verbose_name_plural": "Documentations",
-            },
-            bases=("core.calendarevent",),
-        ),
-        migrations.CreateModel(
-            name="Participation",
-            fields=[
-                (
-                    "id",
-                    models.BigAutoField(
-                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
-                    ),
-                ),
-                (
-                    "managed_by_app_label",
-                    models.CharField(
-                        blank=True,
-                        editable=False,
-                        max_length=255,
-                        verbose_name="App label of app responsible for managing this instance",
-                    ),
-                ),
-                ("extended_data", models.JSONField(default=dict, editable=False)),
-                ("remarks", models.CharField(blank=True, max_length=255)),
-                (
-                    "documentation",
-                    models.ForeignKey(
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="participations",
-                        to="alsijil.documentation",
-                    ),
-                ),
-                (
-                    "extra_marks",
-                    models.ManyToManyField(
-                        blank=True, to="alsijil.extramark", verbose_name="Extra marks"
-                    ),
-                ),
-                ("groups_of_person", models.ManyToManyField(related_name="+", to="core.group")),
-                (
-                    "person",
-                    models.ForeignKey(
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="participations",
-                        to="core.person",
-                    ),
-                ),
-            ],
-            options={
-                "verbose_name": "Participation note",
-                "verbose_name_plural": "Participation notes",
-                "ordering": ["documentation", "person__last_name", "person__first_name"],
-            },
-            bases=(aleksis.apps.alsijil.models.RegisterObjectRelatedMixin, models.Model),
-            managers=[
-                ("objects", aleksis.core.managers.AlekSISBaseManager()),
-            ],
-        ),
-        migrations.AddConstraint(
-            model_name="participation",
-            constraint=models.UniqueConstraint(
-                fields=("documentation", "person"), name="unique_participation_per_documentation"
-            ),
-        ),
-        migrations.AddConstraint(
-            model_name="documentation",
-            constraint=models.CheckConstraint(
-                check=models.Q(
-                    ("course__isnull", True), ("lesson_event__isnull", True), _negated=True
-                ),
-                name="either_course_or_lesson_event",
-            ),
-        ),
-    ]
diff --git a/aleksis/apps/alsijil/migrations/0020_documentation_extramark_colour_bg_and_more.py b/aleksis/apps/alsijil/migrations/0020_documentation_extramark_colour_bg_and_more.py
new file mode 100644
index 000000000..6122c1344
--- /dev/null
+++ b/aleksis/apps/alsijil/migrations/0020_documentation_extramark_colour_bg_and_more.py
@@ -0,0 +1,96 @@
+# Generated by Django 4.2.10 on 2024-04-18 14:48
+
+import colorfield.fields
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0062_alter_freebusy_options_and_more'),
+        ('kolego', '0003_refactor_absence'),
+        ('cursus', '0004_alter_subject_colour_bg_alter_subject_colour_fg_and_more'),
+        ('alsijil', '0019_drop_sites'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Documentation',
+            fields=[
+                ('calendarevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.calendarevent')),
+                ('topic', models.CharField(blank=True, max_length=255, verbose_name='Lesson Topic')),
+                ('homework', models.CharField(blank=True, max_length=255, verbose_name='Homework')),
+                ('group_note', models.CharField(blank=True, max_length=255, verbose_name='Group Note')),
+                ('course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='documentations', to='cursus.course', verbose_name='Course')),
+                ('subject', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='cursus.subject', verbose_name='Subject')),
+                ('teachers', models.ManyToManyField(blank=True, null=True, related_name='documentations_as_teacher', to='core.person', verbose_name='Teachers')),
+            ],
+            options={
+                'verbose_name': 'Documentation',
+                'verbose_name_plural': 'Documentations',
+            },
+            bases=('core.calendarevent',),
+        ),
+        migrations.AddField(
+            model_name='extramark',
+            name='colour_bg',
+            field=colorfield.fields.ColorField(blank=True, default='', image_field=None, max_length=25, samples=None, verbose_name='Background colour'),
+        ),
+        migrations.AddField(
+            model_name='extramark',
+            name='colour_fg',
+            field=colorfield.fields.ColorField(blank=True, default='', image_field=None, max_length=25, samples=None, verbose_name='Foreground colour'),
+        ),
+        migrations.AddField(
+            model_name='extramark',
+            name='show_in_coursebook',
+            field=models.BooleanField(default=True, verbose_name='Show in coursebook'),
+        ),
+        migrations.CreateModel(
+            name='ParticipationStatus',
+            fields=[
+                ('calendarevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.calendarevent')),
+                ('absent', models.BooleanField(verbose_name='Absent')),
+                ('absence_reason', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='kolego.absencereason', verbose_name='Absence Reason')),
+                ('base_absence', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='absences', to='kolego.absence', verbose_name='Base Absence')),
+                ('groups_of_person', models.ManyToManyField(related_name='+', to='core.group', verbose_name='Groups of Person')),
+                ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='participations', to='core.person', verbose_name='Person')),
+                ('related_documentation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='participations', to='alsijil.documentation', verbose_name='Documentation')),
+            ],
+            options={
+                'verbose_name': 'Participation Status',
+                'verbose_name_plural': 'Participation Status',
+                'ordering': ['related_documentation', 'person__last_name', 'person__first_name'],
+            },
+            bases=('core.calendarevent',),
+        ),
+        migrations.CreateModel(
+            name='NewPersonalNote',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('managed_by_app_label', models.CharField(blank=True, editable=False, max_length=255, verbose_name='App label of app responsible for managing this instance')),
+                ('extended_data', models.JSONField(default=dict, editable=False)),
+                ('note', models.TextField(blank=True, verbose_name='Note')),
+                ('documentation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='personal_notes', to='alsijil.documentation', verbose_name='Documentation')),
+                ('extra_mark', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='alsijil.extramark', verbose_name='Extra Mark')),
+                ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='new_personal_notes', to='core.person', verbose_name='Person')),
+            ],
+            options={
+                'verbose_name': 'Personal Note',
+                'verbose_name_plural': 'Personal Notes',
+            },
+        ),
+        migrations.AddConstraint(
+            model_name='participationstatus',
+            constraint=models.UniqueConstraint(fields=('related_documentation', 'person'), name='unique_participation_status_per_documentation'),
+        ),
+        migrations.AddConstraint(
+            model_name='newpersonalnote',
+            constraint=models.CheckConstraint(check=models.Q(models.Q(('note', ''), _negated=True), ('extra_mark__isnull', False), _connector='OR'), name='unique_absence_per_documentation'),
+        ),
+        migrations.AddConstraint(
+            model_name='documentation',
+            constraint=models.CheckConstraint(check=models.Q(('amends__isnull', True), ('course__isnull', True), _negated=True), name='either_course_or_amends'),
+        ),
+    ]
diff --git a/aleksis/apps/alsijil/migrations/0021_participationstatus.py b/aleksis/apps/alsijil/migrations/0021_participationstatus.py
deleted file mode 100644
index 5f3a7225f..000000000
--- a/aleksis/apps/alsijil/migrations/0021_participationstatus.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-11 20:43
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('cursus', '0001_initial'),
-        ('core', '0052_site_related_name'),
-        ('chronos', '0016_lessonevent'),
-        ('kolego', '0003_refactor_absence'),
-        ('alsijil', '0020_add_documentation_and_participation'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='NewPersonalNote',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('managed_by_app_label', models.CharField(blank=True, editable=False, max_length=255, verbose_name='App label of app responsible for managing this instance')),
-                ('extended_data', models.JSONField(default=dict, editable=False)),
-                ('note', models.TextField(blank=True, verbose_name='Note')),
-            ],
-            options={
-                'verbose_name': 'Personal Note',
-                'verbose_name_plural': 'Personal Notes',
-            },
-        ),
-        migrations.CreateModel(
-            name='ParticipationStatus',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('managed_by_app_label', models.CharField(blank=True, editable=False, max_length=255, verbose_name='App label of app responsible for managing this instance')),
-                ('extended_data', models.JSONField(default=dict, editable=False)),
-                ('absent', models.BooleanField(verbose_name='Absent')),
-                ('absence_reason', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='kolego.absencereason', verbose_name='Absence Reason')),
-                ('base_absence', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='absences', to='kolego.absence', verbose_name='Base Absence')),
-            ],
-            options={
-                'verbose_name': 'Participation Status',
-                'verbose_name_plural': 'Participation Status',
-                'ordering': ['documentation', 'person__last_name', 'person__first_name'],
-            },
-        ),
-        migrations.AlterField(
-            model_name='documentation',
-            name='course',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='documentations', to='cursus.course', verbose_name='Course'),
-        ),
-        migrations.AlterField(
-            model_name='documentation',
-            name='group_note',
-            field=models.CharField(blank=True, max_length=255, verbose_name='Group Note'),
-        ),
-        migrations.AlterField(
-            model_name='documentation',
-            name='lesson_event',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='documentation', to='chronos.lessonevent', verbose_name='Lesson Event'),
-        ),
-        migrations.AlterField(
-            model_name='documentation',
-            name='subject',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='cursus.subject', verbose_name='Subject'),
-        ),
-        migrations.AlterField(
-            model_name='documentation',
-            name='topic',
-            field=models.CharField(blank=True, max_length=255, verbose_name='Lesson Topic'),
-        ),
-        migrations.DeleteModel(
-            name='Participation',
-        ),
-        migrations.AddField(
-            model_name='participationstatus',
-            name='documentation',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='participations', to='alsijil.documentation', verbose_name='Documentation'),
-        ),
-        migrations.AddField(
-            model_name='participationstatus',
-            name='groups_of_person',
-            field=models.ManyToManyField(related_name='+', to='core.group', verbose_name='Groups of Person'),
-        ),
-        migrations.AddField(
-            model_name='participationstatus',
-            name='person',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='participations', to='core.person', verbose_name='Person'),
-        ),
-        migrations.AddField(
-            model_name='newpersonalnote',
-            name='documentation',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='personal_notes', to='alsijil.documentation', verbose_name='Documentation'),
-        ),
-        migrations.AddField(
-            model_name='newpersonalnote',
-            name='extra_mark',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='alsijil.extramark', verbose_name='Extra Mark'),
-        ),
-        migrations.AddField(
-            model_name='newpersonalnote',
-            name='person',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='new_personal_notes', to='core.person', verbose_name='Person'),
-        ),
-        migrations.AddConstraint(
-            model_name='participationstatus',
-            constraint=models.UniqueConstraint(fields=('documentation', 'person'), name='unique_participation_status_per_documentation'),
-        ),
-        migrations.AddConstraint(
-            model_name='newpersonalnote',
-            constraint=models.CheckConstraint(check=models.Q(models.Q(('note', ''), _negated=True), ('extra_mark__isnull', False), _connector='OR'), name='unique_absence_per_documentation'),
-        ),
-    ]
diff --git a/aleksis/apps/alsijil/migrations/0022_documentation_teachers.py b/aleksis/apps/alsijil/migrations/0022_documentation_teachers.py
deleted file mode 100644
index 8e6c30bd9..000000000
--- a/aleksis/apps/alsijil/migrations/0022_documentation_teachers.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 4.2.9 on 2024-03-16 00:59
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-    dependencies = [
-        ("core", "0061_remove_group_additional_fields"),
-        ("alsijil", "0021_participationstatus"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="documentation",
-            name="teachers",
-            field=models.ManyToManyField(
-                blank=True,
-                null=True,
-                related_name="documentations_as_teacher",
-                to="core.person",
-                verbose_name="Teachers",
-            ),
-        ),
-    ]
diff --git a/aleksis/apps/alsijil/migrations/0023_extramark_colour_bg_extramark_colour_fg_and_more.py b/aleksis/apps/alsijil/migrations/0023_extramark_colour_bg_extramark_colour_fg_and_more.py
deleted file mode 100644
index e47867577..000000000
--- a/aleksis/apps/alsijil/migrations/0023_extramark_colour_bg_extramark_colour_fg_and_more.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Generated by Django 4.2.9 on 2024-03-16 01:05
-
-import colorfield.fields
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-    dependencies = [
-        ("alsijil", "0022_documentation_teachers"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="extramark",
-            name="colour_bg",
-            field=colorfield.fields.ColorField(
-                blank=True,
-                default="",
-                image_field=None,
-                max_length=25,
-                samples=None,
-                verbose_name="Background colour",
-            ),
-        ),
-        migrations.AddField(
-            model_name="extramark",
-            name="colour_fg",
-            field=colorfield.fields.ColorField(
-                blank=True,
-                default="",
-                image_field=None,
-                max_length=25,
-                samples=None,
-                verbose_name="Foreground colour",
-            ),
-        ),
-        migrations.AddField(
-            model_name="extramark",
-            name="show_in_coursebook",
-            field=models.BooleanField(default=True, verbose_name="Show in coursebook"),
-        ),
-    ]
diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index 32cbe12f4..4cfa41cda 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -467,15 +467,6 @@ class Documentation(CalendarEvent):
         verbose_name=_("Course"),
     )
 
-    lesson_event = models.ForeignKey(
-        LessonEvent,
-        models.PROTECT,
-        related_name="documentation",
-        blank=True,
-        null=True,
-        verbose_name=_("Lesson Event"),
-    )
-
     subject = models.ForeignKey(
         Subject, models.PROTECT, related_name="+", blank=True, null=True, verbose_name=_("Subject")
     )
@@ -522,8 +513,8 @@ class Documentation(CalendarEvent):
         verbose_name_plural = _("Documentations")
         constraints = [
             models.CheckConstraint(
-                check=~Q(course__isnull=True, lesson_event__isnull=True),
-                name="either_course_or_lesson_event",
+                check=~Q(course__isnull=True, amends__isnull=True),
+                name="either_course_or_amends",
             ),
         ]
 
@@ -609,7 +600,7 @@ class Documentation(CalendarEvent):
         return docs
 
 
-class ParticipationStatus(ExtensibleModel):
+class ParticipationStatus(CalendarEvent):
     """A participation or absence record about a single person.
 
     Used in the class register to note participation or absence of a student
@@ -625,7 +616,7 @@ class ParticipationStatus(ExtensibleModel):
         "core.Group", related_name="+", verbose_name=_("Groups of Person")
     )
 
-    documentation = models.ForeignKey(
+    related_documentation = models.ForeignKey(
         Documentation,
         models.CASCADE,
         related_name="participations",
@@ -654,13 +645,13 @@ class ParticipationStatus(ExtensibleModel):
         verbose_name = _("Participation Status")
         verbose_name_plural = _("Participation Status")
         ordering = [
-            "documentation",
+            "related_documentation",
             "person__last_name",
             "person__first_name",
         ]
         constraints = [
             models.UniqueConstraint(
-                fields=("documentation", "person"),
+                fields=("related_documentation", "person"),
                 name="unique_participation_status_per_documentation",
             ),
         ]
-- 
GitLab