Commit Graph

138 Commits

Author SHA1 Message Date
Scarriffle
231d86895f Charge aufteilen: Teilmenge mit gleichem MHD an anderen Lagerort umlagern
Bisher liess sich nur die ganze Charge umlagern. Neu: POST /lots/{id}/split zweigt
eine Teilmenge (Basiseinheiten) als neue Charge mit gleichem MHD an einen anderen
Lagerort ab; der Rest bleibt. Reine Umbuchung ohne Bewegungseintrag, Gesamtbestand
unveraendert. Schutz gegen zu grosse Menge und gleichen Zielort.

Web: gemeinsamer SplitLotDialog (Menge in Artikeleinheit + Zielort, zeigt Rest),
Aufteilen-Knopf auf der Chargen-Seite und in der Chargen-Tabelle der Artikelseite.
Neues Split-Icon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-30 08:43:16 +02:00
Scarriffle
8cf7cef6e1 Web: Artikelseite nutzt volle Breite, Chargen-Tabelle bekommt mehr Platz
Die Bearbeiten-Seite war auf 1400px gedeckelt (viel Rand links/rechts) und teilte
Formular und Chargen 50/50. Jetzt nutzt sie die volle Breite (wie die Listen) und
das Grid ist gespiegelt zu .wide-aside: links das schmale Formular (clamp bis
640px), rechts die Chargen-/Bestandstabelle mit dem Restplatz - so passen
Menge/MHD/Lagerort ohne Seitwaerts-Scrollen. Neuanlage bleibt einspaltig.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 18:52:30 +02:00
Scarriffle
e28b6a5e38 Web: Mindestbestaende per Loesch-Knopf entfernbar
Loeschen ging bisher nur uebers Leeren des Zahlenfeldes - das war weder
auffindbar noch (bei Gesamt-Werten, deren Zeile bestehen bleibt) sichtbar.
Jetzt hat jede gesetzte Zeile einen Papierkorb-Knopf: Gesamt-Wert -> NULL,
je-Lagerort-Eintrag faellt raus. Mit Rueckfrage ueber den App-Dialog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 17:12:57 +02:00
Scarriffle
bfc52997dc Web: Mindestbestand je Lagerort laesst sich anlegen (mergeLoc ergaenzt neue Orte)
Der Endpunkt ersetzt die komplette Lagerort-Liste; mergeLoc iterierte aber nur
ueber bestehende Eintraege und liess neue Orte weg. Dadurch entstand nie ein
neuer je-Lagerort-Mindestbestand, wenn nur ein Gesamt-Wert (leere Ortsliste)
oder ein Eintrag an einem anderen Ort existierte. Jetzt wird ein fehlender Ort
ergaenzt und der Abgleich per String() unabhaengig vom id-Typ gemacht.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 17:04:14 +02:00
Scarriffle
66a52bfecb Web: Scrollleisten ans Theme angepasst
Scrollbare Karten/Tabellen zeigten die helle System-Scrollleiste. Jetzt eine
dezente, theme-abhaengige Scrollleiste (Variablen border-strong/muted, hell wie
dunkel) - schlanker Daumen mit runden Enden, transparente Spur.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 15:20:22 +02:00
Scarriffle
18c07eaf3a Web: Chargenseite - Spalte "Art" (Lebensmittel/Gegenstand)
Neue sortier-/filterbare Spalte zeigt je Charge, ob es ein Lebensmittel oder ein
Gegenstand (Verbrauchsgegenstand) ist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 14:13:22 +02:00
Scarriffle
5550897319 Web: Chargen per Klick auf die ganze Zeile auswaehlen
Nicht nur die kleine Checkbox schaltet die Auswahl, sondern ein Klick irgendwo
in die Zeile (ausser auf Bedienelemente wie Lagerort-Dropdown/Link). Ausgewaehlte
Zeilen werden hervorgehoben. Neuer DataTable-Prop onRowClick.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 14:08:12 +02:00
Scarriffle
51c02091ed Web: Chargen auswaehlen und Lagerort der Auswahl setzen
Chargenliste bekommt Auswahl-Checkboxen. Das obere Panel wirkt jetzt auf die
Auswahl: "N ausgewaehlt -> Lagerort setzen" (leer = Ort entfernen, z.B. beim
Aufloesen eines Orts). Schnellwahl "alle sichtbaren" (respektiert Filter) und
"alle ohne Lagerort". DataTable meldet dafuer die sichtbaren Zeilen
(onVisibleRows).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 14:04:19 +02:00
Scarriffle
826f4df4bd Web: Chargenliste (mit Sammel-Lagerort) + Ladezustand auf allen Tabellen
Neue Seite "Chargen": alle Chargen ueber alle Artikel (Artikel, Menge, MHD,
Lagerort, eingelagert). Lagerort je Zeile direkt aenderbar; alle Chargen ohne
Ort per Klick zuweisbar (bulk-location) - gut, wenn der Lagerort erst spaeter
angelegt wurde.

