Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
107 lines
4.0 KiB
Python
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)
|