diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py index b0d8fbc42c9227e32c227bf3ac10ef9c1635fba6..43125d96be458a42e0af49ffdb943ca287869914 100644 --- a/aleksis/apps/alsijil/preferences.py +++ b/aleksis/apps/alsijil/preferences.py @@ -64,6 +64,19 @@ class GroupTypesRegisterAbsence(ModelMultipleChoicePreference): ) +@site_preferences_registry.register +class GroupTypesViewPersonStatistics(ModelMultipleChoicePreference): + section = alsijil + name = "group_types_view_person_statistics" + required = False + default = [] + model = GroupType + verbose_name = _( + "User is allowed to view coursebook statistics for members " + "of groups the user is an owner of with these group types" + ) + + @site_preferences_registry.register class GroupTypePriorityCoursebook(ModelChoicePreference): section = alsijil diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index 602663b519a0680ca88de3813ecbc38df64579a8..71927e400fb68beab9d2c5864106f63bb011e128 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -20,6 +20,7 @@ from .util.predicates import ( can_view_documentation, can_view_participation_status, can_view_personal_note, + can_view_statistics_for_person, has_person_group_object_perm, is_course_group_owner, is_course_member, @@ -241,6 +242,24 @@ add_perm( edit_personal_note_predicate, ) +view_group_statistics_predicate = has_person & ( + has_global_perm("alsijil.view_participationstatus") | is_group_owner +) +add_perm( + "alsijil.view_group_statistics_rule", + view_group_statistics_predicate, +) + +view_person_statistics_predicate = has_person & ( + is_current_person + | has_global_perm("alsijil.view_participationstatus") + | can_view_statistics_for_person +) +add_perm( + "alsijil.view_person_statistics_rule", + view_person_statistics_predicate, +) + # View parent menu entry view_menu_predicate = has_person & (view_documentations_menu_predicate | view_extramarks_predicate) add_perm( diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py index c7e7e2a23b45c76da8184f1e0f19420a8c417aa7..2e6bb7ad852bb3cb932d34393b8d05abaeed7f0d 100644 --- a/aleksis/apps/alsijil/schema/__init__.py +++ b/aleksis/apps/alsijil/schema/__init__.py @@ -259,28 +259,44 @@ class Query(graphene.ObjectType): @staticmethod def resolve_statistics_by_person(root, info, person, term): + person = Person.objects.get(pk=person) + if not info.context.user.has_perm("alsijil.view_person_statistics_rule", person): + return None school_term = SchoolTerm.objects.get(id=term) return annotate_person_statistics_for_school_term( - Person.objects.filter(id=person), school_term + Person.objects.filter(id=person.id), school_term ).first() @staticmethod def resolve_participations_of_person(root, info, person, term=None): - # TODO: only current term - return ParticipationStatus.objects.filter(person=person, absence_reason__isnull=False) + person = Person.objects.get(pk=person) + if not info.context.user.has_perm("alsijil.view_person_statistics_rule", person): + return [] + school_term = SchoolTerm.objects.get(id=term) + return ParticipationStatus.objects.filter( + person=person, + absence_reason__isnull=False, + datetime_start__date__gte=school_term.date_start, + datetime_end__date__lte=school_term.date_end, + ) @staticmethod def resolve_personal_notes_for_person(root, info, person, term=None): - # TODO: only current term + person = Person.objects.get(pk=person) + if not info.context.user.has_perm("alsijil.view_person_statistics_rule", person): + return [] return NewPersonalNote.objects.filter(person=person) @staticmethod def resolve_statistics_by_group(root, info, group, term=None): + group = Group.objects.get(pk=group) + if not info.context.user.has_perm("alsijil.view_group_statistics_rule", group): + return [] school_term = ( SchoolTerm.objects.get(id=term) if term is not None else SchoolTerm.get_current() ) - members = Group.objects.get(id=group).members.all() + members = group.members.all() return annotate_person_statistics_for_school_term(members, school_term, group=group) diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py index 2a27bca7e2260a13d12199027d3501add3494b60..f44b7677af2b9222b3fbbeec4ee66ad088176135 100644 --- a/aleksis/apps/alsijil/util/predicates.py +++ b/aleksis/apps/alsijil/util/predicates.py @@ -365,3 +365,13 @@ def can_edit_personal_note(user: User, obj: NewPersonalNote): user, obj.documentation.amends ) | is_lesson_event_group_owner(user, obj.documentation.amends) return False + + +@predicate +def can_view_statistics_for_person(user: User, obj: Person) -> bool: + """Predicate for registering absence for person.""" + group_types = get_site_preferences()["alsijil__group_types_view_person_statistics"] + qs = obj.member_of.filter(owners=user.person) + if not group_types: + return False + return qs.filter(group_type__in=group_types).exists()