Skip to content
Snippets Groups Projects
Commit eec6035e authored by Lorenzo Conti's avatar Lorenzo Conti
Browse files

Merge branch 'main' into 'feature/ak-conflict-dependency'

# Conflicts:
#   AKModel/models.py
parents ba533efa bb1179c7
No related branches found
No related tags found
2 merge requests!17Add view to clear schedule,!9Implement export of AK conflicts and dependencies
Pipeline #269214 passed
This commit is part of merge request !9. Comments created here will be created in the context of that merge request.
import decimal
import itertools
import json
import math
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Iterable, Generator
......@@ -382,6 +384,23 @@ class Event(models.Model):
constraints=category_constraints,
)
def discretize_timeslots(self, *, slots_in_an_hour: float = 1.0) -> Iterable[TimeslotBlock]:
""""Choose discretization scheme.
Uses default_time_slots if the event has any DefaultSlot, otherwise uniform_time_slots.
:param slots_in_an_hour: The percentage of an hour covered by a single slot.
Determines the discretization granularity.
:yield: Block of optimizer timeslots as the discretization result.
:ytype: list of TimeslotBlock
"""
if DefaultSlot.objects.filter(event=self).exists():
# discretize default slots if they exists
yield from merge_blocks(self.default_time_slots(slots_in_an_hour=slots_in_an_hour))
else:
yield from self.uniform_time_slots(slots_in_an_hour=slots_in_an_hour)
def schedule_from_json(self, schedule: str) -> None:
"""Load AK schedule from a json string.
......@@ -396,7 +415,7 @@ class Event(models.Model):
timeslot_dict = {
timeslot.idx: timeslot
for block in merge_blocks(self.default_time_slots(slots_in_an_hour=slots_in_an_hour))
for block in self.discretize_timeslots(slots_in_an_hour=slots_in_an_hour)
for timeslot in block
}
......@@ -937,14 +956,17 @@ class AKSlot(models.Model):
conflict_slots = AKSlot.objects.filter(ak__in=self.ak.conflicts.all())
dependency_slots = AKSlot.objects.filter(ak__in=self.ak.prerequisites.all())
ceil_offet_eps = decimal.Decimal(1e-4)
# self.slots_in_an_hour is set in AKJSONExportView
data = {
"id": str(self.pk),
"duration": round(self.duration * self.slots_in_an_hour),
"duration": math.ceil(self.duration * self.slots_in_an_hour - ceil_offet_eps),
"properties": {
"conflicts": [str(conflict.pk) for conflict in conflict_slots.all()],
"dependencies": [str(dep.pk) for dep in dependency_slots.all()],
},
"properties": {},
"room_constraints": [constraint.name
for constraint in self.ak.requirements.all()],
"time_constraints": ["resolution"] if self.ak.reso else [],
......@@ -954,6 +976,7 @@ class AKSlot(models.Model):
for owner in self.ak.owners.all()]),
"description": self.ak.description,
"reso": self.ak.reso,
"duration_in_hours": float(self.duration),
},
}
......
......@@ -9,7 +9,7 @@ from django.views.generic import ListView, DetailView
from AKModel.availability.models import Availability
from AKModel.metaviews.admin import AdminViewMixin, FilterByEventSlugMixin, EventSlugMixin, IntermediateAdminView, \
IntermediateAdminActionView
from AKModel.models import AKRequirement, AKSlot, DefaultSlot, Event, AKOrgaMessage, AK, Room, AKOwner, merge_blocks
from AKModel.models import AKRequirement, AKSlot, Event, AKOrgaMessage, AK, Room, AKOwner
class AKRequirementOverview(AdminViewMixin, FilterByEventSlugMixin, ListView):
......@@ -114,11 +114,7 @@ class AKJSONExportView(AdminViewMixin, FilterByEventSlugMixin, ListView):
if (values := AKSlot.objects.select_related().filter(ak__pk=ak_id, fixed=True)).exists()
}
if DefaultSlot.objects.filter(event=self.event).exists():
# discretize default slots if they exists
blocks = merge_blocks(self.event.default_time_slots(slots_in_an_hour=SLOTS_IN_AN_HOUR))
else:
blocks = self.event.uniform_time_slots(slots_in_an_hour=SLOTS_IN_AN_HOUR)
blocks = self.event.discretize_timeslots(slots_in_an_hour=SLOTS_IN_AN_HOUR)
for block in blocks:
current_block = []
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment