Skip to content
Snippets Groups Projects
Commit e64492e4 authored by Benjamin Hättasch's avatar Benjamin Hättasch
Browse files

WIP: Implement first version for OWNER_TWO_SLOTS violation check

parent 675503a2
No related branches found
No related tags found
No related merge requests found
...@@ -472,6 +472,7 @@ class ConstraintViolation(models.Model): ...@@ -472,6 +472,7 @@ class ConstraintViolation(models.Model):
:rtype: str :rtype: str
""" """
output = [] output = []
"""
# Stringify all ManyToMany fields # Stringify all ManyToMany fields
for field_mm in self.fields_mm: for field_mm in self.fields_mm:
output.append(f"{field_mm}: {', '.join(str(a) for a in getattr(self, field_mm).all())}") output.append(f"{field_mm}: {', '.join(str(a) for a in getattr(self, field_mm).all())}")
...@@ -480,6 +481,7 @@ class ConstraintViolation(models.Model): ...@@ -480,6 +481,7 @@ class ConstraintViolation(models.Model):
a = getattr(self, field, None) a = getattr(self, field, None)
if a is not None: if a is not None:
output.append(f"{field}: {a}") output.append(f"{field}: {a}")
"""
return ", ".join(output) return ", ".join(output)
get_details.short_description = _('Details') get_details.short_description = _('Details')
...@@ -536,9 +538,31 @@ class ConstraintViolation(models.Model): ...@@ -536,9 +538,31 @@ class ConstraintViolation(models.Model):
return set(self.ak_slots.all()) return set(self.ak_slots.all())
return self.ak_slots_tmp 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): def __str__(self):
return f"{self.get_level_display()}: {self.get_type_display()} [{self.get_details()}]" return f"{self.get_level_display()}: {self.get_type_display()} [{self.get_details()}]"
def __eq__(self, other): def __eq__(self, other):
# TODO Check if FIELDS and FIELDS_MM are equal if not isinstance(other, ConstraintViolation):
return super().__eq__(other) 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
...@@ -14,25 +14,26 @@ def ak_changed_handler(sender, instance: AK, **kwargs): ...@@ -14,25 +14,26 @@ def ak_changed_handler(sender, instance: AK, **kwargs):
# Owner might have changed: Might affect multiple AKs by the same owner at the same time # Owner might have changed: Might affect multiple AKs by the same owner at the same time
conflicts = [] conflicts = []
type = ConstraintViolation.ViolationType.OWNER_TWO_SLOTS violation_type = ConstraintViolation.ViolationType.OWNER_TWO_SLOTS
slots_of_this_ak: [AKSlot] = instance.akslot_set.filter(start__isnull=False)
# For all owners... # For all owners...
for owner in instance.owners.all(): for owner in instance.owners.all():
# ...find overlapping AKs... # ...find overlapping AKs...
slots_by_owner : [AKSlot] = [] slots_by_owner: [AKSlot] = []
slots_by_owner_this_ak : [AKSlot] = []
aks_by_owner = owner.ak_set.all() aks_by_owner = owner.ak_set.all()
for ak in aks_by_owner: for ak in aks_by_owner:
if ak != instance: if ak != instance:
slots_by_owner.extend(ak.akslot_set.filter(start__isnull=False)) slots_by_owner.extend(ak.akslot_set.filter(start__isnull=False))
else:
# ToDo Fill this outside of loop? for slot in slots_of_this_ak:
slots_by_owner_this_ak.extend(ak.akslot_set.filter(start__isnull=False))
for slot in slots_by_owner_this_ak:
for other_slot in slots_by_owner: for other_slot in slots_by_owner:
if slot.overlaps(other_slot): if slot.overlaps(other_slot):
# TODO Create ConstraintViolation here
c = ConstraintViolation( c = ConstraintViolation(
type=type, type=violation_type,
level=ConstraintViolation.ViolationLevel.VIOLATION, level=ConstraintViolation.ViolationLevel.VIOLATION,
event=event, event=event,
ak_owner=owner ak_owner=owner
...@@ -44,17 +45,31 @@ def ak_changed_handler(sender, instance: AK, **kwargs): ...@@ -44,17 +45,31 @@ def ak_changed_handler(sender, instance: AK, **kwargs):
conflicts.append(c) conflicts.append(c)
print(f"{owner} has the following conflicts: {conflicts}") print(f"{owner} has the following conflicts: {conflicts}")
# ... and compare to/update list of existing violations of this type: # ... 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: 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 Remove from list of current_violations if an equal new one is found
# TODO Otherwise, store this conflict in db # TODO Otherwise, store this conflict in db
# conflict.save()
# TODO Remove all violations still in current_violations # TODO Remove all violations still in current_violations
for outdated_violation in current_violations:
outdated_violation.delete()
@receiver(post_save, sender=AKSlot) @receiver(post_save, sender=AKSlot)
def akslot_changed_handler(sender, instance, **kwargs): def akslot_changed_handler(sender, instance, **kwargs):
# Changes might affect: Duplicate parallel, Two in room # Changes might affect: Duplicate parallel, Two in room, Resodeadline
print(f"{sender} changed") print(f"{sender} changed")
# TODO Replace with real handling # TODO Replace with real handling
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment