diff --git a/aleksis/apps/alsijil/migrations/0023_add_tardiness_and_rework_constraints.py b/aleksis/apps/alsijil/migrations/0023_add_tardiness_and_rework_constraints.py index 9d3234506e7e2b9b235753639faf7caf3d960f00..3ca24f5865ddf5d3fb02acbd0aa7522bbc8bda13 100644 --- a/aleksis/apps/alsijil/migrations/0023_add_tardiness_and_rework_constraints.py +++ b/aleksis/apps/alsijil/migrations/0023_add_tardiness_and_rework_constraints.py @@ -1,25 +1,9 @@ -# Generated by Django 4.2.10 on 2024-06-18 09:44 +# Generated by Django 4.2.10 on 2024-07-01 13:44 # Updated for more custom logic from django.db import migrations, models -def forwards__one_value_per_note(apps, schema_editor): - # We get the model from the versioned app registry; - # if we directly import it, it'll be the wrong version - NewPersonalNote = apps.get_model("alsijil", "NewPersonalNote") # noqa - db_alias = schema_editor.connection.alias - - NewPersonalNote.objects.using(db_alias).filter(note="").update(note=None) - - -def reverse__one_value_per_note(apps, schema_editor): - NewPersonalNote = apps.get_model("alsijil", "NewPersonalNote") # noqa - db_alias = schema_editor.connection.alias - - NewPersonalNote.objects.using(db_alias).filter(note=None).update(note="") - - def forwards__unique_extra_mark_documentation(apps, schema_editor): NewPersonalNote = apps.get_model("alsijil", "NewPersonalNote") # noqa db_alias = schema_editor.connection.alias @@ -39,10 +23,12 @@ def forwards__unique_extra_mark_documentation(apps, schema_editor): )[1:] NewPersonalNote.objects.using(db_alias).filter(pk__in=pks).delete() + def reverse__unique_extra_mark_documentation(apps, schema_editor): # Nothing to do, we cannot bring back the deleted objects, but they were duplicate data, so they are not needed anyway. pass + class Migration(migrations.Migration): dependencies = [ ('alsijil', '0022_documentation_participation_touched_at'), @@ -54,35 +40,20 @@ class Migration(migrations.Migration): name='unique_absence_per_documentation', ), migrations.AddField( - model_name='newpersonalnote', + model_name='participationstatus', name='tardiness', field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Tardiness'), ), migrations.AlterField( model_name='newpersonalnote', name='note', - field=models.TextField(blank=True, null=True, verbose_name='Note'), + field=models.TextField(blank=True, default='', verbose_name='Note'), ), - migrations.RunPython(forwards__one_value_per_note, reverse__one_value_per_note), migrations.AddConstraint( model_name='newpersonalnote', constraint=models.CheckConstraint( - check=models.Q( - models.Q(('extra_mark__isnull', True), ('note__isnull', False), ('tardiness__isnull', True)), - models.Q(('extra_mark__isnull', False), ('note__isnull', True), ('tardiness__isnull', True)), - models.Q(('extra_mark__isnull', True), ('note__isnull', True), ('tardiness__isnull', False)), - _connector='OR' - ), - name='one_value_per_personal_note' - ), - ), - migrations.AddConstraint( - model_name='newpersonalnote', - constraint=models.UniqueConstraint( - condition=models.Q(('tardiness', None), _negated=True), - fields=('person', 'documentation'), - name='unique_person_documentation_tardiness' - ), + check=models.Q(models.Q(('note', ''), _negated=True), ('extra_mark__isnull', False), _connector='OR'), + name='either_note_or_extra_mark_per_note'), ), migrations.RunPython(forwards__unique_extra_mark_documentation, reverse__unique_extra_mark_documentation), migrations.AddConstraint( @@ -90,7 +61,7 @@ class Migration(migrations.Migration): constraint=models.UniqueConstraint( condition=models.Q(('extra_mark', None), _negated=True), fields=('person', 'documentation', 'extra_mark'), - name='unique_person_documentation_extra_mark' - ), + name='unique_person_documentation_extra_mark', + violation_error_message='A person got assigned the same extra mark multiple times per documentation.'), ), ] diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index 3c152000ff907b2689edc64fc9ebd9a9cc90a13b..9711b457207fefb10acefbc8e8ec1447e6f5e3d3 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -790,6 +790,8 @@ class ParticipationStatus(CalendarEvent): verbose_name=_("Base Absence"), ) + tardiness = models.PositiveSmallIntegerField(blank=True, null=True, verbose_name=_("Tardiness")) + def fill_from_kolego(self, kolego_absence: KolegoAbsence): """Take over data from a Kolego absence.""" self.base_absence = kolego_absence @@ -828,33 +830,27 @@ class NewPersonalNote(ExtensibleModel): null=True, ) - note = models.TextField(blank=True, null=True, verbose_name=_("Note")) + note = models.TextField(blank=True, default="", verbose_name=_("Note")) extra_mark = models.ForeignKey( ExtraMark, on_delete=models.PROTECT, blank=True, null=True, verbose_name=_("Extra Mark") ) - tardiness = models.PositiveSmallIntegerField(blank=True, null=True, verbose_name=_("Tardiness")) def __str__(self) -> str: - return f"{self.person}, {self.note}, {self.extra_mark}, {self.tardiness}" + return f"{self.person}, {self.note}, {self.extra_mark}" class Meta: verbose_name = _("Personal Note") verbose_name_plural = _("Personal Notes") constraints = [ + # This constraint could be dropped in future scenarios models.CheckConstraint( - check=Q(note__isnull=False, extra_mark__isnull=True, tardiness__isnull=True) - | Q(note__isnull=True, extra_mark__isnull=False, tardiness__isnull=True) - | Q(note__isnull=True, extra_mark__isnull=True, tardiness__isnull=False), - name="one_value_per_personal_note", - ), - models.UniqueConstraint( - fields=["person", "documentation"], - name="unique_person_documentation_tardiness", - condition=~Q(tardiness=None), + check=~Q(note="") | Q(extra_mark__isnull=False), + name="either_note_or_extra_mark_per_note", ), models.UniqueConstraint( fields=["person", "documentation", "extra_mark"], name="unique_person_documentation_extra_mark", + violation_error_message=_("A person got assigned the same extra mark multiple times per documentation."), condition=~Q(extra_mark=None), ), ]