from fastapi import APIRouter, Depends, Form, HTTPException, Request from fastapi.responses import RedirectResponse from anode_client import anode_request from auth import require_admin from routers.geraete import OPTIONEN_FELDER, anreichere_mit_quelle_url, gruppiere_nach_kategorie from templating import templates router = APIRouter(prefix="/admin/geraete") def find_device(device_id: str) -> dict | None: result = anode_request("GET", "/api/v1/devices") devices = result.get("devices", []) if result.get("success") else [] for device in devices: if device["id"] == device_id: return device return None @router.get("") def index(request: Request, user: dict = Depends(require_admin)): result = anode_request("GET", "/api/v1/devices") devices = result.get("devices", []) if result.get("success") else [] # Admin-Liste ist organisationsübergreifend - jede Zeile braucht die # OE-Auswahl ihrer eigenen Organisation für "In OE verschieben", daher # je vorkommender Organisation einmal (nicht pro Gerät) abfragen. oe_by_org: dict[str, list[dict]] = {} for organization_id in {device["organization_id"] for device in devices}: oe_result = anode_request("GET", f"/api/v1/organizations/{organization_id}/organisationseinheiten") oe_by_org[organization_id] = oe_result.get("organisationseinheiten", []) if oe_result.get("success") else [] return templates.TemplateResponse( request, "admin/geraete_liste.html", {"user": user, "devices": devices, "oe_by_org": oe_by_org}, ) @router.post("/{device_id}/oe") def oe_verschieben(device_id: str, oe_id: str = Form(...), user: dict = Depends(require_admin)): if find_device(device_id) is None: raise HTTPException(status_code=404, detail="Gerät wurde nicht gefunden.") anode_request("POST", f"/api/v1/devices/{device_id}/oe", json={"oe_id": oe_id}) return RedirectResponse("/admin/geraete", status_code=303) @router.get("/{device_id}") def auftragskatalog_ansicht(request: Request, device_id: str, user: dict = Depends(require_admin)): device = find_device(device_id) if device is None: raise HTTPException(status_code=404, detail="Gerät wurde nicht gefunden.") result = anode_request("GET", f"/api/v1/devices/{device_id}/auftragskatalog") katalog = result.get("auftragskatalog", []) if result.get("success") else [] fehler = None if result.get("success") else result.get("message") katalog = anreichere_mit_quelle_url( katalog, f"/admin/kunden/{device['organization_id']}/organisationseinheiten", f"/admin/kunden/{device['organization_id']}/gruppen", ) return templates.TemplateResponse( request, "auftragskatalog.html", { "user": user, "device": device, "kategorien": gruppiere_nach_kategorie(katalog), "fehler": fehler, "optionen_felder": OPTIONEN_FELDER, "zurueck_url": "/admin/geraete", }, ) @router.post("/{device_id}/auftragskatalog/{merkmal_key}/select") async def auftrag_select( request: Request, device_id: str, merkmal_key: str, user: dict = Depends(require_admin) ): if find_device(device_id) is None: raise HTTPException(status_code=404, detail="Gerät wurde nicht gefunden.") form = await request.form() optionen = { feld["key"]: (form.get(f"optionen.{feld['key']}") == "on") for feld in OPTIONEN_FELDER.get(merkmal_key, []) } anode_request( "POST", f"/api/v1/devices/{device_id}/auftragskatalog/{merkmal_key}/select", json={"optionen": optionen}, ) return RedirectResponse(f"/admin/geraete/{device_id}", status_code=303) @router.post("/{device_id}/auftragskatalog/{merkmal_key}/deselect") def auftrag_deselect(device_id: str, merkmal_key: str, user: dict = Depends(require_admin)): if find_device(device_id) is None: raise HTTPException(status_code=404, detail="Gerät wurde nicht gefunden.") anode_request( "POST", f"/api/v1/devices/{device_id}/auftragskatalog/{merkmal_key}/deselect" ) return RedirectResponse(f"/admin/geraete/{device_id}", status_code=303)