diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 86e88a880f855e8a9a0f7557085dcf42e20124a4..dcdec3c5956617ba23b75766c5d49aea6e9aed7a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -10,4 +10,4 @@ include:
     - project: "AlekSIS/official/AlekSIS"
       file: /ci/build/dist.yml
     - project: "AlekSIS/official/AlekSIS"
-      file: /ci/deploy/pypi.yml
+      file: /ci/publish/pypi.yml
diff --git a/aleksis/apps/alsijil/data_checks.py b/aleksis/apps/alsijil/data_checks.py
index be36446beaf9d1bfc2474df29242f47a23d9a1c8..864f019646411443605b0495075ba6acfb47219b 100644
--- a/aleksis/apps/alsijil/data_checks.py
+++ b/aleksis/apps/alsijil/data_checks.py
@@ -1,9 +1,6 @@
 import logging
 
 from django.db.models import F
-from django.db.models.expressions import ExpressionWrapper, Func, Value
-from django.db.models.fields import DateField
-from django.db.models.functions import Concat
 from django.db.models.query_utils import Q
 from django.utils.translation import gettext as _
 
@@ -92,15 +89,6 @@ class NoGroupsOfPersonsSetInPersonalNotesDataCheck(DataCheck):
             cls.register_result(note)
 
 
