import csv import io from django.http import HttpResponse 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, Groep, Persoon, Roosterblok from core.permissions import CoreDataPermission, StaffDataPermission, module_permission_class ImportExportModuleEnabled = module_permission_class("importexport") def _doel_naam(blok): if blok.groep_id: return blok.groep.naam if blok.subgroep_id: return blok.subgroep.naam if blok.leerling_id: return blok.leerling.volledige_naam return "" EXPORTS = { "personen": ( ["id", "voornaam", "achternaam", "rol", "groep"], lambda: Persoon.objects.select_related("groep").all(), lambda p: [p.id, p.voornaam, p.achternaam, p.rol, p.groep.naam if p.groep_id else ""], ), "groepen": ( ["id", "naam", "actief"], lambda: Groep.objects.all(), lambda g: [g.id, g.naam, g.actief], ), "roosterblokken": ( ["id", "schooljaar", "tijdslot", "activiteit", "doel_type", "doel", "begeleiders"], lambda: Roosterblok.objects.select_related( "schooljaar", "tijdslot", "activiteit", "groep", "subgroep", "leerling" ).prefetch_related("begeleiders"), lambda b: [ b.id, b.schooljaar.naam, str(b.tijdslot), b.activiteit.naam, b.doel_type, _doel_naam(b), ", ".join(p.volledige_naam for p in b.begeleiders.all()), ], ), "afwezigheden": ( ["id", "persoon", "start_datum", "eind_datum", "reden"], lambda: Afwezigheid.objects.select_related("persoon").all(), lambda a: [a.id, a.persoon.volledige_naam, a.start_datum, a.eind_datum, a.reden], ), } @api_view(["GET"]) @permission_classes([StaffDataPermission, ImportExportModuleEnabled]) def export_csv(request, resource): if resource not in EXPORTS: return Response({"detail": "Onbekende export."}, status=404) headers, queryset_factory, row_factory = EXPORTS[resource] response = HttpResponse(content_type="text/csv; charset=utf-8") response["Content-Disposition"] = f'attachment; filename="{resource}.csv"' response.write("\ufeff") writer = csv.writer(response) writer.writerow(headers) for obj in queryset_factory(): writer.writerow(row_factory(obj)) audit_log(request, "export", f"CSV:{resource}") return response @api_view(["POST"]) @permission_classes([CoreDataPermission, ImportExportModuleEnabled]) def import_personen(request): tekst = request.data.get("csv") or "" if not tekst.strip(): return Response({"detail": "CSV-inhoud ontbreekt."}, status=400) reader = csv.DictReader(io.StringIO(tekst)) aangemaakt = 0 meldingen = [] for nummer, row in enumerate(reader, start=2): voornaam = (row.get("voornaam") or row.get("Voornaam") or "").strip() achternaam = (row.get("achternaam") or row.get("Achternaam") or "").strip() rol = (row.get("rol") or row.get("Rol") or "leerling").strip() groep_naam = (row.get("groep") or row.get("Groep") or "").strip() if not voornaam and not achternaam: continue groep = None if groep_naam: groep, _ = Groep.objects.get_or_create(naam=groep_naam) try: Persoon.objects.create(voornaam=voornaam, achternaam=achternaam, rol=rol, groep=groep) aangemaakt += 1 except Exception as exc: meldingen.append(f"Rij {nummer}: {exc}") audit_log(request, "import", "Persoon", {"aangemaakt": aangemaakt, "meldingen": len(meldingen)}) return Response({"aangemaakt": aangemaakt, "meldingen": meldingen})