DataTable bekommt einen loading-Prop: waehrend des Ladens steht "Wird geladen..."
statt der Leer-Meldung. Auf ALLEN Tabellen angewendet (Produkte, Mindestbestaende,
Kategorien, Gruppen, Einheiten, Gebinde, Einzelstuecke, Chargen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 13:58:07 +02:00
Scarriffle
227143d13f Web: Chargen zeigen ihren Lagerort (und lassen ihn aendern)
Die Chargen-Tabelle hatte keine Lagerort-Spalte - dadurch wirkte es, als koenne
man Chargen keinem Ort zuordnen (geht laengst ueber den Lagerort beim Einlagern).
Neue Spalte "Lagerort" zeigt den Ort je Charge; beim Bearbeiten laesst er sich
per Dropdown aendern (z.B. 2 Glaeser Pesto in Schrank A, 2 in Schrank B).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 13:41:19 +02:00
Scarriffle
d448754d2a Web: Lagerort-Inhalt ansehen + von dort einlagern
Der Lagerort-QR (/l/<code>) zeigt jetzt, was am Ort (inkl. Unterorte) liegt -
Artikel mit Bestand, jeweils verlinkt - statt nur den Namen. "Hier einlagern"
springt ins Einlagern mit vorbelegtem Lagerort (?location=). In der Lagerorte-
Verwaltung fuehrt ein neues Lupensymbol zur Inhaltsansicht.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 13:37:34 +02:00
Scarriffle
4034b97cf3 Web: Produktlisten zeigen "wird geladen" statt "keine Produkte" beim Laden
Bisher stand sofort "Keine Produkte gefunden." da, obwohl noch geladen wurde.
Jetzt ein Ladezustand: Kopf zeigt "Wird geladen...", Tabelle "Produkte werden
geladen...", und die Leer-Meldung kommt erst, wenn der Server wirklich nichts
liefert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 12:07:12 +02:00
Scarriffle
f96286b3fa Web: Gegenstaende-Liste - Spalte/Filter "Verwaltung"
Neue Spalte "Verwaltung" (nur in der Gegenstaende-Liste): Menge je Lagerort /
Einzelstuecke / Verbrauchsgegenstand - sortier- und filterbar wie die anderen
Spalten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 15:40:21 +02:00
Scarriffle
03c0f4043d Web: Filter und Sortierung der Tabellen bleiben erhalten
Bisher gingen Filter + Sortierung beim Navigieren (Produkt -> zurueck) verloren.
Jetzt werden sie wie Spaltenreihenfolge/-breiten je Tabelle im Browser
gespeichert (Sets als Arrays serialisiert) und bleiben bis "Filter loeschen"
bzw. bis man anders sortiert. Gilt automatisch fuer alle DataTable-Tabellen.
"Spalten zuruecksetzen" laesst Filter/Sortierung unangetastet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 11:45:49 +02:00
Scarriffle
31137cd884 Web: Spalte "Zuletzt geaendert" in den Produktlisten
Neue sortier- und filterbare Spalte (Datum + Uhrzeit) in Lebensmittel- und
Gegenstaende-Liste, basierend auf Product.updated_at. Nuetzlich, um zuletzt
angelegte/geaenderte Artikel zu finden (z.B. mit fehlender Kategorie). Erscheint
automatisch, laesst sich per Spaltenauswahl aus-/einblenden und umsortieren.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 11:36:47 +02:00
Scarriffle
4141781ffb Web: Foto schon beim Anlegen eines Produkts hinterlegen
Bisher ging ein Foto erst nach dem Speichern (Produkt-ID noetig). Jetzt kann man
beim Neuanlegen direkt "Foto machen"/"Galerie" nutzen - das Bild wird vorgemerkt,
als Vorschau gezeigt und nach dem Anlegen hochgeladen. Nuetzlich, wenn Open Food/
Products Facts kein Bild liefert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 10:28:56 +02:00
Scarriffle
3ff7d2a35a Web: Mindestbestand je Lagerort im Formular in echter Einheit
Der je-Lagerort-Editor (foodLike) zeigt und speichert jetzt in der Anzeigeeinheit
(Gramm/Milliliter/Stueck) statt in Packungen - konsistent zur Mindestbestaende-
Seite. Umrechnung Artikeleinheit<->Anzeigeeinheit an der Formular-Grenze.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 09:02:10 +02:00
Scarriffle
49a96d7fdb Web: Mindestbestand nur fuer Charge-Artikel (Lebensmittel + Verbrauchsgegenstand)
Menge je Lagerort und Einzelstuecke haben keinen Mindestbestand mehr: die
"Mindestbestand (Stueck)"-Felder und der je-Lagerort-Block fallen im Formular
weg (Gruppe fuer Menge bleibt), Alt-Werte werden beim Speichern geleert. Die
Mindestbestaende-Seite und der "+ hinzufuegen"-Dialog zeigen nur noch
Charge-Artikel.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 08:54:50 +02:00
Scarriffle
275611160b Web: Mindestbestaende in echter Einheit statt Packung
"1 Packung" ist nichtssagend (kann 500 g, 1 kg oder 25 ml sein). Die Seite zeigt
und bearbeitet Produkt-Mindestbestaende jetzt in der Anzeigeeinheit des Artikels
(Gramm/Milliliter/Stueck): global (Basiseinheiten) und je Lagerort (Artikel-
einheiten) werden dafuer umgerechnet. Rigatoni zeigt jetzt z.B. "500 Gramm".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 08:48:32 +02:00
Scarriffle
f0c64466e2 Web: Mindestbestaende-Bestand zeigt richtige Einheit ("1 Packung" statt "1 Gramm")
articleLabel fiel bei leerem Gebinde-Namen auf die Basiseinheit zurueck, waehrend
articleUnit durch die Packungsgroesse teilt. Dadurch stand z.B. bei Rigatoni
"1 Gramm" statt "1 Packung" (500 g). Label ist jetzt an die Packungsgroesse
gekoppelt und passt zur Zahl.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 08:39:03 +02:00
Scarriffle
c28ac7d7dd Web: Kategorie-Auswahlfeld zeigt Oberkategorien der gewaehlten Kategorie
Im geschlossenen Feld stand nur das Blatt (z.B. "Fruechte") - bei mehreren
gleichnamigen Kategorien war unklar, welche gemeint ist. Jetzt steht der volle
Pfad drin, Oberkategorien klein/subtil davor (z.B. "TK -> Fruechte"), das Blatt
normal - ohne das Dropdown oeffnen zu muessen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 21:38:16 +02:00
Scarriffle
24ea55c396 Web: Barcode-Feld nicht mehr von den Knoepfen zusammengequetscht
Barcode-Eingabe behaelt eine Mindestbreite; die Knoepfe (Nachschlagen /
Vergleichen) brechen bei Platznot in die naechste Zeile um.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 21:27:16 +02:00
Scarriffle
46f9c69a39 Web: "Neue Kategorie"-Button auf Hoehe des Auswahlfelds
Eigene unsichtbare Beschriftungszeile ueber dem Knopf, damit er auf gleicher
Hoehe wie das Kategorie-Auswahlfeld beginnt - statt am oberen oder unteren
Zeilenrand zu kleben.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 21:23:38 +02:00
Scarriffle
8d34e2e8d8 Web: "Neue Kategorie"-Button an das Kategorie-Feld ausrichten
Button per align-self unten buendig zum Auswahlfeld (stand vorher am oberen
Zeilenrand). Gruppen-Tooltip auf "mehrerer Artikel" verallgemeinert, da jetzt
auch Gegenstaende gruppierbar sind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 21:19:18 +02:00
Scarriffle
f287f8f768 Web: zentrale Mindestbestaende per "+ hinzufuegen" anlegen
Neuer Dialog auf der Mindestbestaende-Seite: Ziel (Produkt/Gegenstand oder
Gruppe) -> Geltung (Gesamt oder Lagerort) -> Menge in der Einheit des Ziels.
Speichert ueber die vorhandenen Endpunkte (updateProduct/updateGroup bzw.
set*LocationMinStock).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 20:41:57 +02:00
Scarriffle
4087277bb0 Web: Verbrauchsgegenstand als dritte Gegenstands-Art + Typ-Position + Thumbnail
ProductForm: Typ/Kategorie an feste Position (nach Marke, vor den typ-
spezifischen Feldern) - der Umschalter springt nicht mehr je nach Auswahl.
Gegenstaende bekommen eine 3-Wege-Verwaltung: Menge je Lagerort /
Einzelstuecke / Verbrauchsgegenstand. Verbrauchsgegenstaende werden wie
Lebensmittel als Charge (Einheit, Packung, MHD, Mindestbestand mit Einheit,
Gruppe, Chargen-Ansicht) gefuehrt (foodLike = kein Gegenstand ODER bulk).
Menge-Gegenstaende koennen jetzt ebenfalls einer Gruppe zugeordnet werden.

Thumbnail: .thumb display:block, damit die Zeilenhoehe beim Nachladen nicht
mehr minimal springt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 20:39:15 +02:00
Scarriffle
1dc249eb79 Mindestbestand auch fuer Gegenstaende (Web-Formular + iOS)
Gegenstaende (Verbrauchsmaterial wie Sonnencreme) koennen jetzt einen Mindestbestand haben - im Web-Produktformular ein Gesamt-Feld (Stueck) plus Mindestbestand je Lagerort, auf iOS ein Gesamt-Feld in der Detailansicht. Umrechnung wie bei Lebensmitteln (fuer Stueck-Artikel = Stueckzahl); iOS sendet min_stock nur bei Gegenstaenden, damit Lebensmittel-Modi unberuehrt bleiben. Backend/Einkaufsliste unterstuetzen das bereits. Namen (Lebensmittel/Gegenstaende) bleiben.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 19:48:41 +02:00
Scarriffle
c52e88f856 Web: Thumbnails cachen (kein Neuladen) + feste Zeilenhoehe
Artikelbilder werden modulweit gecacht (Produkt-ID+Version -> Objekt-URL, auch 'kein Bild'); beim erneuten Oeffnen einer Liste werden sie nicht mehr jedes Mal neu geholt. Der Platzhalter (.thumb-fallback) hat jetzt dieselbe feste Groesse (34x34) wie das Bild, damit die Zeilenhoehe mit/ohne Bild gleich ist und beim Nachladen nicht mehr springt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 19:32:59 +02:00
Scarriffle
189b1f8e6b Web: zentrale Mindestbestand-Liste (Produkte + Gruppen, Gesamt + je Lagerort)
Neue Seite 'Mindestbestaende' (Sidebar): filterbare Tabelle mit je einer Zeile pro Mindestbestand - Gesamt je Produkt/Gruppe und je Lagerort - inline editierbar. Produkt-Gesamtwert wird nicht-destruktiv umgerechnet (Faktor aus dem bestehenden Wert abgeleitet, sonst Artikeleinheit); Lagerort-Bedarfe und Gruppenwerte ueber die vorhandenen Endpunkte. Nur-Lesen fuer Nicht-Admins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 19:00:33 +02:00
Scarriffle
912f3dac6f Web: Lebensmittel-Icon (Apfel) + mehr Abstand vor 'Typ' im Produktformular
Eigenes food-Icon fuer den Lebensmittel-Sidebar-Eintrag (statt des Sechsecks). Der Block 'Mindestbestand je Lagerort' bekommt Abstand nach unten, damit er nicht am Typ-Umschalter klebt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 18:42:12 +02:00
Scarriffle
01a3528227 Web: Produkte in Lebensmittel/Gegenstaende getrennt; Spalten-Labels; Produktformular aufgeraeumt
1) Zwei getrennte Sidebar-Eintraege 'Lebensmittel' und 'Gegenstaende' (Products mit fixedType) statt einem 'Produkte' mit Umschalter - so vermischt sich nichts. 2) Spalten-Waehler zeigt sprechende Labels ('Bild' statt 'thumb', 'Aktionen', ...). 3) Produktformular: leerer Grow-Platzhalter unter 'Typ' entfernt und 'Neue Kategorie' direkt neben das Kategorie-Dropdown gruppiert; Formular wieder auf Lesebreite (kein content--wide), da das Layout-Problem intern war.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 18:26:41 +02:00
Scarriffle
e2d2347524 Web: DataTable - Spalten ein-/ausblenden (Spalten-Waehler)
Neuer 'Spalten'-Button in der Tabellen-Toolbar oeffnet ein Popover mit einer Checkbox je Spalte. Abgewaehlte Spalten werden ausgeblendet (Kopf, Filterzeile, Zellen), wieder anhaken zeigt sie an alter Position. Die Auswahl merkt sich der Browser (localStorage, je Tabelle), mindestens eine Spalte bleibt sichtbar, 'Spalten zuruecksetzen' zeigt wieder alle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 17:58:01 +02:00
Scarriffle
08ee1f20f5 Web: Kategorie-Filter - Oberkategorie subtil + als eigener Eintrag waehlbar
Die DataTable kann jetzt je Spalte mehrere Filter-Werte pro Zeile (filterValues/Tokens) und eine eigene Option-Darstellung (filterOptionLabel). Die Kategorie-Spalte liefert als Tokens jede Ebene kumuliert (Klamotten, Klamotten -> kurze Hosen); so erscheint die Oberkategorie als eigener, anklickbarer Eintrag und selektiert alle Unterkategorien. Ober-Ebenen werden in Zelle und Dropdown kleiner/gedaempft dargestellt (CategoryPathLabel), das Blatt normal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 17:44:38 +02:00
Scarriffle
487c5f5f38 Web: Kategorie-Filter mit vollem Pfad (Oberkategorie findet Unterkategorien)
Der Kategorie-Spaltenfilter zeigte nur die Blatt-Kategorien, die an Produkten haengen - die Oberkategorie (z.B. 'Klamotten') fehlte, obwohl darunter (kurze Hosen, T-Shirts) etwas eingelagert ist. Kategorie wird jetzt als voller Pfad 'Klamotten -> kurze Hosen' gefuehrt; Freitext 'Klamotten' findet damit alles darunter. Betrifft Produkt- und Einzelstueckliste. (Lagerorte nutzen den Pfad bereits.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 17:13:11 +02:00
Scarriffle
76dc29ac72 Web: Filter-Dropdown und Spalten-Resize gefixt
1) Die Checkboxen im Filter-Dropdown erbten die globale input-Regel (width:100%, Rahmen, margin) und sprengten die Zeile - jetzt zurueckgesetzt, Label fuellt die Breite links. 2) Beim Breiterziehen einer Spalte schrumpfte die flexible (grow-)Spalte, wodurch die Nachbarspalte schmaler wurde und alles nach links wanderte. Die grow-Spalte wird beim Start des Ziehens auf ihre Pixelbreite eingefroren; danach verhalten sich die Spalten unabhaengig wie in Excel.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 15:16:35 +02:00
Scarriffle
050496a82d Web: Kategorien (Baum), Gruppen, Einheiten, Gebinde auf DataTable
Restliche Tabellenseiten auf die filterbare DataTable umgestellt. Kategorien nutzen den neuen Tree-Modus (ein-/ausklappbar wie bisher; sobald gefiltert/sortiert wird, flache Liste). Inline-Bearbeitung (Namen, Art, uebergeordnet, Mindestbestand, Gebinde-Formen) bleibt in den Zell-Renderern erhalten; Seiten-Formulare/Panels unveraendert. Damit haben Produkte, Einzelstuecke, Kategorien, Gruppen, Einheiten und Gebinde die gleiche Filter-/Spalten-Bedienung.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 15:10:00 +02:00
Scarriffle
ffbe33bec4 Web: Produkt-Seite nutzt die volle Breite (content--wide)
Die Produkt-Detail-/Anlege-Seite war auf 1400px gedeckelt; ihr zweispaltiges Layout (Formular + EAN-Codes/Chargen) wurde dadurch auf breiten Monitoren gequetscht. Jetzt volle Breite wie die uebrigen Tabellenseiten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 15:00:33 +02:00
Scarriffle
6b7ada33b3 Einzelstueck-Liste: Web-Seite /items + iOS-Liste (filterbar nach Lagerort)
Neue Seite 'Einzelstuecke' (Web, /items, in der Sidebar) listet alle physischen Exemplare ueber alle Produkte in der DataTable - je Spalte filterbar (Lagerort als Pfad, Produkt, Kategorie, Shop, ...), Lagerort und Shop inline aenderbar. iOS bekommt dieselbe Liste als schlichte, filterbare Ansicht (Kachel unter 'Listen'): Suche + Lagerort-/Kategorie-Filter, Tippen oeffnet das Einzelstueck. Item-Model/ItemOut um Kategorie ergaenzt; neuer APIClient.allItems().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 14:58:03 +02:00
Scarriffle
76acf57edf Web: Excel-artige DataTable + volle Breite; Produkte migriert
Neue wiederverwendbare DataTable: feste Filterzeile je Spalte (Freitext + Dropdown der vorhandenen Werte, ueber Spalten kombinierbar), Spalten per Drag verschieben und in der Breite ziehen, Klick-Sortierung; Reihenfolge/Breiten merkt der Browser (localStorage). Produkte-Seite darauf umgestellt. Tabellenseiten (Produkte/Kategorien/Gruppen/Einheiten/Gebinde) nutzen jetzt die volle Fensterbreite (content--wide); Kategorien-Seitenspalte etwas breiter und die Feldliste bricht um, statt ueber den Container zu laufen. Farbschema unveraendert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 14:53:05 +02:00
Scarriffle
4887596b43 Web: Artikelbild per Klick gross anzeigen (Lightbox)
Klick aufs Artikelbild oeffnet es bildschirmfuellend; Schliessen per Knopf, Klick auf den Hintergrund oder Escape. Neue Lightbox-Komponente (Portal an <body>), im bestehenden Farbschema.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 14:44:43 +02:00
Scarriffle
34149ff633 Dashboard nutzt die volle Breite (Lesebreiten-Cap nur fuer andere Seiten)
Die .content-Spalte war global auf max-width 1400px gedeckelt - gut fuer Tabellen/Formulare, aber das Dashboard-Raster klebte dadurch auf breiten Bildschirmen links mit viel Leerraum. Die Dashboard-Routen bekommen jetzt .content--wide (max-width: none), sodass das Raster (react-grid-layout, WidthProvider) die ganze Breite ausmisst und fuellt. Andere Seiten bleiben auf Lesebreite.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 14:01:37 +02:00
Scarriffle
5991a807d2 Einzelstueck-Anlegen: Preis-Vorschlag in eigene Zeile statt in die Preiszeile gequetscht
Der 'Preis-Vorschlag aus Beleg' stand mit Kaufpreis, Waehrung und Datei-Auswahl in einer Zeile und wirkte gequetscht. Jetzt bleibt die Preiszeile zweispaltig (Kaufpreis | Beleg) und der Vorschlag bekommt eine eigene Zeile darunter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 13:43:32 +02:00
Scarriffle
c8c1686395 Amazon-Kaufdatum erkennen; Preis-Vorschlaege beim Anlegen; Lagerort-Dropdowns mit Pfad
1) Beleganalyse erkennt Datumsangaben mit Monatsnamen (DE+EN, z.B. Amazon 'Bestelldatum 29 April 2026'), nicht nur 29.04.2026 - so wird das Kaufdatum solcher Rechnungen gefunden. 2) Beim direkten Anlegen eines Einzelstuecks mit Beleg werden jetzt alle erkannten Preise als Vorschlag angeboten (Dropdown), statt stillschweigend nur den wahrscheinlichsten zu nehmen. 3) Alle Lagerort-Dropdowns zeigen den vollen Pfad (Hedingen -> Keller -> Schublade 1) statt nur den Namen, damit gleichnamige Orte unterscheidbar sind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 13:24:08 +02:00
Scarriffle
4607e3a6a8 Lagerort-Auswahl zeigt gewaehlten uebergeordneten Ort wieder an
CategorySelect wandelte den Wert per Number() um - bei den neuen Lagerort-Codes (Zeichenkette) ergab das NaN, sodass die Anzeige auf 'keiner' zuruecksprang, obwohl korrekt gespeichert wurde. Wert jetzt unveraendert nehmen und typunabhaengig (String-Vergleich) markieren, damit Zahl-IDs (Kategorien) wie Code-IDs (Lagerorte) passen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 12:22:57 +02:00
Scarriffle
d518b4aa23 Lagerorte per 10-Zeichen-Code statt fortlaufender ID; iOS-Einlagern ohne Kamerazwang
Lagerort-IDs sind jetzt ein zufaelliger 10-Zeichen-Code (wie die Einzelstueck-UIDs) statt einer fortlaufenden Zahl - so kollidiert die Stammdaten-Sicherung zwischen zwei Instanzen praktisch nie mehr, und der Code ist zugleich der Inhalt des QR /l/<code>. Alle Fremdschluessel (lots, movements, items, Mindestbestaende, parent_id) ziehen mit; die Umstellung laeuft einmalig und transaktional beim Serverstart (_migrate_locations_to_code) und rollt bei Fehlern komplett zurueck. Vor dem Deploy ein DB-Backup machen.

