from datetime import datetime, timezone from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models.fehlbestand import Fehlbestand, FehlbestandStatus from app.models.mindermenge import MindermengeStatus, MindermengenGenehmigung from app.services import historie as historie_service class FehlbestandBereitsErledigtError(Exception): """Ein bereits erledigter Fehlbestand braucht keine Mindermengen-Bewertung mehr.""" class BereitsGenehmigtError(Exception): """Für diesen Fehlbestand existiert bereits eine aktive Genehmigung.""" async def genehmigen( db: AsyncSession, *, fehlbestand: Fehlbestand, begruendung: str, genehmigt_von: int, zustaendiger_server_id: int, ) -> MindermengenGenehmigung: """Prompt 04: reine fachliche Bewertung - ändert NIEMALS Ist-Menge, Fehlmenge oder den Fehlbestand-Status selbst (Leitplanke, U2). Verknüpft mit der Kontrolle, die den Fehlbestand ausgelöst hat ("aktuelle Kontrolle des Objekts", Prompt 04.3.4).""" if fehlbestand.status == FehlbestandStatus.erledigt: raise FehlbestandBereitsErledigtError() if fehlbestand.kontrolle_id is None: # Sollte praktisch nicht vorkommen (jeder Fehlbestand entsteht aus einer # Kontrolle, Sprint 3), aber das Schema erlaubt kontrolle_id=NULL. raise ValueError("Fehlbestand ohne auslösende Kontrolle kann nicht genehmigt werden") result = await db.execute( select(MindermengenGenehmigung).where( MindermengenGenehmigung.fehlbestand_id == fehlbestand.id, MindermengenGenehmigung.status == MindermengeStatus.aktiv, ) ) if result.scalar_one_or_none() is not None: raise BereitsGenehmigtError() genehmigung = MindermengenGenehmigung( fehlbestand_id=fehlbestand.id, genehmigt_von=genehmigt_von, begruendung=begruendung, genehmigt_am=datetime.now(timezone.utc), ausloesende_kontrolle_id=fehlbestand.kontrolle_id, status=MindermengeStatus.aktiv, ) db.add(genehmigung) await db.flush() await historie_service.log( db, zustaendiger_server_id=zustaendiger_server_id, benutzer_id=genehmigt_von, ereignistyp="mindermenge_genehmigt", entitaet_typ="mindermengen_genehmigung", entitaet_id=genehmigung.id, neuer_wert={"fehlbestand_id": str(fehlbestand.id), "status": "aktiv"}, begruendung=begruendung, ) return genehmigung