diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py
index 09024eae5eab9a692adac8ea8e0bc085bcf8b4e1..8b5a17af9086e65b12abbb2cc734cf033a7a4a89 100644
--- a/aleksis/apps/alsijil/model_extensions.py
+++ b/aleksis/apps/alsijil/model_extensions.py
@@ -9,13 +9,22 @@ from django.utils.translation import gettext as _
 
 from calendarweek import CalendarWeek
 
+from aleksis.apps.alsijil.managers import PersonalNoteQuerySet
 from aleksis.apps.chronos.models import Event, ExtraLesson, LessonPeriod
 from aleksis.core.models import Group, Person
 
 from .models import ExcuseType, ExtraMark, LessonDocumentation, PersonalNote
 
 
-def alsijil_url(self, week: Optional[CalendarWeek] = None):
+def alsijil_url(
+    self: Union[LessonPeriod, Event, ExtraLesson], week: Optional[CalendarWeek] = None
+) -> str:
+    """Build URL for the detail page of register objects.
+
+    Works with `LessonPeriod`, `Event` and `ExtraLesson`.
+
+    On `LessonPeriod` objects, it will work with annotated or passed weeks.
+    """
     if isinstance(self, LessonPeriod):
         week = week or self.week
         return reverse("lesson_period", args=[week.year, week.week, self.pk])
