86 lines
3.4 KiB
Python
86 lines
3.4 KiB
Python
from datetime import timedelta
|
|
|
|
from rest_framework.decorators import api_view, permission_classes
|
|
from rest_framework.response import Response
|
|
|
|
from core.audit import audit_log
|
|
from core.models import Afwezigheid, BlokUitzondering, Persoon, Roosterblok
|
|
from core.permissions import StaffDataPermission, module_permission_class
|
|
|
|
VervangingModuleEnabled = module_permission_class("vervanging")
|
|
|
|
|
|
def _datums(start, eind, weekdag):
|
|
dag = start
|
|
while dag <= eind:
|
|
if dag.weekday() == weekdag:
|
|
yield dag
|
|
dag += timedelta(days=1)
|
|
|
|
|
|
def _beschikbare_medewerkers(blok):
|
|
bezet = Persoon.objects.filter(begeleider_roosterblokken__tijdslot=blok.tijdslot).values("id")
|
|
qs = Persoon.objects.exclude(rol="leerling").filter(actief=True).exclude(id__in=bezet)
|
|
return qs.exclude(id__in=blok.begeleiders.values("id")).distinct()
|
|
|
|
|
|
@api_view(["GET"])
|
|
@permission_classes([StaffDataPermission, VervangingModuleEnabled])
|
|
def suggesties(request):
|
|
afw_id = request.query_params.get("afwezigheid")
|
|
try:
|
|
afw = Afwezigheid.objects.select_related("persoon").get(pk=afw_id)
|
|
except Afwezigheid.DoesNotExist:
|
|
return Response({"detail": "Afwezigheid niet gevonden."}, status=404)
|
|
|
|
blokken = (
|
|
Roosterblok.objects
|
|
.filter(begeleiders=afw.persoon, sjabloon=False)
|
|
.select_related("tijdslot", "activiteit", "groep", "subgroep", "leerling")
|
|
.prefetch_related("begeleiders")
|
|
)
|
|
resultaat = []
|
|
for blok in blokken:
|
|
datums = list(_datums(afw.start_datum, afw.eind_datum, blok.tijdslot.dag))
|
|
if not datums:
|
|
continue
|
|
kandidaten = _beschikbare_medewerkers(blok)[:8]
|
|
resultaat.append({
|
|
"roosterblok": blok.id,
|
|
"activiteit": blok.activiteit.naam,
|
|
"tijdslot": str(blok.tijdslot),
|
|
"doel": blok.groep.naam if blok.groep_id else blok.subgroep.naam if blok.subgroep_id else blok.leerling.volledige_naam,
|
|
"datums": datums,
|
|
"kandidaten": [
|
|
{"id": p.id, "naam": p.volledige_naam, "rol": p.get_rol_display()}
|
|
for p in kandidaten
|
|
],
|
|
})
|
|
return Response({
|
|
"afwezigheid": afw.id,
|
|
"persoon": afw.persoon.volledige_naam,
|
|
"suggesties": resultaat,
|
|
})
|
|
|
|
|
|
@api_view(["POST"])
|
|
@permission_classes([StaffDataPermission, VervangingModuleEnabled])
|
|
def toepassen(request):
|
|
blok_id = request.data.get("roosterblok")
|
|
datum = request.data.get("datum")
|
|
vervanger_id = request.data.get("vervanger")
|
|
if not (blok_id and datum and vervanger_id):
|
|
return Response({"detail": "roosterblok, datum en vervanger zijn verplicht."}, status=400)
|
|
if not StaffDataPermission().has_permission(request, type("View", (), {"write_roles": ("roostermaker", "directie")})()):
|
|
return Response({"detail": "Je hebt geen rechten om vervangingen toe te passen."}, status=403)
|
|
obj, _ = BlokUitzondering.objects.update_or_create(
|
|
roosterblok_id=blok_id,
|
|
datum=datum,
|
|
defaults={
|
|
"vervalt": False,
|
|
"vervanger_id": vervanger_id,
|
|
"opmerking": request.data.get("opmerking", "Vervanging"),
|
|
},
|
|
)
|
|
audit_log(request, "replacement_apply", f"BlokUitzondering:{obj.pk}", {"roosterblok": blok_id, "datum": datum})
|
|
return Response({"id": obj.id, "roosterblok": obj.roosterblok_id, "datum": obj.datum, "vervanger": obj.vervanger_id})
|