diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index cf692d4607e804aad67e0141ecab2c789c0281cf..bab91988cd74c1e6f36b910b301454c0aa8b72c5 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -171,22 +171,11 @@ class Documentation(CalendarEvent):
 
             doc = next(existing_documentations_event, None)
             if doc:
-                if (
-                    (incomplete and doc.topic)
-                    or (
-                        not request.user.has_perm(
-                            "alsijil.edit_participation_status_for_documentation_rule", doc
-                        )
-                        and not doc.participations.filter(
-                            person__pk=request.user.person.pk, absence_reason__isnull=False
-                        ).exists()
-                    )
-                    or (
-                        absences_exist
-                        and (
-                            not doc.participations.all()
-                            or not [d for d in doc.participations.all() if d.absence_reason]
-                        )
+                if (incomplete and doc.topic) or (
+                    absences_exist
+                    and (
+                        not doc.participations.all()
+                        or not [d for d in doc.participations.all() if d.absence_reason]
                     )
                 ):
                     continue
diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py
index 43125d96be458a42e0af49ffdb943ca287869914..0f3b25b24b70a5823830574cf724bc7cc8cfc9f6 100644
--- a/aleksis/apps/alsijil/preferences.py
+++ b/aleksis/apps/alsijil/preferences.py
@@ -14,6 +14,19 @@ from aleksis.core.registries import site_preferences_registry
 alsijil = Section("alsijil", verbose_name=_("Class register"))
 
 
+@site_preferences_registry.register
+class InheritPrivilegesFromParentGroup(BooleanPreference):
+    section = alsijil
+    name = "inherit_privileges_from_parent_group"
+    default = True
+    verbose_name = _(
+        "Grant the owner of a parent group the same privileges "
+        "as the owners of the respective child groups "
+        "in regard to group role management and generating "
+        "full printouts of class registers."
+    )
+
+
 @site_preferences_registry.register
 class GroupOwnersCanAssignRolesToParents(BooleanPreference):
     section = alsijil
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index 595f8e2381fb20ca31593f23ff9e02122066a1c8..740aa1ff271e9e4af374f89c7b96c0e57c06a842 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -1,6 +1,5 @@
 from datetime import datetime
 
-from django.core.exceptions import PermissionDenied
 from django.db.models import BooleanField, ExpressionWrapper, Q
 
 import graphene
@@ -101,7 +100,13 @@ class Query(graphene.ObjectType):
 
     def resolve_documentations_by_course_id(root, info, course_id, **kwargs):
         documentations = Documentation.objects.filter(
-            Q(course__pk=course_id) | Q(amends__course__pk=course_id)
+            pk__in=Documentation.objects.filter(course_id=course_id)
+            .values_list("id", flat=True)
+            .union(
+                Documentation.objects.filter(amends__course_id=course_id).values_list(
+                    "id", flat=True
+                )
+            )
         )
         return documentations
 
@@ -137,7 +142,7 @@ class Query(graphene.ObjectType):
                 )
             )
         ):
-            raise PermissionDenied()
+            return []
 
         # Find all LessonEvents for all Lessons of this Course in this date range
         event_params = {
@@ -175,16 +180,22 @@ class Query(graphene.ObjectType):
         if person:
             person = Person.objects.get(pk=person)
             if not info.context.user.has_perm("core.view_person_rule", person):
-                raise PermissionDenied()
+                return []
         elif has_person(info.context.user):
             person = info.context.user.person
         else:
-            raise PermissionDenied()
+            return []
 
         return (
             Group.objects.for_current_school_term_or_all()
-            .filter(Q(members=person) | Q(owners=person) | Q(parent_groups__owners=person))
-            .distinct()
+            .filter(
+                pk__in=Group.objects.filter(members=person)
+                .values_list("id", flat=True)
+                .union(Group.objects.filter(owners=person).values_list("id", flat=True))
+                .union(
+                    Group.objects.filter(parent_groups__owners=person).values_list("id", flat=True)
+                )
+            )
             .annotate(
                 is_priority=ExpressionWrapper(
                     Q(group_type=get_site_preferences()["alsijil__group_type_priority_coursebook"]),
@@ -199,20 +210,24 @@ class Query(graphene.ObjectType):
         if person:
             person = Person.objects.get(pk=person)
             if not info.context.user.has_perm("core.view_person_rule", person):
-                raise PermissionDenied()
+                return []
         elif has_person(info.context.user):
             person = info.context.user.person
         else:
-            raise PermissionDenied()
+            return []
         return Course.objects.filter(
-            (
-                Q(teachers=person)
-                | Q(groups__members=person)
-                | Q(groups__owners=person)
-                | Q(groups__parent_groups__owners=person)
+            pk__in=(
+                Course.objects.filter(teachers=person)
+                .values_list("id", flat=True)
+                .union(Course.objects.filter(groups__members=person).values_list("id", flat=True))
+                .union(Course.objects.filter(groups__owners=person).values_list("id", flat=True))
+                .union(
+                    Course.objects.filter(groups__parent_groups__owners=person).values_list(
+                        "id", flat=True
+                    )
+                )
             )
-            & Q(groups__in=Group.objects.for_current_school_term_or_all())
-        ).distinct()
+        ).filter(groups__in=Group.objects.for_current_school_term_or_all())
 
     @staticmethod
     def resolve_absence_creation_persons(root, info, **kwargs):
diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py
index cdb2eaca122330f70bd75023a463f2dc1dc0e8e7..b833de336b2a2add64ac5f0e0cf6dd7fdd8ae0c5 100644
--- a/aleksis/apps/alsijil/schema/documentation.py
+++ b/aleksis/apps/alsijil/schema/documentation.py
@@ -108,7 +108,9 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp
             "alsijil.view_participation_status_for_documentation_rule", root
         ):
             if has_person(info.context.user):
-                return root.participations.filter(person=info.context.user.person)
+                return [
+                    p for p in root.participations.all() if p.person == info.context.user.person
+                ]
             return []
         return root.participations.all()
 
diff --git a/aleksis/apps/alsijil/schema/participation_status.py b/aleksis/apps/alsijil/schema/participation_status.py
index fcf15df815619fcc808770116347458d8f7daf02..22e5820594994b2d1bb4c81ae4f5a83f615bea0b 100644
--- a/aleksis/apps/alsijil/schema/participation_status.py
+++ b/aleksis/apps/alsijil/schema/participation_status.py
@@ -119,9 +119,9 @@ class ExtendParticipationStatusToAbsenceBatchMutation(graphene.Mutation):
             return participation, absence
 
         else:
-            # No base absence, simply create one
+            # No base absence, simply create one if absence reason is given
             data = dict(
-                reason_id=participation.absence_reason.id,
+                reason_id=participation.absence_reason.id if participation.absence_reason else None,
                 person=participation.person,
             )