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})