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
42 lines
1.6 KiB
Python
42 lines
1.6 KiB
Python
import enum
|
|
import uuid
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
|
|
from sqlalchemy import ForeignKey, Numeric, String
|
|
from sqlalchemy.dialects.postgresql import ENUM as PgEnum, TIMESTAMP, UUID
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base import Base
|
|
|
|
|
|
class AusgabeStatus(str, enum.Enum):
|
|
offen = "offen"
|
|
zurueck = "zurueck"
|
|
|
|
|
|
ausgabe_status_pg = PgEnum(AusgabeStatus, name="ausgabe_status", create_type=False)
|
|
|
|
|
|
class Ausgabe(Base):
|
|
"""INV-007: personenbezogene Ausgabe/Rückgabe von Material/Leihgeräten -
|
|
ergänzt die reine Standort-/Lagerplatz-Sicht (Lagerbewegung/Materialbewegung)
|
|
um "wer hat das Ding gerade", solange die Ausgabe offen ist."""
|
|
|
|
__tablename__ = "ausgabe"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
material_id: Mapped[int] = mapped_column(ForeignKey("material.id"), nullable=False)
|
|
geraet_instanz_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
UUID(as_uuid=True), ForeignKey("geraet_instanz.id")
|
|
)
|
|
menge: Mapped[Decimal] = mapped_column(Numeric, nullable=False)
|
|
empfaenger_id: Mapped[int] = mapped_column(ForeignKey("benutzer.id"), nullable=False)
|
|
ausgegeben_von: Mapped[int] = mapped_column(ForeignKey("benutzer.id"), nullable=False)
|
|
ausgegeben_am: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), nullable=False)
|
|
rueckgabe_am: Mapped[datetime | None] = mapped_column(TIMESTAMP(timezone=True))
|
|
status: Mapped[AusgabeStatus] = mapped_column(
|
|
ausgabe_status_pg, nullable=False, default=AusgabeStatus.offen
|
|
)
|
|
zweck: Mapped[str | None] = mapped_column(String)
|