feat(inventory): INV-007 Ausgabe/Rückgabe von Material und Leihgeräten
Personenbezogene Ausgabe ergänzt die reine Standort-/Lagerplatz-Sicht
um "wer hat das Ding gerade": neues Modell ausgabe (Material +
optional geraet_instanz_id), POST /ausgaben, GET /ausgaben (Filter
status/empfaenger), POST /ausgaben/{id}/rueckgabe mit Schutz vor
Doppel-Rueckgabe. Frontend als Admin-Tab "Ausgabe/Rückgabe" +
Command-Palette-Eintrag.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
from datetime import datetime, timezone
|
||||
from decimal import Decimal
|
||||
from uuid import UUID
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.ausgabe import Ausgabe, AusgabeStatus
|
||||
|
||||
|
||||
class AusgabeBereitsZurueckError(Exception):
|
||||
"""Eine bereits zurückgegebene Ausgabe kann nicht erneut zurückgegeben werden."""
|
||||
|
||||
|
||||
async def ausgeben(
|
||||
db: AsyncSession,
|
||||
*,
|
||||
material_id: int,
|
||||
geraet_instanz_id: UUID | None,
|
||||
menge: Decimal,
|
||||
empfaenger_id: int,
|
||||
ausgegeben_von: int,
|
||||
zweck: str | None,
|
||||
) -> Ausgabe:
|
||||
ausgabe = Ausgabe(
|
||||
material_id=material_id,
|
||||
geraet_instanz_id=geraet_instanz_id,
|
||||
menge=menge,
|
||||
empfaenger_id=empfaenger_id,
|
||||
ausgegeben_von=ausgegeben_von,
|
||||
ausgegeben_am=datetime.now(timezone.utc),
|
||||
status=AusgabeStatus.offen,
|
||||
zweck=zweck,
|
||||
)
|
||||
db.add(ausgabe)
|
||||
await db.flush()
|
||||
return ausgabe
|
||||
|
||||
|
||||
async def zurueckgeben(db: AsyncSession, *, ausgabe: Ausgabe) -> Ausgabe:
|
||||
if ausgabe.status == AusgabeStatus.zurueck:
|
||||
raise AusgabeBereitsZurueckError
|
||||
ausgabe.status = AusgabeStatus.zurueck
|
||||
ausgabe.rueckgabe_am = datetime.now(timezone.utc)
|
||||
await db.flush()
|
||||
return ausgabe
|
||||
Reference in New Issue
Block a user