Commit Graph

11 Commits

Author SHA1 Message Date
Scarriffle
788ef2caf2 Web: Zweiteinheit erfassen und anzeigen
Im Artikel-Formular eine Zeile "3 [Stk] ≙ 250 [Gramm]" mit ausgerechneter
Kontrolle darunter ("1 Stk ≈ 83,33 g"). Links steht die Basiseinheit des
Artikels fest, rechts stehen nur die anderen Arten zur Wahl - eine Bruecke auf
die eigene Art haette nichts umzurechnen. Nur vollstaendig ausgefuellt wird sie
gespeichert; Gegenstaende ohne Charge tragen keine.

buildUnitOptions laesst bei hinterlegter Bruecke auch die Einheiten der Gegenart
zu - damit erben Ein- und Auslagern die Faehigkeit ohne eigene Logik. Beim
Auslagern steht der Bestand jetzt in beiden Lesarten ("6 Stueck · 500 g").

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 00:40:33 +02:00
Scarriffle
0537a2b53f Web: Obergruppen zuordnen, Mindestbestaende nach Lagerort
Mindestbestaende-Seite ist jetzt nach Lagerort gegliedert statt nach Artikel -
"Ueberall (egal wo)" zuerst, danach die Lagerorte. Es gibt keine automatische
Leerzeile je Artikel mehr; angelegt wird ueber "+ hinzufuegen" im jeweiligen
Abschnitt, dann steht der Ort schon fest und es fehlen nur Ziel und Menge.
Das Zeilenmodell faellt damit von vier Faellen auf zwei, und weil der Server
einheitlich Basiseinheiten liefert, bleibt genau eine Umrechnung uebrig statt
der drei gegenlaeufigen von vorher.

Gruppen: neue Spalte "Obergruppen" mit Mehrfachauswahl (GroupParentSelect).
Bewusst kein Baum - CategorySelect und die tree-Prop der DataTable koennen nur
einen Elternteil und wuerden eine Gruppe mit zwei Obergruppen doppelt anzeigen.
Die eigene Gruppe und ihre Untergruppen sind in der Auswahl gesperrt, damit die
Ringregel sichtbar wird, bevor der Server sie ablehnt. Produktzahl zeigt
transitiv und direkt ("12 (3 direkt)"), dazu Badges fuer Untergruppen und eine
Warnung, wenn eine Gruppe mit Untergruppen keine Einheit hat - sonst summiert
sie Gramm und Stueck zu einer sinnlosen Zahl.

Einkaufsliste: "Gesamt" heisst "Ueberall", Gruppen zeigen ihre mitgezaehlten
Untergruppen, und eine Fussnote benennt die eine Stelle, die sich nicht
verrechnen laesst (zwei Obergruppen mit gemeinsamer Untergruppe).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 23:56:18 +02:00
Scarriffle
fd9045226b Gebinde verwalten - mit Einzahl und Mehrzahl
Bisher war die Auswahl eine fest im Frontend verdrahtete Liste und es gab nur
eine Form: ueberall stand "3 Glas".

Neu unter Verwaltung > Gebinde: anlegen, umbenennen, loeschen, jeweils mit
Einzahl und Mehrzahl. Die eingebauten Gebinde lassen sich in der Schreibweise
aendern, aber nicht loeschen; ein Gebinde, das ein Artikel verwendet, ebenfalls
nicht.

Der Artikel speichert weiterhin nur die Einzahl als Text - so bleiben
vorhandene Artikel, Sicherungen und CSV-Dateien gueltig, und eine unbekannte
Bezeichnung faellt schlicht auf die Einzahl zurueck. Deshalb zieht ein
Umbenennen die Artikel mit; sonst zeigten sie auf eine Bezeichnung, die es
nicht mehr gibt.

Die Mehrzahl greift jetzt in Artikelliste, Artikelseite (Chargen und Gebinde-
Auswahl), Auslagern und in allen Ablauf- und Einkaufslisten samt Startseite.
Einheiten wie Gramm oder Liter bleiben unveraendert - die haben im Deutschen
keine Mehrzahl.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:24:42 +02:00
Scarriffle
30307d6cfb MHD nur mit Monat und Jahr in Web-UI und iOS-App
Setzt den Backend-Umbau in beiden Oberflaechen um.

Die Genauigkeit gilt jeweils fuer den ganzen Einlager-Vorgang und nicht je
Charge: Auf einer Packung steht entweder ein Tagesdatum oder nur Monat/Jahr,
gemischt kommt das nicht vor. Vorbelegt wird sie aus dem Produkt, laesst sich
aber im Vorgang umstellen.