-weekday_to_date = ExpressionWrapper(
-    Func(
-        Concat(F("year"), F("week")), Value("IYYYIW"), output_field=DateField(), function="TO_DATE"
-    )
-    + F("lesson_period__period__weekday"),
-    output_field=DateField(),
-)
-
-
 class LessonDocumentationOnHolidaysDataCheck(DataCheck):
     """Checks for lesson documentation objects on holidays.
 
@@ -123,13 +111,11 @@ class LessonDocumentationOnHolidaysDataCheck(DataCheck):
 
         holidays = Holiday.objects.all()
 
-        documentations = LessonDocumentation.objects.not_empty().annotate(
-            actual_date=weekday_to_date
-        )
+        documentations = LessonDocumentation.objects.not_empty().annotate_date_range()
 
         q = Q()
         for holiday in holidays:
-            q = q | Q(actual_date__gte=holiday.date_start, actual_date__lte=holiday.date_end)
+            q = q | Q(day_end__gte=holiday.date_start, day_start__lte=holiday.date_end)
         documentations = documentations.filter(q)
 
         for doc in documentations:
@@ -159,11 +145,11 @@ class PersonalNoteOnHolidaysDataCheck(DataCheck):
 
         holidays = Holiday.objects.all()
 
-        personal_notes = PersonalNote.objects.not_empty().annotate(actual_date=weekday_to_date)
+        personal_notes = PersonalNote.objects.not_empty().annotate_date_range()
 
         q = Q()
         for holiday in holidays:
-            q = q | Q(actual_date__gte=holiday.date_start, actual_date__lte=holiday.date_end)
+            q = q | Q(day_end__gte=holiday.date_start, day_start__lte=holiday.date_end)
         personal_notes = personal_notes.filter(q)
 
         for note in personal_notes:
diff --git a/aleksis/apps/alsijil/managers.py b/aleksis/apps/alsijil/managers.py
index 862e33a6d6a1cf0c8893359a65cb9a8ea6440da5..4c7741d3b89620b1682532192acf7fb9ad1c0196 100644
--- a/aleksis/apps/alsijil/managers.py
+++ b/aleksis/apps/alsijil/managers.py
@@ -1,7 +1,9 @@
 from datetime import date, datetime
 from typing import Optional, Sequence, Union
 
-from django.db.models import QuerySet
+from django.db.models import Case, ExpressionWrapper, F, Func, QuerySet, Value, When
+from django.db.models.fields import DateField
+from django.db.models.functions import Concat
 from django.db.models.query import Prefetch
 from django.db.models.query_utils import Q
 
@@ -11,6 +13,65 @@ from aleksis.apps.chronos.managers import DateRangeQuerySetMixin
 from aleksis.core.managers import CurrentSiteManagerWithoutMigrations
 
 
+class RegisterObjectRelatedQuerySet(QuerySet):
+    """Common queryset for personal notes and lesson documentations with shared API."""
+
+    def _get_weekday_to_date(self, weekday_name, year_name="year", week_name="week"):
+        """Get a ORM function which converts a weekday, a week and a year to a date."""
+        return ExpressionWrapper(
+            Func(
+                Concat(F(year_name), F(week_name)),
+                Value("IYYYIW"),
+                output_field=DateField(),
+                function="TO_DATE",
+            )
+            + F(weekday_name),
+            output_field=DateField(),
+        )
+
+    def annotate_day(self) -> QuerySet:
+        """Annotate every personal note/lesson documentation with the real date.
+
+        Attribute name: ``day``
+
+        .. note::
+            For events, this will annotate ``None``.
+        """
+        return self.annotate(
+            day=Case(
+                When(
+                    lesson_period__isnull=False,
+                    then=self._get_weekday_to_date("lesson_period__period__weekday"),
+                ),
+                When(
+                    extra_lesson__isnull=False,
+                    then=self._get_weekday_to_date(
+                        "extra_lesson__period__weekday", "extra_lesson__year", "extra_lesson__week"
+                    ),
+                ),
+            )
+        )
+
+    def annotate_date_range(self) -> QuerySet:
+        """Annotate every personal note/lesson documentation with the real date.
+
+        Attribute names: ``day_start``, ``day_end``
+
+        .. note::
+            For lesson periods and extra lessons,
+            this will annotate the same date for start and end day.
+        """
+        return self.annotate_day().annotate(
+            day_start=Case(
+                When(day__isnull=False, then="day"),
+                When(day__isnull=True, then="event__date_start"),
+            ),
+            day_end=Case(
+                When(day__isnull=False, then="day"), When(day__isnull=True, then="event__date_end"),
+            ),
+        )
+
+
 class PersonalNoteManager(CurrentSiteManagerWithoutMigrations):
     """Manager adding specific methods to personal notes."""
 
@@ -33,7 +94,7 @@ class PersonalNoteManager(CurrentSiteManagerWithoutMigrations):
         )
 
 
-class PersonalNoteQuerySet(QuerySet):
+class PersonalNoteQuerySet(RegisterObjectRelatedQuerySet, QuerySet):
     def not_empty(self):
         """Get all not empty personal notes."""
         return self.filter(
@@ -45,7 +106,7 @@ class LessonDocumentationManager(CurrentSiteManagerWithoutMigrations):
     pass
 
 
-class LessonDocumentationQuerySet(QuerySet):
+class LessonDocumentationQuerySet(RegisterObjectRelatedQuerySet, QuerySet):
     def not_empty(self):
         """Get all not empty lesson documentations."""
         return self.filter(~Q(topic="") | ~Q(group_note="") | ~Q(homework=""))
diff --git a/aleksis/apps/alsijil/static/css/alsijil/full_register.css b/aleksis/apps/alsijil/static/css/alsijil/full_register.css
index 9a3dc493aa468c989ed766817436d20b40cd0bff..0584c12ee4e266f43fe8d34c8003d37d4a09815c 100644
--- a/aleksis/apps/alsijil/static/css/alsijil/full_register.css
+++ b/aleksis/apps/alsijil/static/css/alsijil/full_register.css
@@ -25,7 +25,7 @@ tr.lessons-day-first {
     border-top: 3px solid rgba(0, 0, 0, 0.3);
 }
 
-th.lessons-day-head, td.rotate, th.rotate {
+td.rotate, th.rotate {
     text-align: center;
     transform: rotate(-90deg);
 }
diff --git a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
index ca2d801d60cf9657be5378c38abf5903304a2ed7..3434853ae9af44ca86c8972c4f24a7b388d27acc 100644
--- a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
+++ b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
@@ -370,7 +370,7 @@
   {% endfor %}
 
   {% for week in weeks %}
-    <h4>{% trans 'Lesson documentation for week' %} {{ week.week }}</h4>
+    <h4>{% trans 'Week' %} {{ week.week }}: {{ week.0 }}–{{ week.6 }}</h4>
 
     <table class="small-print">
       <thead>
@@ -401,7 +401,7 @@
                     {% endif %}
                   ">
               {% if forloop.first %}
-                <th rowspan="{{ register_objects|length }}" class="lessons-day-head">{{ day }}</th>
+                <th rowspan="{{ register_objects|length }}" class="lessons-day-head">{{ day|date:"D" }}</th>
               {% endif %}
               <td class="lesson-pe">
                 {% if register_object.label_ != "event" %}
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index 99910ee7897b73d2f5bb1970e1fcbbeb937cbf2c..1f400054e242fb21197bd454f01d71bc358fbfb1 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -247,8 +247,8 @@ def register_object(
                             reversion.set_user(request.user)
                             for instance in instances:
                                 instance.person.mark_absent(
-                                    wanted_week[lesson_period.period.weekday],
-                                    lesson_period.period.period + 1,
+                                    wanted_week[register_object.period.weekday],
+                                    register_object.period.period + 1,
                                     instance.absent,
                                     instance.excused,
                                     instance.excuse_type,