Verwendungsstatus: Backend fuer "getragen / in Reinigung / in Reparatur"
Einzelstuecke hatten bisher keinen Zustand - der Lagerort sagt, wohin ein
Stueck gehoert, aber nicht, woran es gerade ist. Neue Tabelle item_usages
nach dem Vorbild von item_loans: ein Zeitraum je Zustand, ended_at NULL
heisst "laeuft noch", und ein Teilindex laesst nur einen laufenden zu.
"Verfuegbar" wird bewusst nicht gespeichert - keine offene Zeile IST
verfuegbar, wie bei lots.opened_on und beim Verleih. Damit kostet der
Ruhezustand nichts und die Tabelle fuellt sich nicht mit Rauschen.
Abgeschlossene Zeilen bleiben stehen, sie sind der Verlauf.
Eigener Endpunkt (PUT /items/{id}/verwendung) und ausdruecklich nicht
PATCH /items/{id}: Das ist Admins vorbehalten, und die App schickt dort
immer alle Felder mitsamt null - jedes Speichern wuerde den Status
stillschweigend zuruecksetzen. Umstellen darf deshalb jeder angemeldete
Benutzer, wie Verleihen.
Der Zustand aendert den Bestand nicht und schreibt keine Bewegung: ein
getragenes Hemd ist weiterhin im Haushalt, anders als ein verliehenes.
Sichtbar nur bei Kategorien mit usage_tracking. Ein Haken an einer
Oberkategorie wandert in den Unterbaum, weil die Garderobe als
Kategoriebaum ja schon existiert. Die Markierung fahrt in beiden
Sicherungswegen mit; der Verlauf nicht, weil Einzelstuecke dort
ueberhaupt nicht vorkommen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8c752e3d1f
commit
98e2d18142
@@ -12,6 +12,7 @@ from .models import (
|
||||
RemovalReason,
|
||||
Role,
|
||||
UnitKind,
|
||||
UsageStatus,
|
||||
)
|
||||
|
||||
|
||||
@@ -283,6 +284,8 @@ class CategoryOut(BaseModel):
|
||||
# Maske: Ein leeres Feld soll zeigen, was es erbt, statt nur leer zu sein.
|
||||
inherited_open_days: int = 0
|
||||
open_days_source: str = ""
|
||||
# Ob Einzelstuecke dieser Kategorie einen Verwendungsstatus fuehren.
|
||||
usage_tracking: bool = False
|
||||
|
||||
|
||||
class CategoryCreate(BaseModel):
|
||||
@@ -291,6 +294,8 @@ class CategoryCreate(BaseModel):
|
||||
# None: erbt vom Elternteil bzw. neue Oberkategorie = Gegenstand.
|
||||
tracking: CategoryTracking | None = None
|
||||
open_days: int | None = Field(default=None, ge=1)
|
||||
# None: erbt vom Elternteil bzw. neue Oberkategorie = aus.
|
||||
usage_tracking: bool | None = None
|
||||
|
||||
|
||||
class CategoryUpdate(BaseModel):
|
||||
@@ -300,6 +305,9 @@ class CategoryUpdate(BaseModel):
|
||||
# 0 ist nicht erlaubt: „sofort verbrauchen" waere keine Frist, und None
|
||||
# heisst schon „erben" – zwei Bedeutungen fuer leer gaebe es sonst.
|
||||
open_days: int | None = Field(default=None, ge=1)
|
||||
# Wird beim Speichern in den ganzen Unterbaum uebernommen, siehe
|
||||
# routers/categories.py::update_category.
|
||||
usage_tracking: bool | None = None
|
||||
|
||||
|
||||
# ---- Shops (Bezugsquellen, nur für Gegenstände) ----
|
||||
@@ -1064,6 +1072,28 @@ class LoanOut(BaseModel):
|
||||
location_name: str | None = None
|
||||
|
||||
|
||||
class VerwendungSetzen(BaseModel):
|
||||
"""Verwendungsstatus eines Einzelstuecks setzen.
|
||||
|
||||
``status`` leer heisst verfuegbar – dafuer gibt es keinen eigenen Wert, es
|
||||
wird nur der laufende Zustand beendet (siehe models.py::UsageStatus).
|
||||
"""
|
||||
status: UsageStatus | None = None
|
||||
|
||||
|
||||
class VerwendungOut(BaseModel):
|
||||
"""Ein Zeitraum in einem Verwendungszustand – laufend oder abgeschlossen."""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: int
|
||||
item_id: int
|
||||
status: UsageStatus
|
||||
started_at: datetime
|
||||
# None = laeuft noch.
|
||||
ended_at: datetime | None = None
|
||||
# Wer umgestellt hat (Konto kann spaeter geloescht sein).
|
||||
username: str | None = None
|
||||
|
||||
|
||||
class ItemKurz(BaseModel):
|
||||
"""Ein Einzelstueck in Kurzform – fuer Zubehoer-Listen in beide Richtungen.
|
||||
|
||||
@@ -1112,6 +1142,12 @@ class ItemOut(BaseModel):
|
||||
# Der offene Verleih, falls das Stück gerade draußen ist – sonst None.
|
||||
# Der Lagerort bleibt daneben stehen: dorthin gehört es zurück.
|
||||
loan: LoanOut | None = None
|
||||
# Der laufende Verwendungszustand – None heisst verfuegbar. Anders als beim
|
||||
# Verleih bleibt das Stueck dabei im Bestand: getragen ist nicht weg.
|
||||
verwendung: VerwendungOut | None = None
|
||||
# Ob die Kategorie dieses Stuecks ueberhaupt einen Verwendungsstatus fuehrt.
|
||||
# Steuert, ob die Oberflaeche die Bedienung dafuer zeigt.
|
||||
verwendung_moeglich: bool = False
|
||||
# Zubehör: die Teile dieses Geräts und, umgekehrt, das Gerät, zu dem dieses
|
||||
# Stück gehört. Beide Richtungen, weil beide Fragen im Alltag vorkommen.
|
||||
zubehoer: list[ItemKurz] = []
|
||||
|
||||
Reference in New Issue
Block a user