Web-UI: Umschalter im Kopf der Chargenliste; das Eingabefeld wechselt zwischen
type="date" und type="month". Im Produktformular gibt es das neue Feld
"MHD-Angabe" neben der Gebinde-Bezeichnung. Anzeige laeuft ueber den
Settings-Context, damit das eingestellte Datumsformat erhalten bleibt und
Monatsangaben ueberall als "09/2026" erscheinen (Auslagern, Uebersicht,
Chargentabelle). Die Abgelaufen-Warnung prueft bei Monatsangaben gegen den
Monatsletzten - sonst haette eine Packung schon am Monatsersten als abgelaufen
gegolten.

iOS: Auswahl "Tagesdatum / nur Monat/Jahr" im Einlagern-Formular und beim
Anlegen eines Artikels. SwiftUI hat keinen DatePicker ohne Tag, deshalb ein
eigener MonthYearPicker aus zwei Auswahlfeldern; die Jahresliste reicht zwei
Jahre zurueck (bereits abgelaufene Ware) und fuenfzehn nach vorn (Konserven).
Die Chargenauswahl beim Auslagern zeigt Monatsangaben ebenfalls ohne Tag.

Getestet: Web-Build (vite) und iOS-Geraetebuild laufen fehlerfrei durch, die
App ist auf dem iPhone installiert. Das Verhalten in der Oberflaeche ist noch
nicht von Hand durchgeklickt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 17:57:09 +02:00
Scarriffle
93e487a1b0 Datumsformat konfigurierbar (Einstellungen -> Darstellung)
MHD wurde in den Ansichten noch roh als YYYY-MM-DD ausgegeben. Jetzt:
- Neue Einstellung date_format (23.12.2026 | 23.12.26 | 23. Dezember 2026 |
  2026-12-23 | 12/23/2026) mit Live-Beispiel auf der Einstellungsseite.
- SettingsProvider stellt Format und formatDate() app-weit bereit und laedt die
  Einstellungen nach dem Login.
- Verwendet in Uebersicht (bald ablaufend), Produktdetail (Chargen) und
  Auslagern (Chargenauswahl). Datumsfelder zur Eingabe bleiben ISO, wie es das
  HTML-Datumsfeld verlangt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:04:01 +02:00
Scarriffle
4bb9a10366 iOS-App angefangen; Import-Modi; MHD-Formatierung; Gebinde in Ablauf-Ansichten
iOS (neu, ios/):
- SwiftUI-App: Login (Server + Keychain-Token), Kamera-Scanner (EAN/UPC/Code128),
  Einlagern mit mehreren Chargen und eigenem MHD, Auslagern mit Chargenauswahl
  oder FEFO, Artikelsuche, Anlegen mit Open-Food-Facts-Vorbefuellung.
- Home-Screen-Shortcuts: Schnellaktionen (langer Druck) und URL-Schema
  projectgood://checkin | ://checkout fuer eigene Symbole via Kurzbefehle.
- project.yml (XcodeGen) + README mit Build-Anleitung. NICHT kompiliert - auf
  diesem Rechner ist kein Xcode vorhanden.

Import-Modi (wie besprochen sinnvoll):
- add (Standard, nichts loeschen), replace_listed (Bestaende der in der Datei
  genannten Produkte ersetzen - fuer Inventur), replace_all (alles ersetzen).
  Geleerte Bestaende werden als Korrektur-Bewegung protokolliert; die Oberflaeche
  fragt bei den zerstoerenden Modi nach.

Anzeige:
- "Bald ablaufend"/"Abgelaufen" zeigen jetzt das Gebinde ("1 Glas") mit der
  Basiseinheit klein darunter (ExpiringItem liefert die Einheiten mit).
- MHD als Zeitspanne mit korrektem Numerus: "in 3 Tagen", "in 1 Woche",
  "vor 2 Wochen", dazu heute/morgen/gestern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 14:59:04 +02:00
Scarriffle
0bc141a1be Ein-/Auslagern nutzt die Artikeleinheit (Gebinde) statt fest "Packung"
- buildUnitOptions verwendet product.package_label als Beschriftung der
  Gebinde-Option (Wert bleibt intern "package").
- Beim Auswaehlen eines Artikels ist das Gebinde vorbelegt, wenn eine
  Packungsgroesse hinterlegt ist.
