from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import func from sqlalchemy.orm import Session from ..database import get_db from ..deps import get_current_user, require_admin from ..models import Group, Product, Unit, User from ..schemas import UnitCreate, UnitOut, UnitUpdate router = APIRouter(prefix="/units", tags=["units"]) @router.get("", response_model=list[UnitOut]) def list_units( db: Session = Depends(get_db), _: User = Depends(get_current_user) ) -> list[Unit]: return db.query(Unit).order_by(Unit.kind, Unit.factor).all() @router.post("", response_model=UnitOut, status_code=status.HTTP_201_CREATED) def create_unit( payload: UnitCreate, db: Session = Depends(get_db), _: User = Depends(require_admin), ) -> Unit: exists = db.query(Unit).filter(func.lower(Unit.name) == payload.name.lower()).first() if exists: raise HTTPException(status.HTTP_409_CONFLICT, "Einheit existiert bereits") unit = Unit(name=payload.name, kind=payload.kind, factor=payload.factor, is_builtin=False) db.add(unit) db.commit() db.refresh(unit) return unit @router.patch("/{unit_id}", response_model=UnitOut) def update_unit( unit_id: int, payload: UnitUpdate, db: Session = Depends(get_db), _: User = Depends(require_admin), ) -> Unit: """Umbenennen – auch bei eingebauten Einheiten, wie bei den Gebinden. Produkte und Gruppen verweisen ueber die ID und bleiben unberuehrt.""" unit = db.get(Unit, unit_id) if unit is None: raise HTTPException(status.HTTP_404_NOT_FOUND, "Einheit nicht gefunden") name = payload.name.strip() doppelt = ( db.query(Unit) .filter(func.lower(Unit.name) == name.lower(), Unit.id != unit_id) .first() ) if doppelt is not None: raise HTTPException(status.HTTP_409_CONFLICT, "Einheit existiert bereits") unit.name = name db.commit() db.refresh(unit) return unit @router.delete("/{unit_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_unit( unit_id: int, db: Session = Depends(get_db), _: User = Depends(require_admin), ) -> None: unit = db.get(Unit, unit_id) if unit is None: raise HTTPException(status.HTTP_404_NOT_FOUND, "Einheit nicht gefunden") if unit.is_builtin: raise HTTPException(status.HTTP_400_BAD_REQUEST, "Eingebaute Einheiten können nicht gelöscht werden") in_use = ( db.query(Product).filter(Product.display_unit_id == unit_id).first() or db.query(Group).filter(Group.min_stock_unit_id == unit_id).first() ) if in_use: raise HTTPException( status.HTTP_409_CONFLICT, "Einheit wird noch von Produkten/Gruppen verwendet" ) db.delete(unit) db.commit()