From 3dedddbfafb3b7c6aad0e73c642d65efdf841b48 Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Mon, 22 Jun 2020 11:37:57 +0200
Subject: [PATCH] Add better options to get previous or next lesson period

- Add properties to LessonPeriod model
- Also annotate year while annotating a week
- Fix use of negative indexes in next_lesson
---
 aleksis/apps/chronos/managers.py | 14 +++++++++-----
 aleksis/apps/chronos/models.py   | 29 +++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py
index 0e956705..361f8da2 100644
--- a/aleksis/apps/chronos/managers.py
+++ b/aleksis/apps/chronos/managers.py
@@ -64,12 +64,13 @@ class LessonSubstitutionManager(CurrentSiteManager):
 class WeekQuerySetMixin:
     def annotate_week(self, week: Union[CalendarWeek, int]):
         """Annotate all lessons in the QuerySet with the number of the provided calendar week."""
-        if isinstance(week, CalendarWeek):
-            week_num = week.week
-        else:
-            week_num = week
+        if isinstance(week, int):
+            week = CalendarWeek(week=week)
 
-        return self.annotate(_week=models.Value(week_num, models.IntegerField()))
+        return self.annotate(
+            _week=models.Value(week.week, models.IntegerField()),
+            _year=models.Value(week.year, models.IntegerField())
+        )
 
 
 class GroupByPeriodsMixin:
@@ -236,6 +237,9 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin):
         if next_index > self.count() - 1:
             next_index %= self.count()
             week = reference._week + 1
+        elif next_index < 0:
+            next_index = self.count() + next_index
+            week = reference._week - 1
         else:
             week = reference._week
 
diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py
index a7a54e9a..b49a255c 100644
--- a/aleksis/apps/chronos/models.py
+++ b/aleksis/apps/chronos/models.py
@@ -321,6 +321,35 @@ class LessonPeriod(ExtensibleModel):
     def __str__(self) -> str:
         return f"{self.period}, {self.lesson}"
 
+    @property
+    def next(self) -> "LessonPeriod":
+        """Get next lesson period of this lesson.
+
+        .. warning::
+            To use this property a week had to be annotated to the provided lesson period.
+        """
+        return LessonPeriod.objects.filter(lesson=self.lesson).next_lesson(self)
+
+    @property
+    def prev(self) -> "LessonPeriod":
+        """Get previous lesson period of this lesson.
+
+        .. warning::
+            To use this property a week had to be annotated to the provided lesson period.
+        """
+        return LessonPeriod.objects.filter(lesson=self.lesson).next_lesson(self, -1)
+
+    @property
+    def week(self) -> Union[CalendarWeek, None]:
+        """Get annotated week as `CalendarWeek`.
+
+        Defaults to `None` if no week is annotated.
+        """
+        if hasattr(self, "_week"):
+            return CalendarWeek(week=self._week, year=self._year)
+        else:
+            return None
+
     class Meta:
         ordering = [
             "lesson__date_start",
-- 
GitLab