- Auslagern: Chargen-Dropdown und Hinweis zeigen die Menge in der Artikeleinheit
  (z.B. "MHD 2026-12-23 - 1 Glas") statt in der Basiseinheit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 13:46:14 +02:00
Scarriffle
0310cdfbd6 Verwaltbare Einheiten mit Umrechnung + Chargen bearbeiten + gezieltes Auslagern
Einheiten (neu):
- Tabelle units (name, kind=count|weight|volume, factor, is_builtin); eingebaut
  Stueck/Gramm/Kilogramm/Milliliter/Liter, Admin kann eigene anlegen (z.B. Pfund=500g).
- Bestaende bleiben intern in kanonischer Basis (Stueck/Gramm/Milliliter);
  Product.display_unit_id und Group.min_stock_unit_id als nullable FKs.
- Neuer Umrechnungs-Service (services/conversion.py) ersetzt die feste Einheitenlogik;
  Ein-/Auslagern und Gruppen-Mindestbestand rechnen ueber den Faktor.
- Gruppen-Mindestbestand mit Einheit; Gruppenbestand summiert nur Produkte
  passender Art. Neue Verwaltungsseite "Einheiten" (Admin).
- Schonende Migration beim Start: ADD COLUMN IF NOT EXISTS (Postgres), damit
  bestehende Installationen ihre Daten behalten.

Chargen:
- PATCH /lots/{id} und DELETE /lots/{id}: Menge/MHD korrigieren, Charge loeschen
  (wird als Korrektur-Bewegung protokolliert). Bearbeitung im Produktdetail.

Auslagern:
- Optionales lot_id: gezielt aus einer bestimmten Charge/MHD abbuchen statt FEFO;
  Auswahl-Dropdown in der Auslagern-Seite.

Sonstiges: Roadmap aktualisiert, Tests fuer die Umrechnung.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 12:33:14 +02:00
Scarriffle
d4e7ff8e3d Ablauf-Warnungen + Packungen-Spalte + Farbcodierung
- Backend: ProductOut.expired_count (Anzahl abgelaufener Chargen je Produkt).
- Einlagern: Inline-Warnung pro Charge, wenn MHD in der Vergangenheit liegt.
- Produkte-Liste: Badge "N abgelaufen"; neue Spalte "Packungen" (Bestand/Packungsgroesse,
  bei Stueck-Produkten = Bestand).
- Produktdetail: abgelaufene Chargen rot, Warnfrist gelb (Warnfrist aus Settings),
  Warnbanner bei abgelaufenem Bestand.
- Uebersicht: alle Ablaufzeilen gelb, abgelaufene rot; deutlicher Warnbanner.
- units.js: daysUntil/isExpired/expiryRowClass/amountText.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 11:21:14 +02:00
Scarriffle
a3dbb971f7 Fix Einkaufsliste: Mindestbestand in Packungen angebbar (Einheiten-Missverstaendnis)
Problem: min_stock wird in Basiseinheiten verglichen. Bei einem 190g-Glas (base
gram, package 190) bedeutete "min 2" 2 Gramm statt 2 Glaeser -> Produkt tauchte
nie auf der Einkaufsliste auf.

Fix:
- Produktformular: Mindestbestand wahlweise in Basiseinheit ODER Packungen
  eingebbar (mit Umrechnung); Default Packungen bei Packungsprodukten.
- ShoppingItem liefert package_size; Einkaufsliste/Dashboard zeigen Bedarf in
  Packungen (+ Basiseinheit in Klammern) via amountText().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 10:55:34 +02:00
Scarriffle
639126468f Schritt 1: Fundament der Lebensmittel-Lagerverwaltung (Pantry)
Backend (FastAPI + PostgreSQL): Chargen mit MHD, FEFO-Auslagern,
Einheiten-Umrechnung (Stueck/g/ml + Packungen), Open-Food-Facts-Lookup
mit lokalem Fallback, JWT-Auth mit Rollen (Admin/Nutzer), erster Admin
beim Setup, Einkaufsliste, Ablaufwarnung, Lagerorte, pytest fuer FEFO.

Web-UI (React/Vite): Login, Dashboard, Ein-/Auslagern, Produkte,
Lagerorte, Benutzerverwaltung, Einkaufsliste - rollenabhaengig.

Deploy: docker-compose + install.sh (Docker-Autoinstall, Secrets),
README und Roadmap fuer Schritt 2 (iOS) und Schritt 3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 09:14:14 +02:00