Skip to content
Snippets Groups Projects
models.py 3.1 KiB
Newer Older
from django.db.models.signals import post_save
from django.dispatch import receiver

from AKModel.availability.models import Availability
from AKModel.models import AK, AKSlot, Room, Event, AKOwner, ConstraintViolation


@receiver(post_save, sender=AK)
def ak_changed_handler(sender, instance: AK, **kwargs):
    # Changes might affect: Owner(s), Requirements, Conflicts, Prerequisites, Category, Interest
    print(f"{instance} changed")

    event = instance.event

    # Owner might have changed: Might affect multiple AKs by the same owner at the same time
    conflicts = []
    type = ConstraintViolation.ViolationType.OWNER_TWO_SLOTS
    # For all owners...
    for owner in instance.owners.all():
        # ...find overlapping AKs...
        slots_by_owner : [AKSlot] = []
        slots_by_owner_this_ak : [AKSlot] = []
        aks_by_owner = owner.ak_set.all()
        for ak in aks_by_owner:
            if ak != instance:
                slots_by_owner.extend(ak.akslot_set.filter(start__isnull=False))
            else:
                # ToDo Fill this outside of loop?
                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:
                if slot.overlaps(other_slot):
                    # TODO Create ConstraintViolation here
                    c = ConstraintViolation(
                        type=type,
                        level=ConstraintViolation.ViolationLevel.VIOLATION,
                        event=event,
                        ak_owner=owner
                    )
                    c.aks_tmp.add(instance)
                    c.aks_tmp.add(other_slot.ak)
                    c.ak_slots_tmp.add(slot)
                    c.ak_slots_tmp.add(other_slot)
                    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)
    for conflict in conflicts:
        pass
        # TODO Remove from list of current_violations if an equal new one is found
        # TODO Otherwise, store this conflict in db
    # TODO Remove all violations still in current_violations


@receiver(post_save, sender=AKSlot)
def akslot_changed_handler(sender, instance, **kwargs):
    # Changes might affect: Duplicate parallel, Two in room
    print(f"{sender} changed")
    # TODO Replace with real handling


@receiver(post_save, sender=Room)
def room_changed_handler(sender, **kwargs):
    # Changes might affect: Room size, Requirement
    print(f"{sender} changed")
    # TODO Replace with real handling


@receiver(post_save, sender=Availability)
def availability_changed_handler(sender, **kwargs):
    # Changes might affect: category availability, AK availability, Room availability
    print(f"{sender} changed")
    # TODO Replace with real handling


@receiver(post_save, sender=Event)
def room_changed_handler(sender, **kwargs):
    # Changes might affect: Reso-Deadline
    print(f"{sender} changed")
    # TODO Replace with real handling