Einzelstuecke verleihen: eigener Vorgang statt Lagerort-Wert

Der Lagerort bleibt beim Verleihen stehen - er sagt weiter, wohin das
Stueck nach der Rueckgabe zurueckgehoert. Ein Lagerort-Wert "verliehen"
haette diese Information vernichtet. Stattdessen eine eigene Tabelle
item_loans mit Entleiher und Grund als Freitext, Verleihdatum und einem
optionalen Rueckgabedatum: "kurz mal mitgenommen" soll nicht an einem
Datumszwang scheitern.

Zurueckgegebene Vorgaenge bleiben stehen, damit die Tabelle gleichzeitig
die Verleih-Historie je Stueck ist. Ein Teilindex auf die offenen
Vorgaenge haelt fest, dass ein Stueck nicht zweimal gleichzeitig
verliehen sein kann - wie bei den "Ueberall"-Mindestbestaenden, weil
Postgres NULLs in UNIQUE als verschieden zaehlt.

Verliehen heisst nicht im Bestand: Ein Stueck, das nicht im Haus ist,
zaehlt nirgends mehr mit - weder am Lagerort noch im Gesamtbestand.
Entschieden wird das an einer Stelle (services/loans.py::nicht_verliehen),
die alle fuenf Zaehlungen benutzen. Sonst behauptete "Was liegt hier?"
weiterhin, die Kamera liege im Regal. Folge: Faellt ein verliehenes
Stueck unter den Mindestbestand, erscheint der Artikel auf der
Einkaufsliste.

Verleihen und Zuruecknehmen darf jeder angemeldete Benutzer - es ist eine
Buchung wie Ein- und Auslagern, keine Stammdatenaenderung - und wird mit
dem Konto protokolliert. Nur das Loeschen eines Vorgangs bleibt Admins
vorbehalten, weil es Historie vernichtet.

Bewusst keine Movement-Bewegung je Verleih: Der Verlauf rechnet den
Bestand rueckwaerts aus vorzeichenbehafteten Bewegungen, ein Abgang ohne
Gegenbuchung wuerde diese Kurve verfaelschen.

GET /loans?due_in= liefert die faelligen Verleihe und ist damit schon die
Datenquelle fuer die spaetere Rueckgabe-Erinnerung der App. Oberflaeche in
Web und App fehlt noch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-17 09:16:47 +02:00
co-authored by Claude Opus 5
parent ba84e4ea01
commit 467ef3c804
12 changed files with 833 additions and 12 deletions
+29
View File
@@ -89,6 +89,35 @@ Selfhostbare Lebensmittel-Lagerverwaltung. Aufbau in mehreren Schritten.
*Bekannte Ungenauigkeit:* Die Umrechnung nutzt die heutige Packungsgröße; wird
sie später geändert, verschiebt sich auch die Historie.
## Schritt 2e – Verleih von Einzelstücken (Backend ✅, Oberfläche offen)
- **Eigene Tabelle `item_loans` statt eines Lagerort-Werts „verliehen".** Der
Lagerort am Stück bleibt stehen und sagt weiter, wohin es nach der Rückgabe
zurückgehört; ein Lagerort-Wert hätte diese Information vernichtet.
Je Vorgang: Entleiher (Freitext), Grund (Freitext, optional), Verleihdatum,
erwartetes Rückgabedatum (**optional** – „kurz mal mitgenommen" soll nicht an
einem Datumszwang scheitern) und das Konto, das herausgegeben hat.
- **Zurückgegebene Verleihe bleiben stehen** (`returned_on` gesetzt) – damit ist
die Tabelle gleichzeitig die Verleih-Historie je Stück. Ein Teilindex auf die
offenen Vorgänge sichert ab, dass ein Stück nicht zweimal gleichzeitig
verliehen ist.
- **Verliehen heißt nicht im Bestand.** Ein verliehenes Stück zählt nirgends
mehr mit – weder am Lagerort noch im Gesamtbestand. Entschieden wird das an
einer Stelle (`services/loans.py::nicht_verliehen`), die alle fünf Zählungen
benutzen. „Was liegt hier?" behauptet damit nicht länger, das Stück liege im
Regal. *Folge:* Fällt es unter den Mindestbestand, erscheint der Artikel auf
der Einkaufsliste – gewollt, aber gut zu wissen.
- **Verleihen darf jeder** angemeldete Benutzer (es ist eine Buchung wie Ein- und
Auslagern, keine Stammdatenänderung) und wird mit dem Konto protokolliert. Nur
das *Löschen* eines Vorgangs bleibt Admins vorbehalten, weil es Historie
vernichtet.
- **Bewusst keine `Movement`-Bewegung je Verleih:** Der Verlauf rechnet den
Bestand rückwärts aus vorzeichenbehafteten Bewegungen – ein Abgang ohne
Gegenbuchung würde diese Kurve verfälschen.
- Noch offen: Oberfläche in Web und App sowie die **Rückgabe-Erinnerung**. Sie
kann nur den Weg der Ablauf-Meldungen gehen (lokale Benachrichtigung der App
aus einem Server-Snapshot, `GET /loans?due_in=…` ist dafür schon die
Datenquelle) – echtes Push fehlt weiterhin, siehe Schritt 3.
## Schritt 3 – Weitere Ideen – offen
- **Ablauf-Push-Benachrichtigungen** via APNs (setzt die App voraus).
- **Einkaufsliste verfeinern:** Abhaken dauerhaft speichern, manuelle Einträge,