Umsetzung der Warenwirtschafts-/Produktmanagement-Erweiterung gemaess Entwicklungsplan V4.0: - AP-00: Regressionsbasis fuer 5.1-Features (ProductPhase51Test) - AP-01: URL-Bugfixes B1/B2 (suppliers/packaging-items, breitere url-Spalten) - AP-04/04.1: iPad-taugliche, vereinheitlichte Tabellen-Aktionen - AP-05: Einstellungen "Allgemein" mit UST-Saetzen (tax_rates) und Lieferzeit-Vorlagen (delivery_times, inkl. Tage-Feld) - AP-06: Lieferanten um Bestellweg, Bestell-Mail/-URL und Lieferzeit erweitert - AP-07/07.1: INCI um Lieferanten-Mehrfachwahl, UST und Lieferzeit erweitert; Lieferanten-Detailansicht im Modal mit pflegbaren INCI-/Verpackungslisten - AP-08: Einkauf um UST-Snapshot, Netto/Brutto-Automatik und Duplizieren erweitert Entwicklungsplan aktualisiert: alle Klaerungspunkte (§5) vom Kunden beantwortet und in die jeweiligen APs eingearbeitet (AP-02/03/09/13/15), neues AP-18 (Hinweise-Doku unter Einstellungen) ergaenzt. Naechster Schritt eindeutig markiert: AP-09 (Produktion auf Hersteller-Rezeptur, kein Fallback, Warnung).
42 KiB
Aktualisierter Entwicklungsplan: Warenwirtschaft, Produktion & Produktbestand
Version: 4.0 - Stand 02.06.2026 Ersetzt:
entwicklungsplan-aktualisiert-27-04-2026.md(V3.0) als operative Arbeitsgrundlage Referenzen:entwicklungsplan.md(V2.0),briefing-anpassungen-27-04-2026.md,feedback.md,konzept-final.md,docs/Todos.mdMethodik: Backlog aus kleinen, sequenziell abarbeitbaren Arbeitspaketen (AP). Jedes AP hat Ziel, konkrete Schritte mit Dateipfaden, DB-Änderungen, Akzeptanzkriterien und Tests. Reihenfolge ist so gewählt, dass jedes AP einzeln deploybar ist.
0. Was dieses Dokument neu macht
Gegenüber V3.0 wurde der reale Code-Stand verifiziert (nicht nur die Protokolltabelle übernommen). Daraus ergeben sich Korrekturen, neu entdeckte Bugs und eine feinere Zerlegung in einzeln umsetzbare Schritte.
Geprüfte Dateien u. a.: routes/web.php, app/Http/Controllers/Admin/Inventory/*, app/Services/ProductionService.php, app/Http/Requests/Inventory/*, resources/views/admin/inventory/*, Migrationen unter database/migrations/.
0a. Umsetzungsprotokoll V4.0 (laufend)
Jede abgeschlossene Teil-Lieferung wird hier mit Datum, betroffenen Dateien und Test-Status protokolliert.
| Datum | AP | Kurzbeschreibung | Tests |
|---|---|---|---|
| 02.06.2026 | AP-01 | URL-Bugfixes B1/B2 umgesetzt: suppliers/form.blade.php und packaging-items/form.blade.php von type="url" auf type="text" (placeholder https://); Store/UpdatePackagingItemRequest URL-Regel url|max:500 → string|max:2048; Migration 2026_06_02_145358_widen_url_columns_in_inventory_tables (suppliers.url + packaging_items.url → varchar(2048)). |
tests/Feature/InventoryUrlFieldsTest.php (3 grün); Regression Phase 2+3 grün (17) |
| 02.06.2026 | AP-04 | iPad-taugliche Tabellen-Aktionen (B5): neue Partial resources/views/admin/inventory/partials/table-actions-style.blade.php (@once-Style für .wawi-table td .btn, min. 42px Touch-Target, mehr Abstand); Klasse wawi-table + Partial-Include in allen 8 Index-Views (locations, material-qualities, packaging-materials, supplier-categories, suppliers, packaging-items, stock-entries, productions). |
Render-Regression Phase 2+3+5 grün (21) |
| 02.06.2026 | AP-00 | Regressionsbasis für umgesetzte 5.1-Features als Pest-Tests nachgezogen: INCI-Rohstoffqualität-Relation, Hersteller-Rezeptur getrennt von Produkt-Rezeptur, Produkt-Kopie inkl. beider Rezepturen, „nur aktive Produkte" im Produktions-Formular, Produktion edit/copy rendern. | tests/Feature/ProductPhase51Test.php (5 grün) |
| 02.06.2026 | AP-04.1 | Aktionsspalten vereinheitlicht (Kunden-Feedback): einheitliches Schema Spalte 1 = Ansicht + Bearbeiten (+ Kopieren bei Produktion), letzte Spalte = Löschen. Umgebaut: stock-entries/index (Ansicht/Bearbeiten nach vorn, Löschen ans Ende, DataTables order/columnDefs an verschobene Spalten angepasst) und productions/index (Ansicht/Bearbeiten/Kopieren nach vorn). Stammdaten-Tabellen waren bereits konform (kein show-Route → keine Ansicht). CSS-Feinjustierung der Button-Abstände durch Kunden in partials/table-actions-style.blade.php übernommen. |
Produktions-Index-Render + Aktionslinks geprüft; stock-entries Index-Render grün (13) |
| 02.06.2026 | AP-05 (Teil 1: UST) | Neuer Unterpunkt Warenwirtschaft → Einstellungen → „Allgemein" als erweiterbarer Container für kleinteilige Einstellungen (erstes Modul = Umsatzsteuersätze). Tabelle tax_rates (name, percent DECIMAL(5,2), active, pos) via Migration 2026_06_02_152721_create_tax_rates_table; Model TaxRate (casts percent/active, scopeActive), TaxRateFactory, Seeder-Erweiterung InventoryStammdatenSeeder (19/7/0, idempotent per firstOrCreate). CRUD: GeneralSettingController@index (Allgemein-Seite), TaxRateController (create/store/edit/update/destroy, Redirect zurück auf general), Store/UpdateTaxRateRequest. Views admin/inventory/general/index.blade.php (Karte „Umsatzsteuersätze" mit Tabelle + Neu/Bearbeiten/Löschen) und admin/inventory/tax-rates/form.blade.php. Routen in superadmin-Gruppe (admin.inventory.general, Resource tax-rates ohne index/show). Sidenav-Eintrag „Allgemein" inkl. open/active-Logik. Migration + Seed auf DB ausgeführt (3 Default-Sätze vorhanden). |
tests/Feature/TaxRateSettingsTest.php (7 grün, 24 Assertions): Render, CRUD, Validierung Pflicht/Bereich, active-Scope, Zugriffsschutz Nicht-SuperAdmin |
| 02.06.2026 | AP-05 (Teil 2: Lieferzeiten) | Zweite Karte „Lieferzeit-Vorlagen" auf der Allgemein-Seite. Tabelle delivery_times (label, active, pos) via Migration 2026_06_02_153243_create_delivery_times_table; Model DeliveryTime (cast active, scopeActive), DeliveryTimeFactory, Seeder-Erweiterung (1–3 / 3–5 Werktage / 1–2 Wochen, idempotent). CRUD: DeliveryTimeController (create/store/edit/update/destroy → Redirect general), Store/UpdateDeliveryTimeRequest. GeneralSettingController um deliveryTimes erweitert. View admin/inventory/delivery-times/form.blade.php + zweite Karte in general/index. Route Resource delivery-times (ohne index/show) in superadmin-Gruppe. Sidenav open/active um delivery-times ergänzt. Migration + Seed auf DB ausgeführt. |
tests/Feature/DeliveryTimeSettingsTest.php (7 grün, 21 Assertions): Render, CRUD, Validierung, active-Scope, Zugriffsschutz |
| 02.06.2026 | AP-06 (Lieferanten erweitern) | Felder order_method ENUM(email,online_shop), order_email, order_url, delivery_time (Freitext) an suppliers via Migration 2026_06_02_154755_add_order_fields_to_suppliers_table. Supplier fillable erweitert; Store/UpdateSupplierRequest Regeln (order_method in:email,online_shop; order_email email; order_url string max 2048; delivery_time string). SupplierRepository::extractSupplierAttributes erweitert. SupplierController create/edit übergeben aktive deliveryTimes als Vorlagen. suppliers/form.blade.php: Bestellweg-Select + bedingte Felder (Bestell-E-Mail / Bestell-URL via JS-Toggle) + Lieferzeit-Textfeld mit <datalist> aus aktiven Lieferzeit-Vorlagen. Migration auf DB ausgeführt. |
tests/Feature/SupplierOrderFieldsTest.php (6 grün): Formular zeigt nur aktive Vorlagen, Speichern E-Mail-/Shop-Bestellweg, Update, Validierung Bestellweg/Bestell-E-Mail. Regression InventoryPhase2Test (9 grün) |
| 02.06.2026 | AP-06 (Nachtrag: Lieferzeit in Tagen) | Lieferzeit-Vorlagen erhalten festes Feld days (ganze Tage bis Wareneingang, Basis für spätere „rechtzeitig bestellen"-Ableitung). Migration 2026_06_02_160411_add_days_to_delivery_times_table (delivery_times.days unsignedSmallInt nullable) + 2026_06_02_160411_add_delivery_time_days_to_suppliers_table (suppliers.delivery_time_days). DeliveryTime (fillable+cast days), Factory/Seeder (3/5/14 Tage, Bestandsdaten nachgepflegt). Store/UpdateDeliveryTimeRequest + Store/UpdateSupplierRequest um days/delivery_time_days (nullable int) erweitert; SupplierRepository + Supplier cast. Views: Tage-Feld in delivery-times/form, Spalte „Tage" in general/index, Tage-Feld im suppliers/form + JS-Autofill (data-days an Datalist-Optionen setzt Tage bei Vorlagenauswahl, manuell überschreibbar). Migrationen auf DB ausgeführt, Default-Vorlagen mit Tagen befüllt. |
DeliveryTimeSettingsTest (10 grün): days speichern/optional/Integer-Validierung; SupplierOrderFieldsTest (9 grün): delivery_time_days speichern, Integer-Validierung, data-days-Ausgabe |
| 02.06.2026 | AP-08 (Einkauf erweitern) | Einkauf um UST-Satz + Netto/Brutto-Automatik + Duplizieren erweitert. Migration 2026_06_02_181548_add_price_fields_to_stock_entries_table (price_per_kg_gross DECIMAL(10,4), tax_rate_id FK→tax_rates nullOnDelete, tax_rate_percent DECIMAL(5,2) als Snapshot). price_per_kg bleibt das bestehende Netto-Feld (kein Rename → keine Migration der Bestandsdaten/Tests). StockEntry: fillable + casts (price_per_kg_gross/tax_rate_percent) + taxRate() belongsTo. Store/UpdateStockEntryRequest: Regeln tax_rate_id (exists) + price_per_kg_gross (numeric), Reformat dt. Zahl, neue Regel „bei Rohstoff genau eines von Netto/Brutto verpflichtend". Berechnung zentral im StockEntryRepository::resolvePrices(): UST-Prozent als Snapshot, fehlender Netto-/Brutto-Wert wird aus dem Faktor (1+%/100) berechnet (Netto↔Brutto), bei Verpackung Preisfelder/UST genullt (Netto-Gesamt bleibt). View _form: UST-Dropdown (aktive tax_rates, data-percent) + Netto-/Brutto-Felder nebeneinander; _scripts: JS rechnet live Netto↔Brutto bei Eingabe und UST-Wechsel (dt. Zahlenformat). show: Anzeige Netto/Brutto/USt. Duplizieren: Route stock-entries/{stock_entry}/copy + StockEntryController@copy legt direkt eine pending-Kopie der Stufe-1-Felder an (Charge/MHD/Eingangsdaten leer, ordered_at=heute, ordered_by=aktueller User) und leitet zur Bearbeitung; Kopieren-Button in index (Aktionsspalte) + show-Header. Migration auf DB ausgeführt. |
tests/Feature/StockEntryPriceTest.php (6 grün): Netto→Brutto, Brutto→Netto, ohne UST Netto=Brutto, Netto/Brutto-Pflicht, Duplizieren erzeugt pending-Kopie ohne Chargendaten, Copy-Zugriffsschutz. Regression InventoryPhase3Test (8 grün) |
| 02.06.2026 | AP-07.1 (Lieferanten-Detailansicht/Modal) | Zwischenschritt (Kunde): Lieferanten-Zuordnungen auch von der Lieferantenseite aus sichtbar/pflegbar. Supplier::ingredients() belongsToMany (Gegenstück zu Ingredient::suppliers()). Resource suppliers show reaktiviert + neue Routen suppliers.ingredients.attach/detach und suppliers.packaging-items.attach/detach (admin-Gruppe). SupplierController: show() + attach/detachIngredient() + attach/detachPackagingItem() rendern gemeinsames Partial suppliers/_details.blade.php (Stammdaten + zwei kleine Listen „Zugeordnete INCIs" / „Zugeordnete Verpackungsartikel" mit Entfernen-Button und Hinzufügen-Auswahl der noch nicht zugeordneten Einträge). Index: Augen-Button (Spalte 1) öffnet Bootstrap-Modal, lädt Details per AJAX; Hinzufügen/Entfernen via delegiertem jQuery-AJAX (X-CSRF-TOKEN-Header) und ersetzt den Modal-Body mit dem neu gerenderten Partial. Verpackungsartikel-Zuordnung = packaging_items.supplier_id setzen/leeren. |
tests/Feature/SupplierDetailsTest.php (7 grün): show zeigt zugeordnete INCIs/Verpackung, INCI attach/detach, Verpackung attach/detach, Validierung, Zugriffsschutz Nicht-Admin |
| 02.06.2026 | AP-07 (INCI erweitern) | INCI/Rohstoffe um Lieferanten-Mehrfachwahl, UST-Satz und eigene Lieferzeit (inkl. Tage-Autofill) erweitert. Migration 2026_06_02_161237_add_order_fields_to_ingredients_table (ingredients.tax_rate_id FK→tax_rates nullOnDelete, delivery_time VARCHAR, delivery_time_days unsignedSmallInt) + 2026_06_02_161237_create_ingredient_supplier_table (Pivot ingredient_id (unsignedInt, passend zu altem increments) / supplier_id, preferred bool, supplier_sku, url(2048), unique-Paar, cascadeOnDelete). Ingredient: fillable + cast delivery_time_days, Relationen taxRate() belongsTo + suppliers() belongsToMany (Pivot preferred/supplier_sku/url). O1 erledigt: IngredientController::store() von Request::all() auf neuen App\Http\Requests\StoreIngredientRequest umgestellt (validiert + normalisiert deutsche Dezimalzahlen default_factor/min_stock_alert, leere FKs→null). edit() lädt aktive taxRates, aktive deliveryTimes, aktive suppliers + eager-load suppliers; nach Speichern suppliers()->sync(). Single-Endpoint-Schema (admin_product_ingredient_store für Neu+Update) beibehalten → ein FormRequest genügt. View admin/ingredient/form.blade.php: UST-Dropdown (aktive tax_rates), Select2-Mehrfachwahl Lieferanten, Lieferzeit-Textfeld mit <datalist> (data-days) + Tage-Feld; edit.blade.php @section('scripts') mit Select2-Init + Tage-Autofill (manuell überschreibbar). Lieferzeit-Logik: INCI-Lieferzeit hat Vorrang vor Lieferanten-Lieferzeit (Auswertung erst in AP-10). Migrationen auf DB ausgeführt. |
tests/Feature/IngredientOrderFieldsTest.php (6 grün): Formular zeigt Lieferanten/UST/aktive Vorlagen+data-days, Speichern mit UST/Lieferzeit/Tagen/Lieferanten, Lieferanten-Sync bei Update, Validierung Tage-Integer/UST-Existenz/Name-Pflicht. Regression SupplierOrderFieldsTest (8) + ProductPhase51Test (5) grün |
Status Roadmap: AP-00, AP-01, AP-04, AP-05, AP-06 (inkl. Nachtrag) erledigt; AP-07 erledigt (INCI: Lieferanten-Mehrfachwahl, UST-Satz, eigene Lieferzeit inkl. Tage-Autofill, ingredient_supplier-Pivot; O1 IngredientController auf FormRequest umgestellt) inkl. AP-07.1 (Lieferanten-Detailansicht im Modal mit pflegbaren INCI-/Verpackungs-Listen); AP-08 erledigt (Einkauf: UST-Snapshot, Netto/Brutto-Automatik, Duplizieren).
Alle Klärungspunkte aus §5 sind beantwortet (Kunde, 02.06.2026) und in die jeweiligen APs eingearbeitet — keine Blocker mehr offen.
➡️ NÄCHSTER SCHRITT: AP-09 (Produktion korrigieren). Konkret: (1) Produktion ausschließlich auf Hersteller-Rezeptur umstellen + Warnung, wenn keine gepflegt ist (kein Fallback); (2) Chargen-Dropdown-Label + nur Chargen mit Restbestand; (3) B3 „Weitere Charge"-JS-Fix (genau eine Zeile); (4) Soll-Neuberechnung ohne Überschreiben manueller Eingaben; (5) B4 iPad-Layout der Kopfdaten; (6) Produktentwicklung-Platzhalterseite („Briefing ausstehend"). Danach AP-02/AP-03, dann die großen Übersichten. Neu: AP-18 (Hinweise-Doku unter Einstellungen) kann jederzeit dazwischengezogen werden.
1. Verifizierter Ist-Stand (02.06.2026)
Umgesetzt und im Code vorhanden
| Bereich | Status | Belegt durch |
|---|---|---|
| Produktmanagement (Produkte, INCIs, Kategorien, Attribute) | vorhanden | app/Http/Controllers/ProductController.php, IngredientController.php |
| Rezeptur + Hersteller-Rezeptur (Prozent, Faktor, 100%-Summe) | vorhanden | product_ingredients.recipe_type, Product::p_ingredients() / manufacturer_ingredients() |
| Haltbarkeit am Produkt (PAO / festes MHD) | vorhanden | products.shelf_life_type, shelf_life_months |
| Stammdaten (Lagerorte, Lieferanten, Kategorien, Rohstoffqualität, Verpackungsmaterial, Produkt-/Versandverpackung) | vorhanden | app/Http/Controllers/Admin/Inventory/*, Migrationen 2026_03_27_* |
| INCI mit Rohstoffqualität | vorhanden | ingredients.material_quality_id |
| Verpackung & Material am Produkt (BOM) | vorhanden | product_packagings, Product::packagings() |
| Einkauf & Wareneingang (zweistufig pending → received, Charge, MHD) | vorhanden | stock_entries, StockEntryController, ReceiveStockEntryRequest |
| Produktion (Chargen-Zuordnung, Soll-Verbrauch, MHD-Warnung, Packaging-Snapshot, edit/copy) | vorhanden | ProductionService, ProductionController, production_*-Tabellen |
| Tests Phase 0–5 | vorhanden | tests/Feature/ProductPhase0/1/4Test.php, InventoryPhase2/3Test.php, ProductionPhase5Test.php |
Noch NICHT im Code vorhanden (entgegen Eindruck aus V3.0-Lesart)
- Phase 5.2 ist vollständig offen — keine der dort beschriebenen DB-Strukturen existiert:
- kein
tax_rates/tax_rate_id/tax_rate_percent - kein
is_set,main_product_id,product_set_items - kein
order_method/order_email/order_url/delivery_timeansuppliers - kein
ingredient_supplier-Pivot, keintax_rate/delivery_timeaningredients - kein
price_per_kg_net/price_per_kg_grossanstock_entries - kein
out_of_stock_untilanproducts - kein
product_stock_movements, keinInventoryService, keine Bestandsseiten
- kein
- Produktion basiert noch auf
p_ingredients(Produkt-Rezeptur), nicht auf der Hersteller-Rezeptur (ProductionService::store()undbuildRecipePayload()ladenp_ingredients). Briefing fordert Hersteller-Rezeptur als Basis → offen. - Kein Rohstoffbestand / Produktbestand / Historie, kein Ausgang/Ausschuss, kein Audit-Trail, kein 2FA, keine blockbasierten Rechte, keine Warenwirtschafts-Einstellungen.
2. Gefundene Bugs & Optimierungen (sofort vor Feature-Arbeit)
Diese Punkte sind klein, konkret und blockieren teils die tägliche Nutzung. Sie werden als Phase 5.1.x Nachzügler vorgezogen.
B1 — Lieferanten-URL: Speichern schlägt fehl, wenn URL ausgefüllt ist (umgekehrtes Verhalten)
- Symptom (Kunde): „Neuer Lieferant: sagt ‚URL eingeben‘, obwohl eine drinsteht. Nehme ich sie raus, geht das Abspeichern."
- Ursache:
resources/views/admin/inventory/suppliers/form.blade.phpZeile 56 nutzt<input type="url">. Die native Browser-Validierung lehnt eine ausgefüllte, aber nicht streng schema-konforme URL (z. B. ohnehttps://oder mit kodierten Parametern) ab; ein leeres Feld ist gültig → exakt das gemeldete „umgekehrte" Verhalten. Die Server-Validierung ist bereits korrekt (nullable|string|max:2048). - Fix:
type="url"→type="text"(Server validiert ohnehin als String). Damit werden auch Konfigurator-URLs mit Parametern akzeptiert (siehe B2). - Aufwand: ~15 Min.
B2 — URL-Felder müssen Konfigurator-URLs mit Parametern akzeptieren
- Anforderung (Todos Z. 1–2): URLs wie
https://www.kartonsaufmass.de/bestellen?bom_configuration=%7B%2522length%2522:125,...%7Dmüssen gespeichert werden können (Versandverpackungs-Konfiguratoren). - Status (verifiziert): Lieferanten-URL ist bereits
nullable|string|max:2048(ok, mit B1-Fix vollständig).PackagingItemist NICHT ok:Store/UpdatePackagingItemRequesthaben['nullable','url','max:500']— dieurl-Regel lehnt kodierte Konfigurator-URLs ab undmax:500ist für lange Konfigurator-Links zu kurz. → auf['nullable','string','max:2048']ändern und Blade-Input auftype="text". Konsistent für alle URL-Felder im Warenwirtschaftsmodul. - Aufwand: ~30 Min.
B3 — „Weitere Charge": es erscheinen zwei Felder statt einem
- Anforderung (Todos Z. 14, Briefing 5.2.6): Klick auf „Weitere Charge" soll genau eine neue Zeile/Dropdown hinzufügen.
- Status: JS-Fehler in der Produktions-Create/Edit-View (Chargen-Splitting). Wird in AP-09 (Produktionskorrekturen) sauber behoben, da es mit der Soll-Neuberechnung zusammenhängt.
B4 — iPad: Produktionsdatum und Stückzahl überlappen grafisch
- Anforderung (Todos Z. 86, Briefing 5.2.6 D): Responsive Grid der Kopfdaten in
productions/create.blade.php/edit.blade.phpreparieren. → Teil von AP-09.
B5 — Tabellen-Aktionsicons (Auge/Stift/Mülleimer) zu klein/zu eng (iPad)
- Anforderung (Todos Z. 36, Briefing 5.2.3 C): Betrifft alle Tabellen im Modul. Eine gemeinsame CSS-Utility-Klasse (z. B.
.wawi-actionsmit größeren Touch-Targets + Abstand) einführen und in allenindex.blade.phpanwenden. → AP-04 (Querschnitt, früh, weil überall sichtbar).
Optimierungen (Konsistenz/Sauberkeit)
- O1:
IngredientControllernutzt nochRequest::all()statt FormRequest → bei INCI-Erweiterung (AP-07) aufStoreIngredientRequest/UpdateIngredientRequestumstellen. - O2: Offene Tests aus Phase 5.1 (Menü-Labels, INCI-Qualität, Prozent-Rezeptur, 100%-Summe, Hersteller-Rezeptur, Produktion edit/copy, nur aktive Produkte) sind im Plan als
[ ]markiert, aber Features sind umgesetzt → AP-00 schreibt diese Tests nach, um eine grüne Regressionsbasis zu haben, bevor 5.2 beginnt. - O3: Steuerart als Enum, später änderbar gewünscht (feedback/Briefing INCI B). Lösung: konfigurierbare
tax_rates-Stammdaten statt Hardcode-Enum (AP-05).
3. Priorisierte Roadmap (Phasenüberblick)
| Reihenfolge | AP | Titel | Abhängigkeit | Aufwand |
|---|---|---|---|---|
| 1 | AP-00 | Regressionsbasis: offene 5.1-Tests nachziehen | – | 1 Tag |
| 2 | AP-01 | Quick-Fixes B1/B2 (URL-Felder) | – | 0,5 Tag |
| 3 | AP-04 | Querschnitt: iPad-taugliche Tabellen-Aktionen (B5) | – | 0,5–1 Tag |
| 4 | AP-05 | Einstellungen: UST-Sätze & Lieferzeiten (Stammdaten) | – | 1–2 Tage |
| 5 | AP-06 | Lieferanten erweitern (Bestellweg, Lieferzeit) | AP-05 | 1–2 Tage |
| 6 | AP-07 | INCI erweitern (Lieferanten-Mehrfachwahl, UST, Lieferzeit) | AP-05, AP-06 | 2–3 Tage |
| 7 | AP-08 | Einkauf erweitern (UST, Netto/Brutto, Duplizieren) | AP-05 | 2–3 Tage |
| 8 | AP-09 | Produktion korrigieren (Hersteller-Rezeptur, Charge-JS, iPad, Produktentwicklung-Platzhalter) | – | 2–4 Tage |
| 9 | AP-02 | Produkt-Klassen: Einzelprodukt vs. Set + Hauptprodukt | – | 3–5 Tage |
| 10 | AP-03 | „Nicht vorrätig" mit Zeitangabe | – | 1–2 Tage |
| 11 | AP-10 | Rohstoffbestand (InventoryService + Übersicht) | AP-06, AP-07, AP-09 | 4–6 Tage |
| 12 | AP-11 | Produktbestand + Historie + manuelle Bewegungen | AP-02, AP-10 | 5–8 Tage |
| 13 | AP-12 | Ausgang/Ausschuss (Rohstoffe/Verpackung) | AP-10 | 2–3 Tage |
| 14 | AP-13 | Shop-Anbindung: Bestand bei Verkauf reduzieren (inkl. Sets) | AP-02, AP-11 | 3–5 Tage |
| 15 | AP-14 | Audit-Trail (inventory_logs) | AP-10–13 | 2–3 Tage |
| 16 | AP-15 | Blockbasierte Rechte | AP-05+ | 5–8 Tage |
| 17 | AP-16 | 2FA Google Authenticator für Admins | – | 3–5 Tage |
| 18 | AP-17 | Warenwirtschafts-Einstellungen (Alarm-Mail, Default-Lager, Schwellwerte) | AP-10/11 | 1–2 Tage |
| 19 | AP-18 | Hinweise-/Doku-Seite (Einstellungen → Hinweise, MD-basiert) | – | 0,5 Tag |
Leitplanke: AP-00 bis AP-09 sind „Korrektur & Datenmodell-Vorbereitung". Erst danach werden die großen Übersichten (Rohstoff-/Produktbestand) gebaut, weil sie auf den neuen Stammdatenfeldern aufsetzen.
4. Arbeitspakete im Detail
AP-00 — Regressionsbasis: offene 5.1-Tests nachziehen
Ziel: Grüne Test-Suite als Sicherheitsnetz, bevor 5.2 beginnt.
Schritte
- Pest-Feature-Tests ergänzen (
php artisan make:test --pest <Name>):- Menü-Labels (Rohstoffqualität, Verpackungsmaterial, Produkt-/Versandverpackung).
- INCI mit
material_quality_idspeichern + Anzeige im Produktformular-Katalog. - Rezeptur in Prozent (3 Nachkomma) speichern; 100%-Summen-Validierung (grün/rot).
- Hersteller-Rezeptur getrennt speichern (
recipe_type=manufacturer). - Produktion
edit/updateundcopy. - Nur aktive Produkte im Produktions-Dropdown.
Akzeptanz: php artisan test läuft vollständig grün; neue Tests decken die genannten Features ab.
AP-01 — Quick-Fixes URL-Felder (B1 + B2)
Schritte
resources/views/admin/inventory/suppliers/form.blade.php:type="url"→type="text"(Zeile ~56).- URL-Validierung aller Warenwirtschafts-FormRequests prüfen (Supplier ist ok).
Store/UpdatePackagingItemRequest: fallsurl-Regel → auf['nullable','string','max:2048']ändern; zugehöriges Blade-Input auftype="text". vendor/bin/pint --dirty.
Akzeptanz
- Lieferant mit ausgefüllter URL (auch ohne
https://und mit kodierten Parametern) speichert ohne Fehler. - Konfigurator-URL aus Todos Z. 2 wird unverändert gespeichert.
Tests: Feature-Test „Supplier mit Parameter-URL speichern", „PackagingItem mit Parameter-URL speichern".
AP-04 — Querschnitt: iPad-taugliche Tabellen-Aktionen (B5)
Schritte
- Gemeinsame CSS-Klasse
.wawi-actions(größere Buttons, mehr Abstand, Touch-Target ≥ 44px) in vorhandenes Admin-CSS aufnehmen (Laravel Mix; danachnpm run dev/prod). - In allen
resources/views/admin/inventory/**/index.blade.phpdie Aktionsspalte (Auge/Stift/Mülleimer) auf die Klasse umstellen.
Akzeptanz: Aktionen sind auf dem iPad gut und einzeln klickbar; Optik in allen Modul-Tabellen konsistent.
AP-05 — Einstellungen: UST-Sätze & Lieferzeiten
Ziel: Konfigurierbare Steuersätze und Lieferzeit-Vorlagen als Stammdaten (Basis für AP-06/07/08).
DB
tax_rates:name(z. B. „Standard"),percentDECIMAL(5,2),activebool,pos. Seeder: 19,00 / 7,00 / 0,00.delivery_times:labelVARCHAR (Freitext, z. B. „3–5 Werktage"),days(ganze Tage bis Wareneingang, optional – Basis für „rechtzeitig bestellen"-Ableitung),active,pos.
Code
- Models
TaxRate,DeliveryTime(make:model -mf), CRUD-Controller unterAdmin/Inventory/, FormRequests, Viewsindex+form, Routen unteradmin/inventory(superadmin), Sidenav-Einträge.
Akzeptanz: SuperAdmin pflegt UST-Sätze und Lieferzeiten; nur aktive Sätze sind in Dropdowns wählbar; historische (deaktivierte) Sätze bleiben referenzierbar.
Entscheidung (O3): UST als Stammdaten-Tabelle statt PHP-Enum, weil „später änderbar" gefordert ist und historische Werte erhalten bleiben müssen.
Umgesetzte Struktur (Kunde, 02.06.2026): Unter Warenwirtschaft → Einstellungen neuer Unterpunkt „Allgemein" als Sammelseite für kleinteilige Einstellungen. Sektion 1 = Umsatzsteuersätze, Sektion 2 = Lieferzeit-Vorlagen (jeweils Tabelle, neue Einträge jederzeit ergänzbar). Weitere kleinteilige Einstellungen (Default-Werte etc.) werden später als zusätzliche Karten auf derselben „Allgemein"-Seite ergänzt.
Status: Erledigt — Teil 1 (
tax_rates) und Teil 2 (delivery_times) als CRUD unter „Allgemein".
AP-06 — Lieferanten erweitern
DB (suppliers)
order_methodENUM(email,online_shop) nullable.order_emailnullable (falls abweichend vonemail).order_urlnullable (falls abweichend vonurl).delivery_timeVARCHAR nullable (Freitext; optional Verknüpfung mitdelivery_timesals Vorlage, aber Freitext bleibt führend).
Code
- Migration +
Supplierfillable/casts;Store/UpdateSupplierRequesterweitern;suppliers/form.blade.php: Radio/Select Bestellweg + bedingte Felder + Lieferzeit-Textfeld (mit Vorlagen-Datalist ausdelivery_times).
Akzeptanz: Pro Lieferant ist Bestellweg + Ziel (Mail/Shop) + Lieferzeit hinterlegt und editierbar; Daten stehen später dem Rohstoffbestand für Bestell-Links zur Verfügung.
Status: Erledigt (02.06.2026). Migration
2026_06_02_154755_add_order_fields_to_suppliers_table(order_method,order_email,order_url,delivery_time). Formular mit Bestellweg-Select, JS-gesteuerten bedingten Feldern (E-Mail vs. URL) und Lieferzeit-Datalist aus aktivendelivery_times. Freitext bleibt führend, Vorlagen sind nur Eingabehilfe. Tests:tests/Feature/SupplierOrderFieldsTest.php.Nachtrag (02.06.2026, Kunde): Lieferzeit ist jetzt zusätzlich als fester Tageswert auswertbar. Lieferzeit-Vorlagen haben Feld
days(ganze Tage). Lieferant hatdelivery_time_days(2026_06_02_160411_*). Beim Auswählen einer Vorlage im Lieferzeit-Feld setzt JS automatisch den Tageswert (manuell überschreibbar). Dieser Tageswert ist die Grundlage, um später Rohstoffe rechtzeitig vor MHD/Bedarf zu bestellen. Gleiche Auto-Befüllung wird in AP-07 (INCI) übernommen.
AP-07 — INCI erweitern
DB
- Pivot
ingredient_supplier:ingredient_id,supplier_id, optionalpreferredbool,supplier_sku,url. ingredients:tax_rate_idnullable FK,delivery_timeVARCHAR nullable.
Code
Ingredient:suppliers()belongsToMany,taxRate()belongsTo; fillable/casts.- O1:
IngredientControlleraufStoreIngredientRequest/UpdateIngredientRequestumstellen (Ersatz fürRequest::all()). admin/ingredient/form.blade.php: Select2-Mehrfachauswahl Lieferanten, UST-Dropdown (aktivetax_rates), Lieferzeit-Textfeld.
Lieferzeit-Logik: INCI-Lieferzeit überschreibt Lieferanten-Lieferzeit (Auswertung erst im Rohstoffbestand AP-10).
Akzeptanz: INCI kann mehrere Lieferanten, einen UST-Satz und eine eigene Lieferzeit haben; alles wird gespeichert und angezeigt.
Status: Erledigt (02.06.2026). Migrationen
2026_06_02_161237_add_order_fields_to_ingredients_table(tax_rate_idFK,delivery_time,delivery_time_days) +2026_06_02_161237_create_ingredient_supplier_table(Pivot mitpreferred/supplier_sku/url).Ingredient:taxRate()belongsTo,suppliers()belongsToMany (mit Pivot-Feldern), castdelivery_time_days. O1 umgesetzt:IngredientControllernutzt jetztStoreIngredientRequest(stattRequest::all()) und synct Lieferanten viasuppliers()->sync(). Formular: UST-Dropdown, Select2-Lieferanten-Mehrfachwahl, Lieferzeit-Textfeld mitdata-days-Datalist + Tage-Feld inkl. JS-Autofill (manuell überschreibbar). Der bestehende Single-Endpoint (admin_product_ingredient_storefür Neu+Update) wurde beibehalten, daher genügt ein FormRequest. Pivot-Zusatzfelder (preferred/supplier_sku/url) sind im Schema vorbereitet, das Formular synct vorerst nur die Lieferanten-Zuordnung. Tests:tests/Feature/IngredientOrderFieldsTest.php(6 grün).
AP-08 — Einkauf erweitern
DB (stock_entries)
tax_rate_idnullable FK + Snapshottax_rate_percentDECIMAL(5,2) (für historische Korrektheit).price_per_kg_netDECIMAL(10,4) nullable,price_per_kg_grossDECIMAL(10,4) nullable.
Code
- Migration +
StockEntryfillable/casts;Store/UpdateStockEntryRequesterweitern (genau eines von Netto/Brutto verpflichtend bei Rohstoff). stock-entries/_form.blade.php+_scripts.blade.php: UST-Dropdown; JS berechnet Netto↔Brutto gegenseitig beim Eintragen/UST-Wechsel (einheitliche Rundung).- Duplizieren: Route
GET stock-entries/{stock_entry}/copy+StockEntryController@copy: dupliziert Stufe-1-Felder, setztstatus=pending, lässt Charge/MHD/Eingangsdaten leer.
Akzeptanz
- Einkauf mit Netto oder Brutto anlegbar; Gegenfeld wird automatisch korrekt berechnet.
- UST-Wechsel aktualisiert das Gegenfeld.
- Ausgefüllter Einkauf für weitere Kanister/Chargen mit einem Klick duplizierbar.
Tests: Netto→Brutto-Berechnung, Brutto→Netto, Duplizieren erzeugt pending-Kopie ohne Chargendaten.
Status: Erledigt (02.06.2026). Migration
2026_06_02_181548_add_price_fields_to_stock_entries_table(price_per_kg_gross,tax_rate_id,tax_rate_percent). Das bereits vorhandeneprice_per_kgdient als Netto-Feld (price_per_kg_net), ergänzt umprice_per_kg_gross; bewusst kein Rename, um Bestandsdaten/Factory/Tests stabil zu halten. Netto/Brutto-Umrechnung zentral inStockEntryRepository::resolvePrices()(UST-Prozent-Snapshot, fehlender Wert wird berechnet), live im Formular via JS. Duplizieren überstock-entries/{id}/copylegt direkt einepending-Kopie der Stufe-1-Felder an. Verpackungspreis bleibt Netto-Gesamt ohne UST/Brutto (außerhalb des Plan-Scopes, kann später ergänzt werden). Tests:tests/Feature/StockEntryPriceTest.php(6 grün).
AP-09 — Produktion korrigieren
Ziel: Produktion auf Hersteller-Rezeptur stellen, JS-/iPad-Fehler beheben, Platzhalter Produktentwicklung.
Code
- Basis Hersteller-Rezeptur:
ProductionService::store(),updateProduction(),requiredGramsByIngredient(),buildRecipePayload()vonp_ingredientsaufmanufacturer_ingredientsumstellen (Pivotgram/factoranalog).ProductionController::recipeJson()entsprechend.Entscheidung (§5.1, geklärt): Produktion nutzt ausschließlich die Hersteller-Rezeptur. Kein Fallback auf die Produkt-Rezeptur. Ist für das gewählte Produkt keine Hersteller-Rezeptur gepflegt, muss im Produktions-Formular direkt eine deutliche Warnung erscheinen (kein stilles Laden der Produkt-Rezeptur, Produktion ohne Hersteller-Rezeptur blockieren bzw. unmissverständlich warnen).
- Chargen-Dropdown-Label:
Lieferant - Chargennr. - dd.mm.yyyy(kein „MHD"-Text). Nur Chargen mit Restbestand > 0 anzeigen (Restbestand =received_quantity− bereits inproduction_ingredientsverbrauchte Menge dieser Charge). Erfordert Verbrauchsabfrage jestock_entry_id. - B3 JS-Fix: „Weitere Charge" fügt genau eine Zeile/ein Dropdown hinzu.
- Soll-Neuberechnung stabil: Ändert sich oben die Stückzahl, bleiben bereits eingetragene Chargen/Ist-Mengen erhalten; nur Soll-Gramm werden neu berechnet (keine Überschreibung manueller Eingaben).
- UI vereinfachen: Spaltenüberschriften „Charge"/„Menge" pro Rohstoffzeile entfernen;
ghinter Mengen; weniger Linien. - B4 iPad-Fix: Bootstrap-Grid der Kopfdaten (Produktionsdatum / Stückzahl) responsive ohne Überlappung.
- Produktentwicklung-Platzhalter (§5.5, geklärt): Sidenav-Unterpunkt unter „Produktion"; Route + simple View mit Hinweistext, dass hier noch ein genaues Briefing aussteht (keine Bestandsbuchung, keine Logik).
Akzeptanz: Produktion rechnet auf Basis Hersteller-Rezeptur; fehlt diese, erscheint eine Warnung (kein Fallback); Chargenliste zeigt nur verfügbare Chargen im geforderten Label; „Weitere Charge" erzeugt eine Zeile; Stückzahländerung zerstört keine Eingaben; iPad-Layout sauber; Menüpunkt Produktentwicklung mit „Briefing ausstehend"-Hinweis sichtbar.
Tests: Soll-Verbrauch aus Hersteller-Rezeptur; Warnung bei fehlender Hersteller-Rezeptur; Charge ohne Restbestand erscheint nicht; Service-Berechnung bei Stückzahländerung.
AP-02 — Produkt-Klassen: Einzelprodukt vs. Set + Hauptprodukt
Entscheidung (§5.6, geklärt): Echte Sets via Pivot (
product_set_items) — mehrere Einzelprodukte bündelbar, nicht nur „genau ein Hauptprodukt".
DB (products)
is_setbool default 0.main_product_idnullable FK aufproducts(Child→Hauptprodukt).main_product_quantityUINT nullable (z. B. 50 für „50 × 15 ml").- Pivot
product_set_items:set_product_id,component_product_id,quantity.
Code
Product:setItems(),mainProduct(), ScopesmainProducts()/singleProducts().- Produktformular: Checkbox „Ist Set"; bei aktiv Karten Rezeptur/Verpackung/Warenwirtschaft ausblenden, Karte „Set-Bestandteile" einblenden (Modal wie Rezeptur, nur Einzelprodukte wählbar, mit Menge).
- Validierung: Set enthält nur Einzelprodukte (keine Sets), mind. 1 Bestandteil; Einzelprodukt darf Rezeptur/Packaging/Warenwirtschaft pflegen.
Akzeptanz: Sets bestehen aus Einzelprodukten mit Menge; Sets sind nicht produzierbar; Produktbestand (AP-11) zeigt nur Haupt-/Einzelprodukte; Set-Verkauf reduziert später die enthaltenen Einzelprodukte (AP-13).
AP-03 — „Nicht vorrätig" mit Zeitangabe
DB (products)
out_of_stock_untilDATE nullable (Empfehlung: aus Tagen berechnet, sauber für Resttage).out_of_stock_indefinitebool default 0 (zweites Kästchen „auf unbestimmte Zeit vergriffen", ohne Tagefeld).
Code
- Produktformular: Checkbox „Nicht vorrätig" + Tagefeld →
out_of_stock_until = now()->addDays($tage); zweite Checkbox „unbestimmt". - Shop-/Bestellansicht: bei
out_of_stock_untilin der Zukunft Hinweis „In ca. X Tagen wieder da!" (Resttage dynamisch); beiindefiniteentsprechender Dauerhinweis.
Entscheidung (§5.3, geklärt): Vorerst nur Hinweis, der Kauf bleibt möglich. In der Hinweise-Doku (AP-18) ist zu dokumentieren, dass künftig optional eine Kauf-Sperre ergänzt werden kann/muss.
Akzeptanz: Produkt zeitweise/unbefristet als nicht vorrätig markierbar; Resttage zählen automatisch herunter; nach Ablauf verschwindet der Hinweis ohne manuelles Zutun.
AP-10 — Rohstoffbestand (InventoryService + Übersicht)
Code
app/Services/InventoryService.php: Restbestand je Rohstoff/Charge/Lagerort =SUM(received_quantity)−SUM(production_ingredients.quantity_used)−SUM(stock_disposals.quantity)(Ausgang ab AP-12).- Controller + View „Rohstoffbestand" (Sidenav-Menüpunkt). Spalten: INCI/Rohstoff, Qualität, Gesamtbestand, Bestand je Lagerort (dynamisch aus
locations), verbraucht/Produktion, Meldebestand/Bedarf, Status, Lieferanten, Lieferzeit (INCI vor Lieferant), Bestellaktion (mailto:/Shop-Link jeorder_method). - Nur Chargen mit Restbestand > 0 einbeziehen; kritische Rohstoffe visuell markieren.
Akzeptanz: Reale Restbestände sichtbar; Bestellweg direkt aus der Übersicht erreichbar; kritische Rohstoffe hervorgehoben.
AP-11 — Produktbestand + Historie
DB
product_stock_movements:product_id,directionENUM(in,out),quantity,reason,source(produktion/verkauf/manuell/set),user_id,created_at,reference_type/reference_id(polymorph, nullable).- Schwellwerte: Felder an
products(min_product_stock,critical_product_stock) oder eigene Tabelle. - Initialisierung (Briefing): Lagerbestand einmalig einpflegbar (Anfangsbestand als
in-Bewegung mit Grund „Initialbestand").
Code
- Bestand =
SUM(in)−SUM(out). Manuelle Bewegung: Menge + Grund + Richtung Pflicht. - Hauptmenü „Produktbestand" (nur Hauptprodukte, Suche, Checkbox „nur kritische", Buttons
+/−/Produzieren, rot/gelb-Markierung) + Untermenü „Historie" (filterbar Produkt/Quelle/Zeitraum/User; revisionssicher, Korrektur nur per Gegenbuchung).
Akzeptanz: Bestand schnell pflegbar; jede Bewegung in der Historie; nur Hauptprodukte sichtbar; Kritisch-Filter funktioniert.
AP-12 — Ausgang / Ausschuss (Rohstoffe/Verpackung)
stock_disposals(Typ, Artikel, Charge optional, Lagerort, Menge, Einheit, Grund Pflicht, User, Datum) + Controller/Views; Integration inInventoryService.- Akzeptanz: Ausgang reduziert Rohstoff-/Verpackungsbestand; Grund ist Pflicht.
AP-13 — Shop-Anbindung: Bestand bei Verkauf reduzieren
- Entscheidung (§5.2, geklärt): Bestandsabzug erfolgt beim Versand (erst wenn der Versand gebucht ist, wurde das Produkt real „aus dem Regal" genommen). Dieser Hinweis ist auch in der Hinweise-Doku (AP-18) zu hinterlegen.
- Beim Statuswechsel auf versendet
product_stock_movements-out-Buchung; bei Sets die enthaltenen Einzelprodukte (× Menge) reduzieren. Stornos/Retouren als Gegenbuchung (Detailregel bei Umsetzung festzurren). - Akzeptanz: Versand reduziert Produktbestand; Set-Versand reduziert Einzelprodukte; jede Buchung in der Historie.
AP-14 — Audit-Trail
inventory_logs(polymorph) + Observer aufStockEntry/Production/StockDisposal/ProductStockMovement.- Akzeptanz: Jede Bestandsbewegung wird mit User/Zeit/Änderungen protokolliert.
AP-15 — Blockbasierte Rechte
- Entscheidung (§5.4, geklärt): Blockrechte gelten nur für Warenwirtschaft und Produktmanagement, nicht für alle Admin-Bereiche. In der Hinweise-Doku (AP-18) dokumentieren, dass die Rechte bei Bedarf später ausgebaut werden können/müssen, falls sie nicht ausreichen.
admin_permission_blocks+admin_permission_user(view/edit pro Block: Produkte, Einkauf, Rohstoffbestand, Produktbestand, Produktion, Lieferanten, Einstellungen, Historie); Middleware/Gates; Sidenav zeigt nur erlaubte Blöcke.- Bestehende Level (
copyreader/admin/superadmin) bleiben als Grundschutz. - Akzeptanz: SuperAdmin vergibt pro Mitarbeiter view/edit je Block (Warenwirtschaft + Produktmanagement); Leserecht ohne Schreibrecht greift; gesperrte Blöcke unsichtbar.
AP-16 — 2FA Google Authenticator (Admins)
- TOTP-Secret am
App\User(Guarduser), Setup-Flow, Login-Zwischenschritt; Recovery-Codes. - Akzeptanz: Bei aktivem 2FA kein Zugriff auf geschützte Bereiche ohne Code.
AP-17 — Warenwirtschafts-Einstellungen
- Über bestehendes
Setting-Model:inventory_alert_email,inventory_alert_enabled,inventory_default_location, optional Produktbestands-Schwellwerte, Standardtexte „Nicht vorrätig". SuperAdmin-only.
AP-18 — Hinweise-/Doku-Seite (Einstellungen → Hinweise)
Anforderung (§5, Kunde): Eine als MD gepflegte Doku, die unter Warenwirtschaft → Einstellungen → „Hinweise" im Admin sichtbar ist, damit auch der Kunde Einsicht hat.
Code
- Markdown-Datei im Repo (z. B.
docs/hinweise.mdoderresources/docs/hinweise.md) als Pflege-Quelle. - Route + View unter
admin/inventory(Einstellungen-Gruppe), die das MD gerendert anzeigt (Parsedown o. Ä.); Sidenav-Eintrag „Hinweise".
Inhalt (laufend zu pflegen):
- Kurzer Entwicklungsstand / Überblick (was fertig ist, was offen ist).
- Wichtige Hinweise & noch nötige Schritte verständlich für den Kunden.
- Festgehaltene offene/spätere Entscheidungen, u. a.:
- „Nicht vorrätig" kann künftig optional zur Kauf-Sperre ausgebaut werden (§5.3).
- Blockrechte ggf. später über Warenwirtschaft/Produktmanagement hinaus ausbauen (§5.4).
- Shop-Bestandsabzug erfolgt bei Versand (§5.2).
- Akzeptanz: Kunde sieht unter Einstellungen → Hinweise eine lesbare, gepflegte Statusseite.
Empfehlung: Früh als Platzhalter anlegen und mit jedem AP fortschreiben, damit der Kunde jederzeit den Stand sieht.
5. Klärungspunkte — ALLE GEKLÄRT (Kunde, 02.06.2026)
Alle Punkte sind beantwortet und in die jeweiligen Arbeitspakete eingearbeitet. Keine Blocker mehr offen.
-
Produktion-Basis → Ausschließlich Hersteller-Rezeptur. Kein Fallback. Ist keine angelegt, erscheint direkt eine Warnung. → eingearbeitet in AP-09.
-
Shop-Bestandsabzug → Beim Versand (erst mit gebuchtem Versand ist das Produkt real „aus dem Regal"). Als Hinweis dokumentieren. → eingearbeitet in AP-13 + Hinweis in AP-18.
-
„Nicht vorrätig" → Vorerst nur Hinweis. Dokumentieren, dass künftig optional eine Kauf-Sperre ergänzt werden kann. → eingearbeitet in AP-03 + Hinweis in AP-18.
-
Blockrechte-Geltung → Nur Warenwirtschaft und Produktmanagement. Dokumentieren, dass die Rechte bei Bedarf später ausgebaut werden können. → eingearbeitet in AP-15 + Hinweis in AP-18.
-
Produktentwicklung → Platzhalter-Seite mit Hinweis, dass ein genaues Briefing noch aussteht. → eingearbeitet in AP-09.
-
Child-Produkt / Sets → Echte Sets via Pivot (
product_set_items). → eingearbeitet in AP-02. -
Hinweise-Doku (neu): MD-basierte Doku-Seite unter Einstellungen → Hinweise mit Entwicklungsstand, wichtigen Hinweisen und noch nötigen Schritten, einsehbar auch für den Kunden. → neues AP-18.
6. Empfohlene Sofort-Reihenfolge (nächste Schritte)
✅ Erledigt: AP-00, AP-01, AP-04 (+ AP-04.1), AP-05, AP-06 (+ Nachtrag), AP-07 (+ AP-07.1), AP-08.
➡️ Hier geht es weiter:
- AP-09 Produktionskorrekturen: ausschließlich Hersteller-Rezeptur (+ Warnung bei fehlender Rezeptur, kein Fallback), Chargen-Label + Restbestandsfilter, B3 „Weitere Charge"-Fix, stabile Soll-Neuberechnung, B4 iPad-Layout, Produktentwicklung-Platzhalter.
- AP-18 Hinweise-Doku (Einstellungen → Hinweise) — kann parallel/früh als Platzhalter angelegt und laufend gepflegt werden.
- Datenmodell AP-02 (Sets via Pivot) / AP-03 („Nicht vorrätig", nur Hinweis).
- Große Übersichten AP-10/AP-11 und Folge-APs (AP-12–AP-17).
7. Pflege dieses Dokuments
- Jedes abgeschlossene AP hier mit Datum + Kurzbeschreibung + Test-Status protokollieren (analog Umsetzungsprotokoll in
entwicklungsplan.md). - Bei DB-Änderungen: Migration-Dateinamen referenzieren; bei Modellen Casts in
casts()-Methode pflegen (L11-Konvention). - Vor jedem Commit:
vendor/bin/pint --dirtyund betroffene Tests (php artisan test --filter=...).