Neuer Endpunkt GET /location/{code} liefert alle Artikel an einem Lagerort inkl. der Unterorte (Lot-Bestaende und Einzelstuecke), sortiert nach Name mit Menge in Artikeleinheiten. In der App loest der /l/-QR beim Nachschlagen jetzt diese Liste auf; ein Tipp auf einen Eintrag oeffnet den Artikel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
- 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>
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>
- 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>
Bei einer Rechnung mit mehreren Artikeln soll man den Zeilenpreis des passenden
Produkts wählen können. Die Kandidatenliste enthaelt daher wieder alle
geldartigen Betraege (Zeilen- und Summenbetraege), nur ohne MwSt-Satz und
Nicht-Geld-Zahlen; der Auto-Tipp bleibt die Gesamtsumme und steht vorne.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Anhand echter Galaxus-Rechnungen nachgeschärft:
- Preis: MwSt-Satz ("8.10 %") wird als Prozentangabe ignoriert; von den
Betraegen nahe einem Summen-Stichwort gewinnt der GRÖSSTE (Endbetrag inkl.,
steht rechts) statt des naechstgelegenen (bisher der Exkl.-Betrag).
- Kaufdatum: eindeutige Stichworte (Rechnungs-/Bestell-/Kaufdatum) haben Vorrang;
"Fälligkeitsdatum"/Zahlungsziel werden nicht mehr als Kaufdatum gewertet.
- Garantieende: ein ausdruecklich genanntes Enddatum im Garantie-Umfeld
(z.B. "… - 06.10.2027") hat Vorrang vor dem gerechneten. 4 neue Tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ItemAddSheet: Kaufpreis (+Währung) und Beleg (Bild/PDF). PDF wird beim Waehlen
analysiert und Kaufdatum/Garantie/Preis/Shop vorbefuellt; erkannter neuer Shop
wird beim Anlegen erstellt. Beleg haengt an das erste angelegte Stueck.
- ItemEditView-Vorschlag zeigt/uebernimmt jetzt auch Kaufdatum und Shop
(bekannten zuweisen, sonst anlegen).
- Models/Client: DocumentSuggestions, analyzeItemDocument, ItemCreateRequest um
price_cents/currency erweitert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 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>
- guess_acquired_on (Kaufdatum) und guess_shop (bekannter Shop erkannt -> id;
sonst Kandidatenname zum Anlegen) ergaenzt.
- Upload liefert zusaetzlich suggested_acquired_on / shop_id / shop_name.
- Neuer POST /items/analyze-document: analysiert einen Beleg OHNE zu speichern
(zum Vorbefuellen beim Anlegen). Gemeinsamer Helfer _doc_suggestions.
- 6 neue Tests; Suite 150 gruen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Saubere App-Icon-Version des Vorrania-Zeichens (vollflächig, feste Farbe, 1024px,
ohne abgerundete Ecken) unter brand/app-icon.svg, plus README. Quelle des
Zeichens ist das "box"-Icon; das Favicon liegt weiterhin in web/public.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Produkt-Detail: neuer Editor „Mindestbestand je Lagerort" (Zeilen: Lagerort +
Menge in Artikeleinheiten), zusaetzlich zum Gesamt-Mindestbestand.
- Einkaufsliste: Abschnitte „Bedarf: <Lagerort>" mit Produkten und Gruppen, die
am Ort unter dem dort hinterlegten Mindestbestand liegen.
- Models/Client: LocationMinStock(+In), LocationNeeds*, setProductLocationMinStock,
shoppingByLocation; Product um location_min_stocks erweitert.
(Gruppen-Bedarf je Ort ist vorerst nur im Web pflegbar, wird aber in der iOS-
Einkaufsliste mit angezeigt.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 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>
Nur noch Beträge, die nach Preis aussehen: direkt hinter einem Summen-Stichwort
oder mit Währung (CHF/EUR/€/…) in der Nähe. Ohne solchen Hinweis kein Vorschlag.
Datumsangaben (31.12.2027) werden per Lookaround nicht mehr als Betrag (31.12)
missgelesen. Kandidatenliste enthaelt entsprechend nur plausible Preise.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Zusaetzlich zum globalen Mindestbestand: je Produkt und je Gruppe laesst sich pro
Lagerort ein Mindestbestand (in Artikeleinheiten) hinterlegen.
- Neue Tabellen product_location_min_stock / group_location_min_stock.
- PUT /products/{id}/location-min-stock und /groups/{id}/location-min-stock
ersetzen die Eintraege; Produkt-/Gruppen-Ausgabe liefert sie mit.
- Neue Einkaufsliste GET /shopping-list/by-location: Bedarfe je Ort (Produkte +
Gruppen), Bestand-am-Ort gegen Mindestbestand-am-Ort.
- Helfer location_stock_base (Bestand je Ort). 4 neue Tests, Suite 144 gruen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Findet die Beleg-Analyse mehrere Beträge, liefert der Upload jetzt eine
Kandidatenliste (bester Tipp zuerst). Web und iOS bieten dann ein Dropdown zur
Auswahl des richtigen Kaufpreises, statt nur den automatischen Tipp. 1 neuer
Test; Backend-Suite gruen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Zwei-Finger-Pinch zoomt im Kamerabild naeher an einen Code heran (digital,
auf Faktor 6 begrenzt).
- Blitz geht nach dem ersten erfolgreichen Scan wieder aus. Per Langdruck auf
den Blitz-Knopf bleibt er dauerhaft an (gesperrt, gelb); Tippen schaltet aus
und hebt die Sperre auf. Gilt fuer alle Scan-Bildschirme.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tap-to-Focus war bereits verdrahtet, aber ohne sichtbare Rueckmeldung – daher
wirkte es, als passiere nichts. Beim Antippen erscheint jetzt kurz ein gelber
Fokus-Rahmen an der getippten Stelle (wie in der System-Kamera); die Kamera
stellt weiterhin gezielt dorthin scharf.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Haken zum Ein-/Ausblenden von "Ohne MHD" ist eine Karten-Einstellung und
erscheint jetzt nur, wenn das Dashboard bearbeitet wird (.dash-grid.editing).
In der normalen Ansicht bleibt er verborgen, die gewaehlte Einstellung wirkt
aber weiterhin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Ablauf-Ring-Karte bekommt einen Umschalter, ob der Anteil "Ohne MHD"
(Gegenstaende/undatierte Chargen) mitgezaehlt wird. Aus zeigt der Ring nur
In Ordnung/Bald/Abgelaufen mit entsprechend neu berechneten Prozenten. Die Wahl
wird in localStorage gemerkt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Waehlt man beim P-touch-Export eine Kategorie, schliesst der Server ihre
Unterkategorien mit ein – das war im UI nicht sichtbar. Jetzt erscheinen die
Unterkategorien einer gewaehlten Kategorie als „enthalten" (angehakt,
deaktiviert, gedimmt); gewaehlte Oberkategorien mit Unterkategorien tragen
„inkl. Unterkategorien", nicht gewaehlte einen „+ Unterkategorien"-Hinweis. Der
Einleitungstext erklaert es zusaetzlich.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
"Foto machen"/"Galerie" sind <label> und erbten das margin-bottom des globalen
label-Stils, wodurch sie hoeher sassen als der "Entfernen"-<button>. margin:0
an den Foto-Knoepfen stellt alle drei auf eine Hoehe.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Barcode-Zeile: Eingabefeld fuellt die Breite, die beiden Knoepfe (Nachschlagen
+ Vergleichen) stehen nebeneinander statt gestapelt – keine Luecke mehr rechts.
- Foto: "Entfernen" ist jetzt ein normaler Button wie "Foto machen"/"Galerie"
(gleiche Hoehe/Ausrichtung) statt reiner Text.
- Umschalter "Typ"/"Verwaltung": Abstand zwischen Beschriftung und Segmenten.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die blaue Hinterlegung der Detailzeile (Preis/Belege) entfernt; Stück-Zeile und
Detailzeile bilden jetzt eine zusammenhaengende Ansicht ohne Trennlinie
dazwischen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Anlege-Maske war ein grosses, dauerhaft sichtbares Formular. Jetzt klappt
sie hinter einen "Einzelstück anlegen"-Knopf. Dafuer werden Kaufpreis und Belege
je Stueck nicht mehr ueber einen Aufklapp-Knopf versteckt, sondern direkt unter
jeder Zeile angezeigt (leicht abgesetzte Detailzeile).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ItemEditView bekommt einen Kaufpreis (Betrag + CHF/EUR) und eine Beleg-Sektion:
Rechnung/Garantieschein als Bild (Fotoauswahl) oder PDF (Datei-Import)
hochladen, ansehen (QuickLook) und loeschen. Nach einem PDF-Upload schlaegt der
Server "Garantie bis" und Kaufpreis vor – per Knopf uebernehmbar. Item-Model um
priceCents/currency/documents erweitert; Client-Methoden fuer Upload, Download
und Loeschen der Belege.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Je Einzelstück eine ausklappbare Detailzeile: Kaufpreis (Betrag + CHF/EUR) und
Belege (Rechnung/Garantieschein) hochladen, ansehen, löschen. Nach dem Upload
eines PDFs schlägt der Server „Garantie bis" und Kaufpreis vor – per Knopf
übernehmbar. Belege werden mit Anmeldung geladen (kein offener Zugriff).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guess_price_cents zieht den Kaufpreis aus dem Belegtext: bevorzugt den Betrag
nach einem Summen-Stichwort (Gesamtbetrag/Total/…), sonst den groessten Betrag.
Versteht Tausendertrenner (1'299.00) und deutsches Format (1.299,00). Der
Upload liefert den Vorschlag als suggested_price_cents mit. 5 neue Tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Item: price_cents + currency (Kaufpreis rappen-/centgenau). Migration ergaenzt.
- Neue Tabelle item_documents (mehrere Belege je Stueck, PDF oder Bild); Blob
wird verzoegert geladen, damit Item-Listen leicht bleiben.
- Endpunkte: Upload (POST), Ansehen/Download (GET), Loeschen (DELETE) je Stueck.
Dateiname beim Download gehaertet (keine Header-Injektion).
- services/warranty.py: schaetzt aus PDF-Text lokal ein Garantieende
(Zeitraum + Kaufdatum, oder Datum nahe Garantie-Stichwort); pypdf ergaenzt.
Der Upload liefert den Vorschlag zurueck. 10 neue Tests, Suite 136 gruen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Lagerorte: LocationEditor hängt bestehende Orte jetzt um (Elternort auch beim
Bearbeiten, eigene Unterorte ausgeschlossen); Client updateLocation +
LocationUpdateRequest (parent_id wird immer gesendet, auch null).
- Kategorien: beim Anlegen optionale Oberkategorie wählbar (Unterkategorie);
mit Eltern erbt sie deren Verwaltungsart, sonst wird sie gewählt.
- Eigene Felder: neue CategoryFieldsView + FieldEditor (anlegen/bearbeiten/
löschen von Feldern je Kategorie), erreichbar aus dem Kategorie-Editor;
Client ownFieldDefinitions/create/update/deleteFieldDefinition + Models.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Zellen, die mit = + - @ (oder Tab/CR) beginnen, werden mit einem vorangestellten
Apostroph zu Text entschaerft. So fuehrt ein Produktname wie "=HYPERLINK(...)"
beim Oeffnen der Etiketten-CSV in Excel/P-touch nicht mehr als Formel aus.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bestehende Lagerorte lassen sich jetzt nachträglich einem anderen Elternort
zuordnen oder auf die oberste Ebene holen.
- Backend: LocationUpdate um parent_id (Name jetzt optional); update_location
haengt um, mit Schutz gegen Ringe (weder auf sich selbst noch auf einen
eigenen Unterort) und Existenzpruefung des Ziels. 6 Tests.
- Web: Lagerorte-Seite bekommt je Ort Bearbeiten (Name + Elternort ueber den
CategorySelect-Baum, eigene Unterorte ausgeschlossen); api.updateLocation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hat ein Artikel ein Bild, zeigt die Produktliste jetzt ein Vorschaubild statt
des neutralen shippingbox-Symbols; ohne Bild bleibt das Symbol. Ein gemeinsamer
ProductImageCache verhindert, dass beim Scrollen dieselben Bilder immer wieder
geladen werden, und merkt sich auch "kein Bild". ProductPhotoSection haelt den
Cache bei Laden/Upload/Entfernen synchron.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend und API-Client konnten Felddefinitionen laengst aendern (PATCH), nur die
Oberflaeche bot bisher nur Anlegen und Loeschen. In der Felder-Verwaltung einer
Kategorie gibt es jetzt je Feld einen Bearbeiten-Knopf: er laedt Name, Typ,
Einheit, Auswahlmoeglichkeiten und Pflicht ins Formular; Speichern aktualisiert
das Feld (oder Abbrechen). Geerbte und eingebaute Felder bleiben unveraendert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Statt der nativen "— —"-Dropdowns nutzen jetzt auch Produktformular
(Kategorie + Inline-"Neue Kategorie"-Elternwahl), Einlagern-Maske und
Produkte-Filter den CategorySelect-Baum. CategorySelect um optionale
Zusatz-Eintraege (extraOptions) erweitert, damit der Produkte-Filter
"Alle Kategorien"/"Ohne Kategorie" weiter anbietet.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Gemeinsame TreeMasterView fuer hierarchische Stammdaten (Ein-/Ausklappen,
Anlegen, Bearbeiten, Loeschen):
- Kategorien: Segment-Filter Alle/Lebensmittel/Gegenstaende (wie im Web); in
der Alle-Ansicht zeigt jede Zeile ihre Art. Anlegen/Bearbeiten waehlt die
Verwaltungsart (neu: createCategory mit tracking, updateCategory).
- Lagerorte: werden jetzt als aufklappbarer Baum gezeigt statt flach. Beim
Anlegen laesst sich ein Elternort waehlen (Hierarchie aufbauen); Umhaengen
unterstuetzt der Server nicht, Bearbeiten bleibt daher Umbenennen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Stammdaten-Kategorien waren nur eingerueckt und immer komplett offen. Jetzt
lassen sich Unterkategorien per Pfeil ein- und ausklappen (wie im Web): zugeklappt
zeigt die Zeile "N ausgeblendet". Anlegen, Umbenennen (Antippen) und Loeschen
(wischen) bleiben unveraendert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die iOS-Stammdaten hatten keinen Punkt fuer Shops – die "gekauft bei"-Liste war
nur im Web pflegbar. Jetzt gibt es unter Verwaltung > Stammdaten "Shops" mit
Anlegen, Bearbeiten (Name + optionale Website) und Loeschen, analog zum Web.
Client um createShop/updateShop/deleteShop samt Request-Models ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Entfernen-Knopf stand auch ohne Bild da. ProduktBild meldet jetzt via
onLoaded, ob ein Bild geladen wurde; das Produktformular blendet "Entfernen"
entsprechend ein oder aus. "Foto machen" und "Galerie" bleiben immer sichtbar.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Kategorien und Gruppen standen in der Alltags-Navigation, obwohl sie – wie
Lagerorte, Shops, Einheiten und Gebinde – nur von Admins gepflegte Katalog-
Stammdaten sind. Jetzt sind alle Stammdaten zusammen im Admin-Bereich, der in
zwei Abschnitte gegliedert ist:
- Stammdaten: Kategorien, Gruppen, Lagerorte, Shops, Einheiten, Gebinde
- System: Benutzer, Import/Export, Einstellungen
Normale Nutzer sehen nur noch den Alltag (Uebersicht, Ein-/Auslagern, Produkte,
Einkaufsliste, Verlauf). /categories und /groups sind jetzt Admin-Routen. Das
entspricht der Gliederung der iOS-App.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auswertungen (by_category, expiry_split, stats) iterierten nur Lots. Gegenstaende
mit Menge-je-Lagerort liegen als Lots und tauchten auf – Einzelstuecke liegen
aber als Items und fehlten dadurch komplett (Dashboard zeigte z.B. nur die
Powerbank, nicht Kamera/Kabel). Neuer Helfer _bestand_beitraege deckt beide
Speicherformen ab: jedes Item zaehlt als ein Stueck ohne MHD. Regressionstest
ergaenzt; volle Suite gruen (120).
CategorySelect: Scrollen IM aufklappbaren Menue schloss es, weil jeder Scroll als
Seiten-Scroll gewertet wurde. Jetzt schliesst nur ein Scroll ausserhalb des
Menues; die lange Liste laesst sich scrollen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die uebergeordnete Kategorie wird nicht mehr ueber ein <select> mit
"— —"-Einrueckung gewaehlt, sondern ueber einen aufklappbaren Baum-Picker
(CategorySelect): echte Einrueckung, Aeste per Pfeil auf-/zuklappbar wie in der
Liste. Das Menue haengt per Portal am <body>, damit der horizontal scrollende
Tabellenrahmen es nicht abschneidet. Ersetzt beide Stellen (Zeilen-Elternwahl
und Anlege-Formular); die kompakten Knoepfe machen die Zeile schmaler, sodass
die Tabelle nicht mehr seitwaerts ueber den Block hinauslaeuft.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Abruf schlug mit „Abgebrochen" (URLError.cancelled) fehl, nicht mit 404:
openItemUid wurde zu Beginn des .task(id:) auf nil gesetzt, wodurch SwiftUI die
laufende Anfrage abbrach. Jetzt wird openItemUid erst NACH dem Laden
zurueckgesetzt – das Stueck oeffnet sich.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- „Gekauft bei" (Shop) gehoert bei Einzelstuecken zum einzelnen Stueck, nicht
ans Modell. Wie im Web wird der Shop-Picker am Produkt jetzt ausgeblendet,
sobald „Einzelstuecke" aktiv ist; der Produktlink (beschreibt das Produkt
allgemein) bleibt. Beim Speichern wird fuer Einzelstuecke kein Shop ans
Modell geschrieben.
- Wird ein gescanntes Einzelstueck nicht gefunden, nennt die Meldung jetzt den
abgefragten Server und den Original-Fehler. So ist sofort erkennbar, ob der
aktive Server ein anderer ist als der im QR-Code (haeufigste Ursache bei
korrekter UID) oder ob ein Netz-/Serverfehler vorliegt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ITSAppUsesNonExemptEncryption=false in die Info.plist. Die App nutzt nur die
Standard-Verschluesselung des Systems (HTTPS), faellt damit unter die Ausnahme
und die "App Encryption Documentation"-Frage entfaellt bei jedem Upload.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Universal Link oeffnete die App, sprang aber nicht aufs Stueck. Jetzt robuster:
- Kaltstart wird abgefangen (AppDelegate application(_:continue:) + pending-URL),
zusaetzlich zu den SwiftUI-Hooks.
- Beim Link wird auf das Server-Profil gewechselt, dessen Adresse zum Host passt
(sonst wuerde die UID am falschen Server gesucht).
- Schlaegt das Aufloesen fehl (nicht angemeldet, UID unbekannt), erscheint jetzt
eine Meldung statt stiller Nichtreaktion.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
P-touch will Komma, wir hatten fest Semikolon - jetzt einstellbar und in
localStorage gemerkt, sodass man es nur einmal setzt. Standard ist Komma.
Anfuehrungszeichen werden passend zum gewaehlten Trennzeichen gesetzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auf "Import / Export" neue Karte: Kategorien auswaehlen (inkl. Unterkategorien)
und je Einzelstueck eine CSV-Zeile herunterladen - Spalten QR-Inhalt (…/i/<UID>),
UID, Produkt, Marke, Kategorie, Lagerort. In der Etiketten-Software als Datenbank
verknuepfen, dann entsteht QR + Text automatisch - kein einzelnes Bild-Download
und Zuordnen mehr.
Backend: GET /export/labels?category_ids=... liefert die Zeilen (JSON); den
QR-Inhalt setzt das Web mit window.location.origin dazu.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beim Nachschlagen/Öffnen eines Einzelstuecks stand oben das QR-Bild - unnoetig,
den hat man ja gerade gescannt. Jetzt oben das Produktbild plus Name/Marke; die
stueckspezifischen Angaben (UID, Kaufdatum, Garantie, Ort, Notiz) bleiben.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>