c532492286c256f48a7ee1857a631295ebe4e86a
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
65b0792148 |
iOS-Scan: Text nennt beide Produkt-Datenbanken
Der Barcode-Lookup fragt schon immer beide Quellen ab (Open Food Facts und Open Products Facts, ueber /products/lookup). Die Scan-Ansicht sprach aber nur von "Open Food Facts" und liess es so wirken, als wuerde nur dort gesucht. Texte neutralisiert bzw. beide Quellen genannt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
b2a38501d2 |
Vorgeschlagene Kategorie wird uebernommen, nicht nur angezeigt
Beim Scannen stand auf der Karte "Kategorie ... vorgeschlagen", im Formular war das Feld danach trotzdem leer - man musste dieselbe Kategorie von Hand nochmal auswaehlen. Der Vorschlag war damit wertlos: Wer weiss, dass Pesto eine Sosse ist, gewinnt nichts daraus, es dem Formular noch einmal zu erzaehlen. Die Ursache lag nicht am Server. Der Lookup liefert category_id und category_name; die App merkte sich aber nur den Namen fuer die Anzeige und warf die ID weg. ProductFormView bekam sie gar nicht erst gereicht - anders als die Gruppe, die schon immer uebernommen wurde. Die Web-Oberflaeche macht es seit jeher richtig (setNewCategoryId in pages/CheckIn.jsx), nur die App nicht. Jetzt wird die ID durchgereicht und wie die Gruppe vorbelegt. Aenderbar bleibt sie: Gespeichert wird ohnehin erst mit "Anlegen & weiter". Der Hinweis auf der Karte heisst deshalb nicht mehr "vorgeschlagen", sondern "wird zugeordnet" - das war vorher richtig und waere es jetzt nicht mehr. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
158196f67b |
Gruppen und Kategorien getrennt, EAN-Codes an der Gruppe automatisch gefuehrt
Die Umbenennung von Gruppen in "Kategorien" war falsch: Es sind zwei
verschiedene Dinge. Sie ist zurueckgenommen, Kategorien kommen als eigene Ebene
dazu.
GRUPPE zaehlt Bestaende mehrerer Marken zusammen - Mehl von Rewe, Aldi und
Migros ergeben "5 kg Mehl". Dafuer Mindestbestand mit Einheit und EAN-Codes.
KATEGORIE ordnet allein die Artikelliste ("zeig mir alle Suesswaren"), ist
verschachtelbar wie ein Lagerort und hat weder Bestand noch EAN-Codes. Ein
Artikel kann beides, eines oder keines haben.
Die Vermischung war aelter als die Umbenennung: guessGroup in offUtils.js hat
aus der Open-Food-Facts-KATEGORIE eine GRUPPE geraten. Das ist entfernt. Die
OFF-Einordnung steuert jetzt die Kategorie, wo sie hingehoert; eine Gruppe
entsteht nur ueber einen hinterlegten Gruppen-Code oder bewusste Auswahl.
EAN-Codes an der Gruppe: Das war kein Anzeigefehler. Beim Anlegen eines Artikels
wurde ausschliesslich group_id gesetzt - ein Gruppen-Code entstand nie, die
Liste war tatsaechlich leer. Die Meldung "bereits vergeben" kam daher, dass der
Code am Artikel hing. Jetzt pflegt services/group_codes.py den Code mit: beim
Zuordnen kommt er hinzu, beim Gruppenwechsel wandert er mit, beim Entfernen der
Gruppe oder Loeschen des Artikels verschwindet er. Beim Scannen aendert sich
nichts an der Reihenfolge - der Artikel wird weiterhin zuerst gefunden; der
Gruppen-Eintrag ist Beleg in der Verwaltung und Rueckfall. Traegt man denselben
Code von Hand nach, ist das kein Fehler mehr, sondern die Auskunft, dass er ueber
den Artikel bereits dort steht.
Kategorien im Backend: neue Tabelle mit parent_id (Muster von Location),
products.category_id per ADD COLUMN IF NOT EXISTS nachgezogen, deutsche
zweistufige Startliste analog zu den eingebauten Einheiten. Die Startliste wird
nur angelegt, wenn ueberhaupt noch keine Kategorie existiert - wer sie bewusst
leerraeumt, findet sie nicht wieder. Beim Setzen einer Oberkategorie wird
geprueft, dass keine Kategorie sich selbst oder einem eigenen Nachfahren
untergeordnet wird; sonst entstuende ein Ring und jede Baumdarstellung liefe
endlos. Der Produktfilter schliesst Unterkategorien ein, category_id=0 liefert
die Artikel ohne Kategorie. Export und Import fuehren die Kategorie als Pfad
("Suesswaren & Snacks > Schokolade") in einer Spalte, damit die CSV in Excel
bedienbar bleibt.
Web: neue Seite Kategorien mit Baumdarstellung, Filter ueber der Produktliste,
getrennte Auswahlfelder im Produktformular mit je einer Zeile Erklaerung, und
beim Einlagern laesst sich eine Gruppe samt Einheit und Mindestbestand direkt
anlegen, ohne den Vorgang zu verlassen.
iOS: Kategorie-Filter ueber der Produktliste, Unterkategorien eingerueckt. Die
Artikelzeile nennt jetzt das Gebinde und warnt, wenn der Mindestbestand
unterschritten ist (rot) oder weniger als ein Viertel Luft bleibt (orange).
Getrennte Auswahlfelder fuer Kategorie und Gruppe, Gruppe direkt anlegbar.
Ausserdem die Eingabefelder in der App: .textFieldStyle(.roundedBorder) zeichnet
in der dunklen Darstellung einen fast schwarzen Kasten. Ersetzt durch eine
Systemfuellung, die sich Hell und Dunkel anpasst und zurueckhaltend bleibt.
Getestet: 54 pytest-Tests gruen, 14 davon neu (Nachfahren-Sammler, OFF-Zuordnung
inklusive Vorrang der Unterkategorie, und die komplette Codepflege an der
Gruppe). Gegen die laufende API geprueft: Startliste ohne Dubletten, Filter auf
Ober- und Unterkategorie, Ringschutz, Loeschen einer Kategorie laesst Artikel
und Unterkategorien bestehen, Export/Import-Rundlauf mit Kategoriepfad, und der
Durchlauf aus der Meldung - Artikel mit Gruppe anlegen, Code steht danach in der
Gruppe. Web-Build und iOS-Geraetebuild fehler- und warnungsfrei.
Die Oberflaechen habe ich nicht selbst bedient.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
8dcc17b22f |
EAN-Codes einer Kategorie nachvollziehbar gemacht
Eine Kategorie mit Artikeln zeigte "0 EANs", und der Versuch, den Code eines eigenen Artikels einzutragen, scheiterte mit "Dieser Code ist bereits vergeben". Beides war fachlich richtig, aber nirgends erklaert. Hintergrund: Die Code-Liste einer Kategorie ist eine Vorratsliste fuer Artikel, die es noch nicht gibt. Sie greift nur, wenn beim Einlagern ein unbekannter Code gescannt wird - dann landet der neu angelegte Artikel in dieser Kategorie (routers/products.lookup). Haengt ein Code bereits an einem Artikel, findet die Suche immer zuerst den Artikel; ein gleichlautender Kategorie-Eintrag koennte nie wirken. Die Spalte zaehlte bisher ausschliesslich diese Vorratscodes, nie die Codes der enthaltenen Artikel - daher die irritierende 0. Die Kategorie liefert jetzt zusaetzlich die Codes ihrer Artikel mit (product_barcodes, rein informativ). Beide Herkuenfte stehen in einer Liste: Artikel-Codes sind als solche gekennzeichnet, nennen den Artikel und lassen sich hier nicht loeschen, weil sie am Artikel haengen. Bewusst ohne Dublette in der Datenbank - ein zweiter Datensatz koennte nie greifen und beim Loeschen des Artikels verwaisen. Die Spalte zaehlt beide Herkuenfte. Die Fehlermeldung sagt jetzt, wem ein Code gehoert: beim Artikel mit Namen und dem Hinweis, dass Artikel-Codes hier nicht eingetragen werden muessen; bei einer anderen Kategorie mit deren Namen. Signal beim Einlagern: Wird ein Code erkannt, der einer Kategorie zugeordnet ist, steht jetzt deutlich sichtbar "Wird automatisch der Kategorie X zugeordnet" samt Begruendung - sowohl im Web als auch in der App, und in beiden Faellen (Open-Food-Facts-Treffer und voellig unbekannter Code). Nach dem Anlegen meldet die Web-Oberflaeche zurueck, welche Kategorie es geworden ist. Vorher stand die Zuordnung nur als Nebensatz in grauer Kleinschrift. Getestet: Gegen die laufende API geprueft, dass eine Kategorie die Codes ihrer Artikel meldet (Haupt-Barcode und zusaetzliche Alias-Codes), dass das Eintragen eines Artikel-Codes und eines fremden Kategorie-Codes mit der jeweils richtigen Begruendung abgewiesen wird und dass ein echter Vorratscode weiterhin angelegt werden kann. iOS-Geraetebuild und Web-Build fehlerfrei, 40 pytest-Tests gruen. Dabei zwei Uebersetzungsfehler durch deutsche Anfuehrungszeichen gefunden: Das schliessende Zeichen war ein gerades ", das den String vorzeitig beendete. Korrigiert und die uebrigen Vorkommen im Projekt gleich mit vereinheitlicht. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
47ca4802aa |
Darstellung der App nachgebessert, Gruppen heissen jetzt Kategorien
Die App zeigte an mehreren Stellen Rohwerte statt lesbarer Angaben, und die
Bedienelemente sahen nicht nach Bedienelementen aus.
Deutsche Lokalisierung: Im Chargen-Abschnitt stand "10. Dec 2027" - deutsches
Format mit englischem Monatsnamen. Die Ursache lag nicht in der Formatierung,
sondern darin, dass die App als englische App gebaut wurde
(CFBundleDevelopmentRegion = $(DEVELOPMENT_LANGUAGE), also "en"). Jetzt ist
Deutsch als Sprache gesetzt; damit zeichnet iOS DatePicker und Monatsnamen von
selbst richtig. Der MonthYearPicker legt seinen Kalender zusaetzlich fest auf
de_DE, damit die Monatsnamen auch bei anderssprachigem Geraet stimmen.
Datumsformat: Die Anzeige folgt jetzt der Servereinstellung (Einstellungen ->
Darstellung), wie die Web-Oberflaeche. Neu DisplaySettings mit den fuenf
Formaten, den deutschen Beschriftungen der Basiseinheiten und der Mengenangabe
in der Leitangabe. Die doppelt ausprogrammierte MHD-Formatierung in
ListViews und CheckOutView ist damit weg.
Chargen-Abschnitt: Jede Charge steht jetzt in einem eigenen Abschnitt mit
Kopfzeile statt gestapelt in einer einzigen Formularzeile - das war der
gequetschte Eindruck. Loeschen sitzt in der Kopfzeile.
Mengenfelder haben einen sichtbaren Rahmen. Ohne ihn las sich das
rechtsbuendige Feld wie fester Text, und es war nicht erkennbar, dass sich die
Menge ueberhaupt aendern laesst.
Kamera: Der Sucher fuellte per ZStack und ignoresSafeArea den ganzen Bildschirm
und wirkte dadurch erdrueckend. Er sitzt jetzt als 4:3-Feld oben, darunter
Hinweis, Meldungen und Knoepfe in gewohnter Form. Am ScannerViewController
musste nichts geaendert werden.
Einkaufsliste: Artikel und Kategorien tragen ein Symbol, Kategoriezeilen
zusaetzlich eine Kennzeichnung. Den Artikelzeilen fehlte bisher jede Einheit
("fehlt 2 - Bestand 7 von 10"); sie nennen jetzt Packungen und Basismenge.
Produktdetails: Die Felder waren blanke TextFields - sobald ein Wert drinstand,
verschwand der Platzhalter und man las nur noch "Bratbutter" / "M-Classic" /
"450". Jetzt mit Beschriftung links, Einheit hinter der Packungsgroesse (vorher
stand dort der rohe API-Wert "gram") und einem Abschnitt "Erkennung" mit
Barcode. Dasselbe im Formular zum Anlegen.
Gruppen heissen in der Oberflaeche jetzt Kategorien - in Web und App. Tabelle,
Feld group_id und die Endpunkte behalten ihren Namen, damit bestehende Zugriffe
wie Home Assistant weiterlaufen; der Unterschied ist rein sprachlich. Die
Kategorie laesst sich nun auch in der App zuweisen, was vorher gar nicht ging.
Dabei ein Fehler gefunden und behoben: Swift laesst nil-Optionals beim Kodieren
weg, das Backend wertet nur mitgeschickte Felder aus. "Keine Kategorie" oder
eine geloeschte Marke waeren damit stumm verpufft. ProductUpdateRequest kodiert
diese Felder jetzt ausdruecklich. Der Mindestbestand steht bewusst nicht mehr
darin, weil die App ihn nicht bearbeitet und ein mitgesendetes null ihn
geloescht haette.
Getestet: iOS-Geraetebuild fehler- und warnungsfrei, Web-Build laeuft durch,
40 pytest-Tests gruen. Die Datumsformatierung wurde eigenstaendig uebersetzt
und gegen elf Faelle geprueft (alle fuenf Formate, Monatsangabe, fehlendes und
unlesbares Datum) - alle korrekt. Im gebauten Bundle ist belegt, dass
CFBundleDevelopmentRegion auf "de" steht. Gegen die laufende API geprueft:
/settings und /groups liefern die erwarteten Felder, das Leeren der Kategorie
wirkt jetzt und der Mindestbestand bleibt dabei erhalten.
Die Oberflaeche selbst habe ich nicht auf dem Geraet bedient.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
8e94f15c84 |
App-Icon eingebunden, fehlendes Auslagern-Symbol und Barcode-Erkennung verbessert
Auslagern-Kachel: "arrow.up.from.line" existiert als SF Symbol nicht, deshalb blieb das Icon leer und man sah nur die eingefaerbte Kachelflaeche. Ersetzt durch "arrow.up.to.line", das Gegenstueck zum "arrow.down.to.line" beim Einlagern. Alle uebrigen im Projekt verwendeten Symbolnamen wurden gegen die Symbolliste des Systems geprueft und sind gueltig. App-Icon: Das mitgelieferte AppIcon.icon (Icon-Composer-Format) wird als Ressource eingebunden und ueber ASSETCATALOG_COMPILER_APPICON_NAME gesetzt. Die Icon-Eintraege landen korrekt in der selbstgepflegten Info.plist. Barcode-Erkennung, nachdem ein dunkelgruener Code auf weiss nicht gelesen wurde: - Aufloesung auf 1920x1080 statt der Voreinstellung, damit kontrastarme und kleine Codes ueberhaupt sauber aufgeloest werden. - Dauerhafter Autofokus mit Beschraenkung auf den Nahbereich; weiches Nachfuehren aus, da es hier nur verzoegert. - Antippen stellt gezielt auf eine Stelle scharf und misst dort die Belichtung. - Licht-Schalter in der Navigationsleiste beider Scan-Bildschirme; beim Verlassen wird das Licht sicher wieder ausgeschaltet. - Mehr Symbologien (ITF-14, DataMatrix, PDF417, Aztec, Code93). Es werden nur die Typen gesetzt, die die Kamera meldet - sonst wirft AVFoundation zur Laufzeit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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>
|