Files
MABEA/backend/app/api/v1/endpoints/materialset.py
T
patrickandClaude Sonnet 5 52bf7d9ec9
CI / backend-tests (push) Successful in 2m55s
CI / frontend-build (push) Successful in 19s
feat(assets): ASSET-007 Material-Sets (Kits), ASSET-008 Consumable-Doku korrigiert
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
2026-09-10 15:22:02 +02:00

107 lines
4.0 KiB
Python

import uuid
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.deps import require_roles
from app.db.session import get_db
from app.models.auth import RolleTyp
from app.models.materialset import MaterialSet
from app.models.stammdaten import Material
from app.schemas.materialset import (
MaterialSetCreate,
MaterialSetMitgliedRead,
MaterialSetMitgliedUpsert,
MaterialSetRead,
MaterialSetUpdate,
)
from app.services.materialset import (
aendere_set,
entferne_mitglied,
erstelle_set,
liste_sets,
loesche_set,
mitglieder_fuer_set,
setze_mitglied,
)
router = APIRouter()
_materialverantwortliche = require_roles(RolleTyp.administration, RolleTyp.materialverantwortlicher)
_lesend = require_roles(
RolleTyp.mitarbeiter,
RolleTyp.materialverantwortlicher,
RolleTyp.leitungsverantwortlicher,
RolleTyp.administration,
)
async def _set_read(db: AsyncSession, material_set: MaterialSet) -> MaterialSetRead:
mitglieder = await mitglieder_fuer_set(db, material_set.id)
return MaterialSetRead(
id=material_set.id,
name=material_set.name,
beschreibung=material_set.beschreibung,
code=material_set.code,
mitglieder=[MaterialSetMitgliedRead.model_validate(m) for m in mitglieder],
)
@router.get("/material-sets", response_model=list[MaterialSetRead])
async def hole_material_sets(db: AsyncSession = Depends(get_db), _=Depends(_lesend)) -> list[MaterialSetRead]:
return [await _set_read(db, s) for s in await liste_sets(db)]
@router.post("/material-sets", response_model=MaterialSetRead, status_code=status.HTTP_201_CREATED)
async def erstelle_material_set(
payload: MaterialSetCreate, db: AsyncSession = Depends(get_db), _=Depends(_materialverantwortliche)
) -> MaterialSetRead:
material_set = await erstelle_set(db, name=payload.name, beschreibung=payload.beschreibung, code=payload.code)
return await _set_read(db, material_set)
@router.patch("/material-sets/{set_id}", response_model=MaterialSetRead)
async def aendere_material_set(
set_id: uuid.UUID,
payload: MaterialSetUpdate,
db: AsyncSession = Depends(get_db),
_=Depends(_materialverantwortliche),
) -> MaterialSetRead:
material_set = await db.get(MaterialSet, set_id)
if material_set is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Set nicht gefunden")
material_set = await aendere_set(db, material_set, **payload.model_dump(exclude_unset=True))
return await _set_read(db, material_set)
@router.delete("/material-sets/{set_id}", status_code=status.HTTP_204_NO_CONTENT)
async def loesche_material_set(
set_id: uuid.UUID, db: AsyncSession = Depends(get_db), _=Depends(_materialverantwortliche)
) -> None:
material_set = await db.get(MaterialSet, set_id)
if material_set is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Set nicht gefunden")
await loesche_set(db, material_set)
@router.put("/material-sets/{set_id}/mitglieder/{material_id}", status_code=status.HTTP_204_NO_CONTENT)
async def setze_material_set_mitglied(
set_id: uuid.UUID,
material_id: int,
payload: MaterialSetMitgliedUpsert,
db: AsyncSession = Depends(get_db),
_=Depends(_materialverantwortliche),
) -> None:
if await db.get(MaterialSet, set_id) is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Set nicht gefunden")
if await db.get(Material, material_id) is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Material nicht gefunden")
await setze_mitglied(db, set_id, material_id, payload.menge)
@router.delete("/material-sets/{set_id}/mitglieder/{material_id}", status_code=status.HTTP_204_NO_CONTENT)
async def entferne_material_set_mitglied(
set_id: uuid.UUID, material_id: int, db: AsyncSession = Depends(get_db), _=Depends(_materialverantwortliche)
) -> None:
await entferne_mitglied(db, set_id, material_id)