iOS-Einlagern oeffnet nicht mehr sofort die Kamera, sondern ein Formular mit Artikelsuche; die Kamera kommt erst per Button. Im Formular laesst sich der Lagerort zusaetzlich per /l/-QR scannen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 12:15:25 +02:00
Scarriffle
6e48cd0a7a Stammdaten-Export/Import (JSON) + Lagerort-Eltern bleibt beim Anlegen
- Backend: services/master_data.py exportiert/importiert Kategorien (inkl.
  eigener Felder), Lagerorte, Einheiten und Gebinde als JSON – MIT IDs, damit
  gedruckte QR-Codes und Verweise nach dem Wiederherstellen passen. Import-Modus
  skip (Vorhandenes lassen) oder overwrite (per ID aktualisieren); Namens-
  Konflikte werden uebersprungen, nicht abgebrochen. Postgres-Sequenzen werden
  danach angehoben. Endpunkte GET /export/master-data, POST /import/master-data.
  5 neue Tests, Suite 162 gruen.
- Web: neue Karte "Stammdaten sichern & wiederherstellen (JSON)" in Import/Export.
- Web: beim Lagerort-Anlegen bleibt der uebergeordnete Ort in der Auswahl.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 11:17:14 +02:00
Scarriffle
636982f6c7 Web: Lagerort-Etiketten-CSV-Export (P-touch), wie bei Einzelstücken
Neuer Abschnitt in Import/Export: exportiert je Lagerort eine Zeile
(QR-Inhalt = Link auf den Ort, ID, Name, Pfad "Hedingen → Keller") als CSV mit
demselben wählbaren Trennzeichen wie der Einzelstück-Export und derselben
Formel-Injektion-Härtung. Client-seitig aus den Lagerorten gebaut.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 10:56:33 +02:00
Scarriffle
625b6ee263 Lagerorte: Baum-Picker beim Anlegen; Unter-Ort-Bestand zählt zum Bedarf
- Web: der übergeordnete Lagerort wird beim Anlegen jetzt über den
  aufklappbaren Baum (CategorySelect) gewählt statt über das flache Dropdown.