@@ -45,8 +54,8 @@ def mark_absent(
 ):
     """Mark a person absent for all lessons in a day, optionally starting with a selected period number.
 
-    This function creates `PersonalNote` objects for every `LessonPeriod` the person
-    participates in on the selected day and marks them as absent/excused.
+    This function creates `PersonalNote` objects for every `LessonPeriod` and `ExtraLesson`
+    the person participates in on the selected day and marks them as absent/excused.
 
     :param dry_run: With this activated, the function won't change any data
         and just return the count of affected lessons
@@ -115,10 +124,15 @@ def mark_absent(
     return lesson_periods.count() + extra_lessons.count()
 
 
-def get_personal_notes(self, persons: QuerySet, wanted_week: Optional[CalendarWeek] = None):
-    """Get all personal notes for that lesson in a specified week.
+def get_personal_notes(
+    self, persons: QuerySet, wanted_week: Optional[CalendarWeek] = None
+) -> PersonalNoteQuerySet:
+    """Get all personal notes for that register object in a specified week.
+
+    The week is optional for extra lessons and events as they have own date information.
 
-    Returns all linked `PersonalNote` objects, filtered by the given weeek,
+    Returns all linked `PersonalNote` objects,
+    filtered by the given week for `LessonPeriod` objects,
     creating those objects that haven't been created yet.
 
     ..note:: Only available when AlekSIS-App-Alsijil is installed.
@@ -253,7 +267,7 @@ def get_absences(self, week: Optional[CalendarWeek] = None) -> Iterator:
     )
 
 
-def get_absences_simple(self, week: Optional[CalendarWeek] = None) -> Iterator:
+def get_absences_simple(self, week: Optional[CalendarWeek] = None) -> PersonalNoteQuerySet:
     """Get all personal notes of absent persons for this event/extra lesson."""
     return self.personal_notes.all()
 
diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index 726bc3e7aaf60c950fe7f5cbc94f163e680821a6..016252970583907dab576fe8ccb1458c6575c9b8 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -88,8 +88,13 @@ lesson_related_constraint_q = (
 
 
 class RegisterObjectRelatedMixin(WeekRelatedMixin):
+    """Mixin with common API for lesson documentations and personal notes."""
+
     @property
-    def register_object(self) -> Union[LessonPeriod, Event, ExtraLesson]:
+    def register_object(
+        self: Union["LessonDocumentation", "PersonalNote"]
+    ) -> Union[LessonPeriod, Event, ExtraLesson]:
+        """Get the object related to this lesson documentation or personal note."""
         if self.lesson_period:
             return self.lesson_period
         elif self.event:
@@ -98,23 +103,38 @@ class RegisterObjectRelatedMixin(WeekRelatedMixin):
             return self.extra_lesson
 
     @property
-    def calendar_week(self) -> CalendarWeek:
+    def calendar_week(self: Union["LessonDocumentation", "PersonalNote"]) -> CalendarWeek:
+        """Get the calendar week of this lesson documentation or personal note.
+
+        .. note::
+
+            As events can be longer than one week,
+            this will return the week of the start date for events.
+        """
         if self.lesson_period:
-            return CalendarWeek(week=self.week, year=self.year,)
+            return CalendarWeek(week=self.week, year=self.year)
         elif self.extra_lesson:
             return self.extra_lesson.calendar_week
         else:
             return CalendarWeek.from_date(self.register_object.date_start)
 
     @property
-    def school_term(self) -> SchoolTerm:
+    def school_term(self: Union["LessonDocumentation", "PersonalNote"]) -> SchoolTerm:
+        """Get the school term of the related register object."""
         if self.lesson_period:
             return self.lesson_period.lesson.validity.school_term
         else:
             return self.register_object.school_term
 
     @property
-    def date(self) -> Optional[date]:
+    def date(self: Union["LessonDocumentation", "PersonalNote"]) -> Optional[date]:
+        """Get the date of this lesson documentation or personal note.
+
+        :: warning::
+
+            As events can be longer than one day,
+            this will return `None` for events.
+        """
         if self.lesson_period:
             return super().date
         elif self.extra_lesson:
@@ -122,14 +142,20 @@ class RegisterObjectRelatedMixin(WeekRelatedMixin):
         return None
 
     @property
-    def date_formatted(self) -> str:
+    def date_formatted(self: Union["LessonDocumentation", "PersonalNote"]) -> str:
+        """Get a formatted version of the date of this object.
+
+        Lesson periods, extra lessons: formatted date
+        Events: formatted date range
+        """
         return (
             date_format(self.date)
             if self.date
-            else f"{self.event.date_start}–{self.event.date_end}"
+            else f"{date_format(self.event.date_start)}–{date_format(self.event.date_end)}"
         )
 
-    def get_absolute_url(self) -> str:
+    def get_absolute_url(self: Union["LessonDocumentation", "PersonalNote"]) -> str:
+        """Get the absolute url of the detail view for the related register object."""
         return self.register_object.get_alsijil_url(self.calendar_week)
 
 
@@ -204,6 +230,7 @@ class PersonalNote(RegisterObjectRelatedMixin, ExtensibleModel):
         return f"{self.date_formatted}, {self.lesson_period}, {self.person}"
 
     def get_absolute_url(self) -> str:
+        """Get the absolute url of the detail view for the related register object."""
         return super().get_absolute_url() + "#personal-notes"
 
     class Meta:
@@ -283,7 +310,7 @@ class LessonDocumentation(RegisterObjectRelatedMixin, ExtensibleModel):
             if changed:
                 lesson_documentation.save()
 
-    def __str__(self):
+    def __str__(self) -> str:
         return f"{self.lesson_period}, {self.date_formatted}"
 
     def save(self, *args, **kwargs):
diff --git a/aleksis/apps/alsijil/util/alsijil_helpers.py b/aleksis/apps/alsijil/util/alsijil_helpers.py
index 1ad17814238fcd0f76ea726245194954bcd103c4..34d9ff4a3b37b09fadf6e01813b2f43cde4742d7 100644
--- a/aleksis/apps/alsijil/util/alsijil_helpers.py
+++ b/aleksis/apps/alsijil/util/alsijil_helpers.py
@@ -58,7 +58,7 @@ def get_timetable_instance_by_pk(
 def annotate_documentations(
     klass: Union[Event, LessonPeriod, ExtraLesson], wanted_week: CalendarWeek, pks: List[int]
 ) -> QuerySet:
-
+    """Return a annotated queryset of all provided register objects."""
     if isinstance(klass, LessonPeriod):
         prefetch = Prefetch(
             "documentations",