diff --git a/AKModel/models.py b/AKModel/models.py index 5a257cd56d25ceb187f7d4337395d87ae6638ae5..510777d851247d27ddfab5bf77ada5f117b6791b 100644 --- a/AKModel/models.py +++ b/AKModel/models.py @@ -425,7 +425,6 @@ class ConstraintViolation(models.Model): return ", ".join(output) get_details.short_description = _('Details') - # TODO Automatically save this aks_tmp = set() @property def _aks(self): @@ -459,9 +458,31 @@ class ConstraintViolation(models.Model): return set(self.ak_slots.all()) return self.ak_slots_tmp + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + # Store temporary m2m-relations in db + for ak in self.aks_tmp: + self.aks.add(ak) + for ak_slot in self.ak_slots_tmp: + self.ak_slots.add(ak_slot) + def __str__(self): return f"{self.get_level_display()}: {self.get_type_display()} [{self.get_details()}]" def __eq__(self, other): - # TODO Check if FIELDS and FIELDS_MM are equal - return super().__eq__(other) + if not isinstance(other, ConstraintViolation): + return False + if self.type != other.type: + return False + for field_mm in self.FIELDS_MM: + s: set = getattr(self, field_mm) + o: set = getattr(other, field_mm) + if len(s) != len(o): + return False + if len(s.intersection(o)) != len(s): + return False + for field in self.FIELDS: + if getattr(self, field) != getattr(other, field): + return False + return True + diff --git a/AKScheduling/models.py b/AKScheduling/models.py index 990bcd4a74b6efebdc865830abd5cafb8600ae21..ae3bf51af4a3dbc010b6871f6723e9c895025117 100644 --- a/AKScheduling/models.py +++ b/AKScheduling/models.py @@ -14,7 +14,7 @@ def ak_changed_handler(sender, instance: AK, **kwargs): # Owner might have changed: Might affect multiple AKs by the same owner at the same time conflicts = [] - type = ConstraintViolation.ViolationType.OWNER_TWO_SLOTS + violation_type = ConstraintViolation.ViolationType.OWNER_TWO_SLOTS # For all owners... for owner in instance.owners.all(): # ...find overlapping AKs... @@ -30,9 +30,8 @@ def ak_changed_handler(sender, instance: AK, **kwargs): for slot in slots_by_owner_this_ak: for other_slot in slots_by_owner: if slot.overlaps(other_slot): - # TODO Create ConstraintViolation here c = ConstraintViolation( - type=type, + type=violation_type, level=ConstraintViolation.ViolationLevel.VIOLATION, event=event, ak_owner=owner @@ -44,12 +43,26 @@ def ak_changed_handler(sender, instance: AK, **kwargs): conflicts.append(c) print(f"{owner} has the following conflicts: {conflicts}") # ... and compare to/update list of existing violations of this type: - current_violations = instance.constraintviolation_set.filter(type=type) + current_violations = list(instance.constraintviolation_set.filter(type=violation_type)) + print(current_violations) for conflict in conflicts: - pass + # eq_violation_index = -1 + try: + current_violations.remove(conflict) + print(f"Found existing conflict {conflict}") + except ValueError: + conflict.save() + """for i, other_violation in enumerate(current_violations): + if conflict == other_violation: + eq_violation_index = i + break + if eq_violation_index > -1:""" # TODO Remove from list of current_violations if an equal new one is found # TODO Otherwise, store this conflict in db + # conflict.save() # TODO Remove all violations still in current_violations + for old_violation in current_violations: + old_violation.delete() @receiver(post_save, sender=AKSlot)