Phasen werden über Name/Reihenfolge den bestehenden zugeordnet und aktualisiert;
nur entfernte Phasen werden gelöscht. Produktions-Verbrauchszeilen behalten so
ihre recipe_phase_id. Derselbe Rohstoff je Phase nur einmal (Validierung).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Lagerplatz-Zuordnung (Raum/Regal/Fach) gab es bisher nur bei Rohstoffen. Jetzt
dieselbe Storage-Hierarchie (StorageRoom/Shelf/Slot) auch für Produkte und
Verpackungsartikel, inkl. Anzeige an den passenden Stellen.
- Migration: storage_room_id/shelf/slot an products + packaging_items
(nullable, FK constrained, nullOnDelete).
- Models Product + PackagingItem: fillable + storageRoom/Shelf/Slot-Relationen +
storageLabel() („Raum 1 | Regal 3 | A").
- Produktformular (Inventar-Abschnitt) + Verpackungsformular: Auswahl-Zeile
Raum/Regal/Fach; Optionen kommen aktiv/sortiert aus den zentral pflegbaren
Bausteinen (Einstellungen → Allgemein).
- Speichern: ProductRepository normalisiert leere Auswahl -> null (FK);
PackagingItem-Requests + Repository um die drei Felder erweitert.
- Anzeige: Produktbestand (Sub-Zeile mit Marker), Produktverpackung-Übersicht
(neue Spalte „Lagerplatz").
- DeletionGuard: Lagerbaustein ist nicht löschbar, solange Produkte/Verpackung
darauf verweisen (analog Rohstoffe).
Tests: 4 neue (Produkt speichern + leer->null, Verpackung speichern + Anzeige,
Löschsperre, freier Baustein löschbar). Migration auf Dev-/Live-DB gelaufen.
Suite 331 grün.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Neuer Helper reFormatWawiNumber(): '5.1'/'5.12' werden als 5,1/5,12
gelesen (kommt beim Kopieren von Daten vor); '1.500' bleibt Tausender.
Gilt nur für die WaWi-Eingaben (Mengen, Preise, Gewichte, Rezeptur) —
reFormatNumber() app-weit unverändert. JS-Parser (parseGerman,
parseDeNumber) auf dieselbe Regel vereinheitlicht; parseDeNumber
behandelte '1.500' bisher sogar als 1,5.
Tests: +1 (Parsing-Matrix).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- H-4: Rezeptur-Neuaufbau (Delete-then-Insert) in DB::transaction;
unbekannte Rohstoff-IDs brechen validiert ab (kein FK-Crash nach dem
Delete mehr), Phasennamen auf varchar(100) gekappt.
- H-5: Phasen werden auch ohne Rohstoffzeilen persistiert — Struktur
mit Namen/Notizen geht beim Speichern nicht mehr verloren.
- M-8: requiredGramsByIngredient() summiert doppelte Rohstoffe statt
zu überschreiben.
- N-11: Set-Umstellung löscht Rezeptur-Phasen mit.
- N-12: Auto-Phasenname nach Z: AA, AB, …
- N-14: Legacy-Zweig updateIngredients() nicht mehr destruktiv —
bestehende gram/factor-Werte bleiben beim Listen-Sync erhalten
(Verhalten lt. ProductPhase0Test unverändert).
Tests: neuer RecipeRobustnessTest (6). Suite komplett grün.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>