Skip to content
Snippets Groups Projects
Verified Commit a1baeeb7 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Fix and simplify saving of absences via absence creation form

parent 6ba4002a
No related branches found
No related tags found
1 merge request!356Add dialog for creation of long-term absences
Pipeline #190378 canceled
......@@ -44,5 +44,18 @@ mutation createAbsencesForPersons(
reason: $reason
) {
ok
items: participationStatuses {
id
isOptimistic
relatedDocumentation {
id
}
absenceReason {
id
name
shortName
colour
}
}
}
}
......@@ -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
......
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
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment