diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql index 683ba5c99315cb62d83d8f6a803be90122277671..f808b469fe427ae7729ab6ce616e1719a35feb31 100644 --- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql +++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql @@ -44,5 +44,18 @@ mutation createAbsencesForPersons( reason: $reason ) { ok + items: participationStatuses { + id + isOptimistic + relatedDocumentation { + id + } + absenceReason { + id + name + shortName + colour + } + } } } diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index 9e68ccd06773dc8b0f6ee65ccd16c81319b94a8b..b2c0a54fcc90d943ba6d85e53b062292d11b9448 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -8,6 +8,7 @@ from django.db import models from django.db.models import QuerySet from django.db.models.constraints import CheckConstraint from django.db.models.query_utils import Q +from django.http import HttpRequest from django.urls import reverse from django.utils import timezone from django.utils.formats import date_format @@ -594,7 +595,7 @@ class Documentation(CalendarEvent): """ event_params = { "type": "PARTICIPANT", - "obj_id": person, + "id": person, } events = LessonEvent.get_single_events( @@ -790,6 +791,34 @@ class ParticipationStatus(CalendarEvent): verbose_name=_("Base Absence"), ) + @classmethod + def get_objects( + cls, request: HttpRequest | None = None, params: dict[str, any] | None = None + ) -> QuerySet: + qs = super().get_objects(request, params).select_related("person", "absence_reason") + if params: + if params.get("person"): + qs = qs.filter(person_id=params["person"]) + elif params.get("persons"): + qs = qs.filter(person_id__in=params["persons"]) + elif params.get("group"): + qs = qs.filter(groups_of_person__id=params.get("group")) + return qs + + @classmethod + def value_title( + cls, reference_object: "ParticipationStatus", request: HttpRequest | None = None + ) -> str: + """Return the title of the calendar event.""" + return f"{reference_object.person} ({reference_object.absence_reason})" + + @classmethod + def value_description( + cls, reference_object: "ParticipationStatus", request: HttpRequest | None = None + ) -> str: + """Return the title of the calendar event.""" + return "" + def fill_from_kolego(self, kolego_absence: KolegoAbsence): """Take over data from a Kolego absence.""" self.base_absence = kolego_absence diff --git a/aleksis/apps/alsijil/schema/absences.py b/aleksis/apps/alsijil/schema/absences.py index ae194435024511bac1eb06731cbf7b2013597570..ed66311c6db9a500f3afcf9408ca0b26a06ed014 100644 --- a/aleksis/apps/alsijil/schema/absences.py +++ b/aleksis/apps/alsijil/schema/absences.py @@ -1,16 +1,10 @@ -from datetime import datetime import graphene from aleksis.apps.kolego.models import Absence -from ..models import Documentation, ParticipationStatus -from .documentation import DocumentationType - - -class LessonsForPersonType(graphene.ObjectType): - id = graphene.ID() # noqa - lessons = graphene.List(DocumentationType) +from ..models import ParticipationStatus +from .participation_status import ParticipationStatusType class AbsencesForPersonsCreateMutation(graphene.Mutation): @@ -22,66 +16,41 @@ class AbsencesForPersonsCreateMutation(graphene.Mutation): reason = graphene.ID(required=True) ok = graphene.Boolean() + participation_statuses = graphene.List(ParticipationStatusType) @classmethod def mutate(cls, root, info, persons, start, end, comment, reason): # noqa # TODO: Check permissions for ParticipationStatus & KolegoAbsence # See MR 356 - # DocumentationBatchCreateOrUpdateMutation.create_or_update - # at least already checks permissions. + participation_statuses = [] for person in persons: - # Get all documentations for this person between start & end - docs, dummies = Documentation.get_documentations_for_person( - person, - datetime.combine(start, datetime.min.time()), - datetime.combine(end, datetime.max.time()), + kolego_absence, __ = Absence.objects.get_or_create( + date_start=start, + date_end=end, + reason_id=reason, + person_id=person, + comment=comment, ) - # Create doc for dummies that are already in the past - future = False - for dummy in dummies: - lesson_event, dummy_start, dummy_end = Documentation.parse_dummy(dummy.pk) - - if dummy_start < datetime.now(dummy_start.tzinfo): - # In the past -> Create a Documentation - docs.append( - Documentation.create_from_lesson_event( - info.context.user, - lesson_event, - dummy_start, - dummy_end, - ) - ) - else: - future = True + events = ParticipationStatus.get_single_events( + start, + end, + None, + {"person": person}, + with_reference_object=True, + ) # Create a ParticipationStatus for each documentation - for doc in docs: + for event in events: + participation_status = event["REFERENCE_OBJECT"] + participation_status.absence_reason_id = reason + participation_status.base_absence = kolego_absence + participation_status.save() + participation_statuses.append(participation_status) # Set person & absence_reason directly from id - ParticipationStatus.objects.get_or_create( - person_id=person, - related_documentation=doc, - absence_reason_id=reason, - datetime_start=doc.datetime_start, - datetime_end=doc.datetime_end, - timezone=doc.timezone, - ) - - # If there are still dummy documentations in the future - # create a Kolego Absence - if future: - # TODO: Are date_start & date_end from CalendarEvent enough - # or is time needed? - # Set reason & person directly from id - Absence.objects.get_or_create( - date_start=datetime.now().date(), - date_end=end, - reason_id=reason, - person_id=person, - comment=comment, - ) - # Return ok=True if everything went well. - return AbsencesForPersonsCreateMutation(ok=True) + return AbsencesForPersonsCreateMutation( + ok=True, participation_statuses=participation_statuses + )