- Backend: Mindestbestand je Lagerort wird jetzt gegen den Bestand INKL. aller
  Unter-Lagerorte geprueft. Ein Bedarf auf „Hedingen" gilt also als gedeckt,
  wenn der Vorrat in „Hedingen -> Keller" liegt. Helfer
  location_subtree_stock_base; 2 neue Tests, Suite 157 gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 10:50:31 +02:00
Scarriffle
4e7512b4bc Web: Kaufpreis + Beleg schon beim Anlegen; Kaufdatum/Shop-Vorschlag
- Anlege-Maske: Kaufpreis (+Währung) und Beleg-Upload. Beim Datei-Auswählen wird
  der Beleg analysiert (ohne Speichern) und Kaufdatum/Garantie/Preis/Shop
  vorbefuellt; ein erkannter, noch nicht hinterlegter Shop wird beim Anlegen
  erstellt. Der Beleg haengt an das erste angelegte Stueck.
- Beleg-Vorschlag (bestehende Stuecke) zeigt/uebernimmt jetzt auch Kaufdatum und
  Shop (bekannter Shop zuweisen, sonst anlegen).
- API analyzeItemDocument.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 09:36:25 +02:00
Scarriffle
dff7677e50 Web: Mindestbestand je Lagerort + Einkaufsliste je Ort
- Neuer LocationMinStock-Editor (Zeilen: Lagerort + Menge, separat speichern).
- Produktformular: Abschnitt „Mindestbestand je Lagerort" (Menge in Artikel-
  einheit), zusaetzlich zum Gesamt-Mindestbestand.
- Gruppen: je Gruppe ein Editor „Mindestbestand je Lagerort".
- Einkaufsliste: Abschnitt „Bedarf: <Lagerort>" mit Produkten und Gruppen, die
  am Ort unter dem dort hinterlegten Mindestbestand liegen.
- API-Methoden set*LocationMinStock und shoppingByLocation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 07:12:59 +02:00