Skip to content
Snippets Groups Projects
Verified Commit ecb5a981 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Add recurrence builder for usage in importer etc.

parent ed59d880
No related branches found
No related tags found
1 merge request!32Recurrence builder
Pipeline #179147 passed with warnings
...@@ -3,8 +3,8 @@ include: ...@@ -3,8 +3,8 @@ include:
file: /ci/general.yml file: /ci/general.yml
- project: "AlekSIS/official/AlekSIS" - project: "AlekSIS/official/AlekSIS"
file: /ci/prepare/lock.yml file: /ci/prepare/lock.yml
# - project: "AlekSIS/official/AlekSIS" - project: "AlekSIS/official/AlekSIS"
# file: /ci/test.yml file: /ci/test/test.yml
- project: "AlekSIS/official/AlekSIS" - project: "AlekSIS/official/AlekSIS"
file: /ci/test/lint.yml file: /ci/test/lint.yml
- project: "AlekSIS/official/AlekSIS" - project: "AlekSIS/official/AlekSIS"
......
...@@ -211,6 +211,24 @@ class Slot(ExtensiblePolymorphicModel): ...@@ -211,6 +211,24 @@ class Slot(ExtensiblePolymorphicModel):
def get_last_datetime(self) -> datetime: def get_last_datetime(self) -> datetime:
return self.get_datetime_end(self.time_grid.validity_range.date_end) return self.get_datetime_end(self.time_grid.validity_range.date_end)
def build_recurrence(self, *args, **kwargs) -> recurrence.Recurrence:
"""Build a recurrence for this slot respecting the validity range borders."""
pattern = recurrence.Recurrence(
dtstart=timezone.make_aware(
datetime.combine(self.time_grid.validity_range.date_start, self.time_start)
),
rrules=[
recurrence.Rule(
*args,
**kwargs,
until=timezone.make_aware(
datetime.combine(self.time_grid.validity_range.date_end, self.time_end)
),
)
],
)
return pattern
class Meta: class Meta:
constraints = [ constraints = [
models.UniqueConstraint( models.UniqueConstraint(
...@@ -305,6 +323,10 @@ class Lesson(TeacherPropertiesMixin, RoomPropertiesMixin, ExtensibleModel): ...@@ -305,6 +323,10 @@ class Lesson(TeacherPropertiesMixin, RoomPropertiesMixin, ExtensibleModel):
if self.slot_start.time_grid != self.slot_end.time_grid: if self.slot_start.time_grid != self.slot_end.time_grid:
raise ValidationError(_("The slots must be in the same time grid.")) raise ValidationError(_("The slots must be in the same time grid."))
def build_recurrence(self, *args, **kwargs) -> "recurrence.Recurrence":
"""Build a recurrence for this lesson respecting the validity range borders."""
return self.slot_start.build_recurrence(*args, **kwargs)
@property @property
def real_recurrence(self) -> "recurrence.Recurrence": def real_recurrence(self) -> "recurrence.Recurrence":
"""Get the real recurrence adjusted to the validity range and including holidays.""" """Get the real recurrence adjusted to the validity range and including holidays."""
...@@ -431,6 +453,10 @@ class Supervision(TeacherPropertiesMixin, RoomPropertiesMixin, ExtensibleModel): ...@@ -431,6 +453,10 @@ class Supervision(TeacherPropertiesMixin, RoomPropertiesMixin, ExtensibleModel):
verbose_name = _("Supervision") verbose_name = _("Supervision")
verbose_name_plural = _("Supervisions") verbose_name_plural = _("Supervisions")
def build_recurrence(self, *args, **kwargs) -> "recurrence.Recurrence":
"""Build a recurrence for this supervision respecting the validity range borders."""
return self.break_slot.build_recurrence(*args, **kwargs)
@property @property
def real_recurrence(self) -> "recurrence.Recurrence": def real_recurrence(self) -> "recurrence.Recurrence":
"""Get the real recurrence adjusted to the validity range and including holidays.""" """Get the real recurrence adjusted to the validity range and including holidays."""
......
from datetime import date, datetime, time
from pprint import pprint
from django.utils.timezone import get_current_timezone
import pytest
import recurrence
from aleksis.apps.lesrooster.models import (
BreakSlot,
Lesson,
Slot,
Supervision,
TimeGrid,
ValidityRange,
)
from aleksis.core.models import SchoolTerm
pytestmark = pytest.mark.django_db
@pytest.fixture
def school_term():
date_start = date(2024, 1, 1)
date_end = date(2024, 6, 1)
school_term = SchoolTerm.objects.create(name="Test", date_start=date_start, date_end=date_end)
return school_term
@pytest.fixture
def validity_range(school_term):
validity_range = ValidityRange.objects.create(
school_term=school_term, date_start=school_term.date_start, date_end=school_term.date_end
)
return validity_range
@pytest.fixture
def time_grid(validity_range):
return TimeGrid.objects.get(validity_range=validity_range, group=None)
def test_slot_build_recurrence(time_grid):
slot = Slot.objects.create(
time_grid=time_grid, weekday=0, period=1, time_start=time(8, 0), time_end=time(9, 0)
)
rec = slot.build_recurrence(recurrence.WEEKLY)
pprint(rec.rrules[0].__dict__)
assert rec.dtstart == datetime(2024, 1, 1, 8, 0, tzinfo=get_current_timezone())
assert len(rec.rrules) == 1
rrule = rec.rrules[0]
assert rrule.until == datetime(2024, 6, 1, 9, 0, tzinfo=get_current_timezone())
assert rrule.freq == 2
assert rrule.interval == 1
def test_lesson_recurrence(time_grid):
slot = Slot.objects.create(
time_grid=time_grid, weekday=0, period=1, time_start=time(8, 0), time_end=time(9, 0)
)
break_slot = BreakSlot.objects.create(
time_grid=time_grid, weekday=0, time_start=time(9, 0), time_end=time(9, 15)
)
lesson = Lesson.objects.create(
slot_start=slot,
slot_end=slot,
)
assert lesson.build_recurrence(recurrence.WEEKLY) == slot.build_recurrence(recurrence.WEEKLY)
supervision = Supervision.objects.create(break_slot=break_slot)
assert supervision.build_recurrence(recurrence.WEEKLY) == break_slot.build_recurrence(
recurrence.WEEKLY
)
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