From 10406c724fa28b3e38f21c7ef25f1c3f6ade5b69 Mon Sep 17 00:00:00 2001 From: Julian Leucker <leuckerj@gmail.com> Date: Wed, 10 Jul 2024 21:18:43 +0200 Subject: [PATCH] Create mutation to extend absences to the entire day --- aleksis/apps/alsijil/schema/__init__.py | 6 +- .../alsijil/schema/participation_status.py | 80 +++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py index f63b8c2c9..2e6775bd3 100644 --- a/aleksis/apps/alsijil/schema/__init__.py +++ b/aleksis/apps/alsijil/schema/__init__.py @@ -32,7 +32,10 @@ from .extra_marks import ( ExtraMarkBatchPatchMutation, ExtraMarkType, ) -from .participation_status import ParticipationStatusBatchPatchMutation +from .participation_status import ( + ExtendParticipationStatusToAbsenceBatchMutation, + ParticipationStatusBatchPatchMutation, +) from .personal_note import ( PersonalNoteBatchCreateMutation, PersonalNoteBatchDeleteMutation, @@ -233,6 +236,7 @@ class Mutation(graphene.ObjectType): touch_documentation = TouchDocumentationMutation.Field() update_participation_statuses = ParticipationStatusBatchPatchMutation.Field() create_absences_for_persons = AbsencesForPersonsCreateMutation.Field() + extend_participation_statuses = ExtendParticipationStatusToAbsenceBatchMutation.Field() create_extra_marks = ExtraMarkBatchCreateMutation.Field() update_extra_marks = ExtraMarkBatchPatchMutation.Field() diff --git a/aleksis/apps/alsijil/schema/participation_status.py b/aleksis/apps/alsijil/schema/participation_status.py index 951ab4419..2b9ebb25f 100644 --- a/aleksis/apps/alsijil/schema/participation_status.py +++ b/aleksis/apps/alsijil/schema/participation_status.py @@ -1,10 +1,16 @@ +import datetime + from django.core.exceptions import PermissionDenied +from django.utils.translation import gettext_lazy as _ import graphene from graphene_django import DjangoObjectType +from reversion import create_revision, set_comment, set_user from aleksis.apps.alsijil.models import NewPersonalNote, ParticipationStatus from aleksis.apps.alsijil.schema.personal_note import PersonalNoteType +from aleksis.apps.kolego.models import Absence +from aleksis.apps.kolego.schema.absence import AbsenceType from aleksis.core.schema.base import ( BaseBatchPatchMutation, DjangoFilterMixin, @@ -70,3 +76,77 @@ class ParticipationStatusBatchPatchMutation(BaseBatchPatchMutation): "alsijil.edit_participation_status_for_documentation_rule", obj.related_documentation ): raise PermissionDenied() + + +class ExtendParticipationStatusToAbsenceBatchMutation(graphene.Mutation): + class Arguments: + input = graphene.List(graphene.ID, description=_("List of ParticipationStatus IDs")) + + participations = graphene.List(ParticipationStatusType) + absences = graphene.List(AbsenceType) + + @classmethod + def create_absence(cls, info, participation_id): + participation = ParticipationStatus.objects.get(pk=participation_id) + + if participation.date_end: + end_date = participation.date_end + else: + end_date = ParticipationStatus.value_end_datetime(participation).date() + + end_datetime = datetime.datetime.combine( + end_date, datetime.time.max, participation.timezone + ) + + if participation.base_absence: + # Update the base absence to increase length if needed + absence = participation.base_absence + + if absence.date_end: + if absence.date_end < end_date: + absence.date_end = end_date + absence.save() + + return participation, absence + + # Absence uses a datetime + if absence.datetime_end.astimezone(absence.timezone) < end_datetime: + # The end date ends after the previous absence end + absence.datetime_end = end_datetime + absence.save() + + return participation, absence + + else: + # No base absence, simply create one + data = dict( + reason_id=participation.absence_reason.id, + person=participation.person, + ) + + if participation.date_start: + data["date_start"] = participation.date_start + data["date_end"] = end_date + else: + data["datetime_start"] = ParticipationStatus.value_start_datetime(participation) + data["datetime_end"] = end_datetime + + absence, __ = Absence.objects.get_or_create(**data) + + participation.base_absence = absence + participation.save() + + return participation, absence + + @classmethod + def mutate(cls, root, info, input): # noqa + with create_revision(): + set_user(info.context.user) + set_comment(_("Extended absence reason from coursebook.")) + participations, absences = zip( + *[cls.create_absence(info, participation_id) for participation_id in input] + ) + + return ExtendParticipationStatusToAbsenceBatchMutation( + participations=participations, absences=absences + ) -- GitLab