From c9e4be8360500425e04289d80b65c61eb53f10fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?=
 <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de>
Date: Sat, 21 May 2022 10:35:07 +0200
Subject: [PATCH 1/2] Make sure post_save signal is sent after update of
 availabilities

Manually trigger post_save signal after bulk create of replacing availabilities
This fixes #132
---
 AKModel/availability/forms.py | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/AKModel/availability/forms.py b/AKModel/availability/forms.py
index 3c68c56b..c99ca202 100644
--- a/AKModel/availability/forms.py
+++ b/AKModel/availability/forms.py
@@ -7,6 +7,7 @@ import json
 
 from django import forms
 from django.db import transaction
+from django.db.models.signals import post_save
 from django.utils.dateparse import parse_datetime
 from django.utils.translation import gettext_lazy as _
 
@@ -142,11 +143,16 @@ class AvailabilitiesFormMixin(forms.Form):
         for avail in availabilities:
             setattr(avail, reference_name, instance.id)
 
-    def _replace_availabilities(self, instance, availabilities):
+    def _replace_availabilities(self, instance, availabilities: [Availability]):
         with transaction.atomic():
             # TODO: do not recreate objects unnecessarily, give the client the IDs, so we can track modifications and leave unchanged objects alone
             instance.availabilities.all().delete()
             Availability.objects.bulk_create(availabilities)
+            # Trigger post save signal manually to make sure constraints are updated accordingly
+            # Doing this one time is sufficient, since this will nevertheless update all availability constraint
+            # violations of the corresponding AK
+            if len(availabilities) > 0:
+                post_save.send(Availability, instance=availabilities[0], created=True)
 
     def save(self, *args, **kwargs):
         instance = super().save(*args, **kwargs)
-- 
GitLab


From 8b5ffde825c870e1a9e676924085d69be48e512d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?=
 <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de>
Date: Sat, 21 May 2022 11:29:32 +0200
Subject: [PATCH 2/2] Update/delete constraint violations when corresponding
 slot is deleted

This fixes #131
---
 AKScheduling/models.py | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/AKScheduling/models.py b/AKScheduling/models.py
index bfdb1e16..cabf78e1 100644
--- a/AKScheduling/models.py
+++ b/AKScheduling/models.py
@@ -1,4 +1,4 @@
-from django.db.models.signals import post_save, m2m_changed
+from django.db.models.signals import post_save, m2m_changed, pre_delete
 from django.dispatch import receiver
 from django.utils.translation import gettext_lazy as _
 
@@ -551,6 +551,19 @@ def akslot_changed_handler(sender, instance: AKSlot, **kwargs):
     update_constraint_violations(new_violations, existing_violations_to_check)
 
 
+@receiver(pre_delete, sender=AKSlot)
+def akslot_deleted_handler(sender, instance: AKSlot, **kwargs):
+    # Manually clean up or remove constraint violations that belong to this slot since there is no cascade deletion
+    # for many2many relationships. Explicitly listening for AK deletion signals is not necessary since they will
+    # transitively trigger this signal and we always set both AK and AKSlot references in a constraint violation
+    print(f"{instance} deleted")
+
+    for cv in instance.constraintviolation_set.all():
+        # Make sure not delete CVs that e.g., show three parallel slots in a single room
+        if cv.ak_slots.count() <= 2:
+            cv.delete()
+
+
 @receiver(post_save, sender=Room)
 def room_changed_handler(sender, instance: Room, **kwargs):
     # Changes might affect: Room size
-- 
GitLab