diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py index b00d9277e507e284130340b84cbbca8c07597d1f..c47546e235ce26da6fef88fee0a2e0324d9df75f 100644 --- a/aleksis/apps/alsijil/preferences.py +++ b/aleksis/apps/alsijil/preferences.py @@ -2,8 +2,14 @@ from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from dynamic_preferences.preferences import Section -from dynamic_preferences.types import BooleanPreference, ChoicePreference, IntegerPreference - +from dynamic_preferences.types import ( + BooleanPreference, + ChoicePreference, + IntegerPreference, + ModelMultipleChoicePreference, +) + +from aleksis.core.models import GroupType from aleksis.core.registries import person_preferences_registry, site_preferences_registry alsijil = Section("alsijil", verbose_name=_("Class register")) @@ -181,3 +187,19 @@ class AllowEditFutureDocumentations(ChoicePreference): ), ) verbose_name = _("Set time range for which documentations may be edited") + + +@site_preferences_registry.register +class GroupTypesRegisterAbsence(ModelMultipleChoicePreference): + section = alsijil + name = "group_types_register_absence" + required = False + default = [] + model = GroupType + verbose_name = _( + "User is allowed to register absences for members " + "of groups the user is an owner of with these group types" + ) + help_text = _( + "If you leave it empty, all member of groups the user is an owner of will be shown." + ) diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index c1ffafbe856ffa64c91a17e3eaf062942debbe40..8b8e15e7b0250c76651144190ea4153b4e5717df 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -14,6 +14,8 @@ from .util.predicates import ( can_edit_documentation, can_edit_participation_status, can_edit_personal_note, + can_register_absence_for_at_least_one_group, + can_register_absence_for_person, can_view_any_documentation, can_view_documentation, can_view_participation_status, @@ -171,12 +173,12 @@ add_perm("alsijil.view_week_personalnote_rule", view_week_personal_notes_predica # Register absence view_register_absence_predicate = has_person & ( - is_person_group_owner | has_global_perm("alsijil.register_absence") + can_register_absence_for_at_least_one_group | has_global_perm("alsijil.register_absence") ) add_perm("alsijil.view_register_absence_rule", view_register_absence_predicate) register_absence_predicate = has_person & ( - is_group_owner + can_register_absence_for_person | has_global_perm("alsijil.register_absence") | has_object_perm("core.register_absence_person") | has_person_group_object_perm("core.register_absence_group") diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py index 9b715583e32a391f0888b0d54d1cb29c8d5e4f79..681b0cd3796d2ee86c219a6e9bc4ec562e484752 100644 --- a/aleksis/apps/alsijil/schema/__init__.py +++ b/aleksis/apps/alsijil/schema/__init__.py @@ -12,7 +12,7 @@ from aleksis.core.models import Group, Person from aleksis.core.schema.base import FilterOrderList from aleksis.core.schema.group import GroupType from aleksis.core.schema.person import PersonType -from aleksis.core.util.core_helpers import has_person +from aleksis.core.util.core_helpers import get_site_preferences, has_person from ..models import Documentation from .absences import ( @@ -174,7 +174,15 @@ class Query(graphene.ObjectType): @staticmethod def resolve_absence_creation_persons(root, info, **kwargs): if not info.context.user.has_perm("alsijil.register_absence"): - return Person.objects.filter(member_of__owners=info.context.user.person) + group_types = get_site_preferences()["alsijil__group_types_register_absence"] + if group_types: + return Person.objects.filter( + member_of__in=Group.objects.filter( + owners=info.context.user.person, group_type__in=group_types + ) + ) + else: + return Person.objects.filter(member_of__owners=info.context.user.person) return Person.objects.all() @staticmethod diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py index e1d8f8a02760b846d35672ffddeeb73d161ece72..5966a7459bc8a32f7e7468f20de2e7da0044441e 100644 --- a/aleksis/apps/alsijil/util/predicates.py +++ b/aleksis/apps/alsijil/util/predicates.py @@ -103,6 +103,26 @@ def is_person_group_owner(user: User, obj) -> bool: return Group.objects.filter(owners=user.person).exists() +@predicate +def can_register_absence_for_at_least_one_group(user: User, obj) -> bool: + """Predicate for registering absence for at least one group.""" + group_types = get_site_preferences()["alsijil__group_types_register_absence"] + qs = Group.objects.filter(owners=user.person) + if not group_types: + return qs.exists() + return qs.filter(group_type__in=group_types).exists() + + +@predicate +def can_register_absence_for_person(user: User, obj: Person) -> bool: + """Predicate for registering absence for person.""" + group_types = get_site_preferences()["alsijil__group_types_register_absence"] + qs = obj.member_of.filter(owners=user.person) + if not group_types: + return qs.exists() + return qs.filter(group_type__in=group_types).exists() + + def use_prefetched(obj, attr): prefetched_attr = f"{attr}_prefetched" if hasattr(obj, prefetched_attr):