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

Add some docstrings and types for statistics builder

parent 4822847b
No related branches found
No related tags found
1 merge request!477Resolve "Add export functionality to absence statistics page"
Pipeline #195680 failed
...@@ -17,6 +17,8 @@ from aleksis.core.managers import ( ...@@ -17,6 +17,8 @@ from aleksis.core.managers import (
if TYPE_CHECKING: if TYPE_CHECKING:
from aleksis.core.models import Group, SchoolTerm from aleksis.core.models import Group, SchoolTerm
from .models import Documentation
class GroupRoleManager(AlekSISBaseManagerWithoutMigrations): class GroupRoleManager(AlekSISBaseManagerWithoutMigrations):
pass pass
...@@ -74,14 +76,17 @@ class GroupRoleAssignmentQuerySet(QuerySet): ...@@ -74,14 +76,17 @@ class GroupRoleAssignmentQuerySet(QuerySet):
class DocumentationManager(RecurrencePolymorphicManager): class DocumentationManager(RecurrencePolymorphicManager):
"""Manager adding specific methods to documentations.""" """Manager adding specific methods to documentations."""
def for_school_term(self, school_term: "SchoolTerm"): def for_school_term(self, school_term: "SchoolTerm") -> QuerySet["Documentation"]:
"""Filter documentations by school term."""
return self.filter( return self.filter(
datetime_start__date__gte=school_term.date_start, datetime_start__date__gte=school_term.date_start,
datetime_end__date__lte=school_term.date_end, datetime_end__date__lte=school_term.date_end,
) )
def all_for_group(self, group: "Group"): def all_for_group(self, group: "Group") -> QuerySet["Documentation"]:
return self.for_school_term(group.school_term).filter( """Filter documentations by group."""
qs = self.for_school_term(group.school_term) if group.school_term else self
return qs.filter(
pk__in=self.filter(course__groups=group) pk__in=self.filter(course__groups=group)
.values_list("pk", flat=True) .values_list("pk", flat=True)
.union(self.filter(course__groups__parent_groups=group).values_list("pk", flat=True)) .union(self.filter(course__groups__parent_groups=group).values_list("pk", flat=True))
...@@ -92,8 +97,10 @@ class DocumentationManager(RecurrencePolymorphicManager): ...@@ -92,8 +97,10 @@ class DocumentationManager(RecurrencePolymorphicManager):
) )
) )
def all_planned_for_group(self, group: "Group"): def all_planned_for_group(self, group: "Group") -> QuerySet["Documentation"]:
return self.for_school_term(group.school_term).filter( """Filter documentations by group, but only planned lessons."""
qs = self.for_school_term(group.school_term) if group.school_term else self
return qs.filter(
pk__in=self.filter( pk__in=self.filter(
amends__in=LessonEvent.objects.filter(LessonEvent.objects.for_group_q(group)) amends__in=LessonEvent.objects.filter(LessonEvent.objects.for_group_q(group))
).values_list("pk", flat=True) ).values_list("pk", flat=True)
......
...@@ -9,11 +9,22 @@ from ..models import Documentation, ExtraMark, NewPersonalNote, ParticipationSta ...@@ -9,11 +9,22 @@ from ..models import Documentation, ExtraMark, NewPersonalNote, ParticipationSta
class BuilderError(Exception): class BuilderError(Exception):
"""Error in building statistics using the StatisticsBuilder."""
pass pass
class StatisticsBuilder: class StatisticsBuilder:
"""Builder class for building queries with annotated statistics on persons.
To build queries, you can combine one `use_` with multiple `annotate` or `prefetch`
methods. At the end, call `build` to get the actual queryset.
>>> StatisticsBuilder(person_qs).use_from_school_term(school_term).annotate_statistics().build()
"""
def __init__(self, persons: QuerySet[Person]) -> None: def __init__(self, persons: QuerySet[Person]) -> None:
"""Intialize the builder with a persons queryset."""
self.qs: QuerySet[Person] = persons self.qs: QuerySet[Person] = persons
self.participations_filter: Q | None = None self.participations_filter: Q | None = None
self.personal_notes_filter: Q | None = None self.personal_notes_filter: Q | None = None
......
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