diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3d24b55b5f332fda533c5577d87c3323de803579..7f099fb3ecfd23c0909f86f2928a7d81eb8c8aeb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,8 @@ Fixed * Register absence form wasn't accessible without direct access to class register. * Printing the full group register failed when a person had no personal notes. * Data checks reported all Lesson Documentations as being during Holidays if there was no Holiday object. +* Students were displayed multiple times in class register views. +* Absences were counted multiple times in some class register views. `2.1`_ - 2022-06-25 ------------------- diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py index 5b0e5ac4b1337dfdc44c97470c36cd954fc7b915..b53f87f997b9f4b62336ef594fcc2676cc00a983 100644 --- a/aleksis/apps/alsijil/model_extensions.py +++ b/aleksis/apps/alsijil/model_extensions.py @@ -434,6 +434,7 @@ def generate_person_list_with_class_register_statistics( "filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True) & ~Q(filtered_personal_notes__excuse_type__count_as_absent=False), + distinct=True, ), excused=Count( "filtered_personal_notes", @@ -442,6 +443,7 @@ def generate_person_list_with_class_register_statistics( filtered_personal_notes__excused=True, ) & ~Q(filtered_personal_notes__excuse_type__count_as_absent=False), + distinct=True, ), excused_without_excuse_type=Count( "filtered_personal_notes", @@ -450,15 +452,16 @@ def generate_person_list_with_class_register_statistics( filtered_personal_notes__excused=True, filtered_personal_notes__excuse_type__isnull=True, ), + distinct=True, ), unexcused=Count( "filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True, filtered_personal_notes__excused=False), + distinct=True, ), tardiness=Sum("filtered_personal_notes__late"), tardiness_count=Count( - "filtered_personal_notes", - filter=Q(filtered_personal_notes__late__gt=0), + "filtered_personal_notes", filter=Q(filtered_personal_notes__late__gt=0), distinct=True ), ) diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index dc88dea6108ddc208142bf5b510f72f1563dbd47..68833a4d5dd8814a58c3bf6cae6b1c2e2c7af701 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -240,8 +240,10 @@ def register_object( else: persons = Person.objects.all() - persons_qs = register_object.get_personal_notes(persons, wanted_week).filter( - person__member_of__in=request.user.person.owner_of.all() + persons_qs = ( + register_object.get_personal_notes(persons, wanted_week) + .filter(person__member_of__in=request.user.person.owner_of.all()) + .distinct() ) # Annotate group roles @@ -476,12 +478,16 @@ def week_view( if not request.user.has_perm("alsijil.view_week_personalnote_rule", instance): persons_qs = persons_qs.filter(pk=request.user.person.pk) elif group: - persons_qs = persons_qs.filter(member_of=group).filter( - member_of__in=request.user.person.owner_of.all() + persons_qs = ( + persons_qs.filter(member_of=group) + .filter(member_of__in=request.user.person.owner_of.all()) + .distinct() ) else: - persons_qs = persons_qs.filter(member_of__in=groups).filter( - member_of__in=request.user.person.owner_of.all() + persons_qs = ( + persons_qs.filter(member_of__in=groups) + .filter(member_of__in=request.user.person.owner_of.all()) + .distinct() ) # Prefetch object permissions for persons and groups the persons are members of @@ -792,12 +798,16 @@ def my_students(request: HttpRequest) -> HttpResponse: new_groups = [] for group in relevant_groups: - persons = group.generate_person_list_with_class_register_statistics( - group.members.prefetch_related( - "primary_group__owners", - Prefetch("member_of", queryset=relevant_groups, to_attr="member_of_prefetched"), + persons = ( + group.generate_person_list_with_class_register_statistics( + group.members.prefetch_related( + "primary_group__owners", + Prefetch("member_of", queryset=relevant_groups, to_attr="member_of_prefetched"), + ) ) - ).filter(member_of__in=request.user.person.owner_of.all()) + .filter(member_of__in=request.user.person.owner_of.all()) + .distinct() + ) persons_for_group = [] for person in persons: person.set_object_permission_checker(checker) @@ -830,10 +840,10 @@ class StudentsList(PermissionRequiredMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["group"] = self.object - context[ - "persons" - ] = self.object.generate_person_list_with_class_register_statistics().filter( - member_of__in=self.request.user.person.owner_of.all() + context["persons"] = ( + self.object.generate_person_list_with_class_register_statistics() + .filter(member_of__in=self.request.user.person.owner_of.all()) + .distinct() ) context["extra_marks"] = ExtraMark.objects.all() context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True)