Commit graph

56 commits

Author SHA1 Message Date
313c6277ce Warenwirtschaft: N-01/N-03/N-05 — Entwurfsmenge ohne Charge, Snapshot-Signatur je Produkt, Alt-Ausschuss in Chargenverfügbarkeit
- N-01: Ist-Menge ohne gewählte Charge bleibt im Entwurf erhalten (Filter in
  Request und Service, formBatchKey liefert '' für chargenlose Zeilen).
- N-03: outputSignature summiert Stückzahlen je Produkt — ein Chargensplit
  ersetzt den historischen Verpackungs-Snapshot nicht mehr.
- N-05: Ausschuss ohne Chargenbezug (Altbestand) wird für die Verfügbarkeit je
  Standort FEFO auf die Chargen angerechnet (applyUnboundDisposals, lesend);
  Chargen-Ausschussprüfung nutzt dieselbe Verfügbarkeit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:48:02 +00:00
731b2461e2 Warenwirtschaft: F-16 — fachliche Vorbedingungen innerhalb der Sperre prüfen
- Statusservice: Vorbedingung (Ausgangsstatus, Zahlungsfreigabe) wird nach
  lockForUpdate erneut geprüft (Board übergibt sie als Closure).
- Wareneingang: Transaktion + Sperre, „offen“ wird innerhalb der Sperre geprüft.
- Ausschuss: betroffene Wareneingänge sperren und Restbestand in der
  Transaktion erneut prüfen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:09:53 +00:00
8808ff538f Warenwirtschaft: F-14 — „Enthalten in“ mit Anteil (%) und Verbrauch je Stück
Nur Hersteller-Rezeptur, alle Phasenzeilen je Produkt summiert, Skalierung
über Füllgewicht und Faktor wie in der Produktion; kein roher Pivot-Wert mehr.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:07:22 +00:00
8c460aa8bf Warenwirtschaft: F-12 — Verkaufs-Gegenbuchungen im Monatsverbrauch netto verrechnen
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 11:04:07 +00:00
a803e956e1 Warenwirtschaft: F-05 — historischer Verpackungs-Snapshot bleibt bei Notizkorrektur erhalten
updateProduction() baut die Verpackungszeilen nur neu auf, wenn sich
Ergebnisprodukte/Stückzahlen ändern oder ein Entwurf abgeschlossen wird.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 10:55:51 +00:00
104671e929 Warenwirtschaft: F-04 — Rezeptur-Phase an Verbrauchszeilen, keine Vervielfachung beim Wiederöffnen
production_ingredients.recipe_phase_id; Formular sendet die Phase je Zeile,
Vorbelegung je Rohstoff|Phase. Altbestand ohne Phase wird nur einmal eingesetzt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 10:54:59 +00:00
859b1f083d Warenwirtschaft: F-03 — Entwurf sichert Chargenzeilen verlustfrei
Entwürfe speichern batch_key roh (stock_entry_id nullable), keine Auflösung
und keine Filterung unfertiger Zeilen mehr beim Zwischenspeichern. Eine nicht
mehr verfügbare Charge wird im Formular markiert statt alle Zeilen zu verwerfen.
Ergebniszeilen dürfen im Entwurf ohne Stückzahl bleiben. Auflösung, Prüfung und
Buchung erst beim Abschluss.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 10:53:36 +00:00
9e745d1441 Warenwirtschaft: F-01 — Entwürfe zählen nicht mehr als Chargenverbrauch
consumedByStockEntry() schließt Entwürfe jetzt wie remainingByIngredient()
aus. Regression: Chargen-/Standortbestand, zweite Produktion, Ausschussprüfung.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 10:49:14 +00:00
abd202a02e Warenwirtschaft: AP-43 — Produktion zwischenspeichern (Entwurf) + „abschließen"
Der Speicher-Button heißt jetzt „Produktion abschließen"; daneben gibt es
„Zwischenspeichern (Entwurf)". Ein Entwurf sichert den Stand ohne Pflichtfeld-
und ohne Bestandsprüfung und bucht KEINEN Bestand (Roh-/Produkt-/Verpackung).
Erst „abschließen" prüft vollständig und bucht.

- Migration: productions.status (default 'completed'; Bestand ist bereits gebucht).
- Production-Model: STATUS_DRAFT/COMPLETED, isDraft(), scopeBooked().
- InventoryService: Entwürfe fallen aus allen Verbrauchs-/Bestandsjoins heraus
  (status != draft an den 4 productions-Joins).
- ProductionService store()/updateProduction() bekommen $draft: Entwurf
  überspringt Rezeptur-/Mengen-/Bestandsprüfung + Buchungen, sichert nur
  vollständige Chargen-Zeilen (filterCompleteLines) und die angegebenen Outputs.
  Ein abgeschlossene Produktion kann NICHT zurück in den Entwurf (sonst
  verwaisen die Buchungen) — Guard wirft ValidationException.
- StoreProductionRequest: save_mode=draft => nur Kopfdaten Pflicht, Chargen/
  Ergebnis optional; validatedPayload filtert unvollständige Zeilen/Outputs.
- Controller: Entwurf löst Chargen tolerant auf (nicht auflösbare Chargen werden
  übersprungen, Entwurf ist immer speicherbar) und leitet zur Bearbeitung zurück.
- Views: create/edit „abschließen" + „Zwischenspeichern"-Button (nur solange
  Entwurf); Entwurf-Badge in Liste + Bearbeiten-Kopf.

Tests: 5 neue (kein Produktbestand, kein Rohstoffverbrauch, Abschluss bucht,
Rück-Entwurf verboten, HTTP-Entwurf ohne Ergebnis ok / Abschluss erzwingt
Ergebnis). Migration auf Dev-/Live-DB. Suite 336 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-28 09:59:42 +00:00
30d4e28696 Warenwirtschaft: AP-51 — Lagerplatz-Felder für Produkte & Verpackung
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>
2026-08-28 09:46:40 +00:00
190713c21b Warenwirtschaft: AP-48 — Produktbestand-Buchungsgründe pflegbar, getrennt Ein/Aus
Kundenentscheid 26.08. (D-5): Eingang und Ausgang haben eigene, pflegbare
Gründe-Listen statt einer festen Liste im Controller.

- Neues Modell/Tabelle stock_movement_reasons (label, direction in/out, pos,
  active, SoftDeletes) inkl. Seed der bisherigen Gründe sinnvoll auf Ein-/Ausgang
  aufgeteilt.
- CRUD wie DisposalReason (SettingCrudController + FormRequest + Formular mit
  Richtungs-Auswahl); zwei Listen (Eingangs-/Ausgangs-Gründe) auf der Seite
  Einstellungen → Allgemeines, „Neu anlegen" mit vorbelegter Richtung.
- Produktbestand-Maske: das Grund-Dropdown wird jetzt je nach Eingang/Ausgang
  per JS aus den passenden, gepflegten Gründen befüllt (manualReasons entfernt).
- DeletionGuard: StockMovementReason immer löschbar.

Migration create_stock_movement_reasons auf Dev-/Live-DB. 4 Tests, Suite 326 grün.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-28 09:22:32 +00:00
d51860af39 Warenwirtschaft: AP-45 + AP-47 — Verpackung aus Produktionsergebnis, Produktionsrelevant-Flag
AP-45: Verpackungsverbrauch (Etikett/Tiegel) wird jetzt aus dem tatsächlichen
Produktionsergebnis gebucht — je Ergebnisprodukt dessen eigene Stückliste ×
Ergebnismenge, über alle Outputs summiert — statt aus der geplanten Stückzahl.
syncPackagingSnapshot liest die production_outputs und läuft daher nach
persistOutputs (store + update umgestellt).

AP-47: Neues Produkt-Kennzeichen „produktionsrelevant" (Boolean, Default true).
Nur so markierte Produkte erscheinen in der Produktions-Auswahl
(ProductionController create/edit/copy) und in der „Enthalten in"-Box des
Rohstoffbestands (blendet z. B. Aloe-Handelsware und Zweitgrößen aus).
Checkbox im Produktformular (mit Hidden-Fallback 0). Migration Default true,
damit Bestandsdaten unverändert bleiben.

Migrationen add_production_relevant auf Dev-/Live-DB ausgeführt. 4 Tests, Suite 314 grün.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-28 08:38:59 +00:00
4c6a57b0f1 Warenwirtschaft: AP-40 + AP-41 — Bestand/Differenz-Spalten, Ablage, Verpackung oben, Phasen-Gramm
AP-40: INCI-Tabelle der Produktion um zwei Spalten ergänzt — „Bestand" (aktueller
Rohstoffbestand je INCI, global) und „Differenz" (Bestand − Soll; negativ rot =
Fehlmenge, sonst grün). Spaltenkopf „Regal" → „Ablage". Bestand kommt aus
InventoryService::remainingByIngredient und wird als current_stock in den
recipeJson-Payload gehängt (lazy aufgelöst — InventoryService hängt selbst von
ProductionService ab, Konstruktor-Injektion wäre zirkulär).

AP-41: „Verpackung (Vorschau)" direkt unter die INCI-Tabelle verschoben (man sieht
auf einen Blick den Gesamtbedarf). Je Phase die Gesamt-Gramm hinter dem Namen
(„Phase A (345 g)"), aktualisiert sich mit Stückzahl und Füllgewicht-Skala.

Test für den current_stock-Payload ergänzt. Suite 311 grün.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-28 08:27:43 +00:00
744b36cdcb Warenwirtschaft: AP-35 + AP-39 — Produktionsmengen auf Füllgewicht + ±5 % Abwiegen
AP-35 (Mengenberechnung): Die Hersteller-Rezeptur ist in Prozent hinterlegt; die
Sollmengen skalieren jetzt auf das Füllgewicht statt fest auf ~100 g. Neuer
Faktor recipeGramScale = Füllgewicht/100. Basis = neues, optionales Produkt-Feld
"fill_weight" (g); ist es leer, gilt bei ml-Produkten (unit=1) die Füllmenge
(contents_total) als Gramm (1 g/ml). Ohne Massenbasis (z. B. Stück-Produkte)
bleibt es beim Altverhalten (Anteil = Gramm), sodass Bestandsprodukte/Tests
unverändert rechnen. Skala wird an die Maske durchgereicht (recipe_gram_scale),
damit Client und Server identisch rechnen (Service + 4 JS-Stellen).

AP-39 (Abwiegen): Die Ist-Menge je INCI muss nicht mehr aufs Gramm passen —
assertLinesMatchRecipe erlaubt ±5 % (kleiner absoluter Sockel), gebucht wird der
reale Ist-Wert. Status-Ampel in der Maske: Orange = nichts eingetragen,
Grün = eingetragen und ±5 %, Rot = >5 % daneben (Zahlendreher-Schutz).

Migration add_fill_weight_to_products auf Dev-/Live-DB ausgeführt (nullable).
Product fillable/cast + Produktformular-Feld ergänzt. 5 Tests, Suite 310 grün.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-27 14:36:52 +00:00
ddd6dde593 Warenwirtschaft: Review-Fix — Mahnwesen-Storno über OrderStatusService::setShipped
Der Auto-Storno der Zahlungserinnerung schrieb shipped=10 direkt und rief
nur syncSaleStock() — Margen-Storno-Flag, pending_to/shipped_at-Reset und
Promotions-/Guthaben-Folgen fehlten. Die Partnerprovision einer
versendeten, nie bezahlten Bestellung wäre zahlbar geblieben.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 09:47:20 +00:00
3eb14762e7 Warenwirtschaft: Review-Fix — Stichtags-Schutz als unveränderliches Flag (sale_stock_exempt)
Der Schutz historischer Bestellungen hing an shipped_at, das der
OrderStatusService beim Status-Toggle nullt und neu stempelt — Storno +
erneutes Versenden einer Alt-Bestellung hätte rückwirkend vom heutigen
Bestand abgezogen. Migration mit einmaligem Backfill (shipped_at vor
16.07.2026), Guard prüft nur noch das Flag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 09:41:01 +00:00
a367d851f6 Warenwirtschaft: AP-33a Bestell-Abwicklung — Nav „Bestellungen" + Fulfillment-Board
Neuer Nav-Punkt „Bestellungen" (Abwicklung + API-Bestellungen als Unterpunkte).
Board für Versand-Mitarbeiter (copyreader): 4 Filter-Kacheln (heute eingegangen /
zu konfektionieren / versandfertig / heute versendet), Packliste je Bestellung
(Sets mit Komponenten), Dokumente (Rechnung/Lieferschein/Kombi-Download über
eigene copyreader-Route, Erstellen ohne Mailversand; API-Bestellungen verlinken
die externe Rechnung), Aktionen Konfektioniert/Versendet (nur vorwärts, Storno
bleibt Verkäufe/admin). Versandfertig-Regel per Kundenentscheid: Rechnung sofort,
Vorkasse nach Zahlungseingang, API immer (ShoppingOrder::isReadyToShip()).
Statuswechsel-Logik in OrderStatusService extrahiert (Verkäufe-Modal + Board
teilen Transaktion/Lock/Margin-Folgen/AP-13-Abzug). Kundenentscheid Punkt 3:
Board-Statuswechsel setzt shipped_status_locked — die Bestell-Detailseiten
ändern den Status dann nicht mehr automatisch (offen → in Bearbeitung).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 11:30:57 +00:00
c0476ebe24 Warenwirtschaft: AP-13 — Stichtags-Schutz für vor Einführung versendete Bestellungen
Erneutes Speichern des Versandstatus einer Alt-Bestellung (shipped_at vor
16.07.2026) hätte rückwirkend vom heutigen Bestand abgezogen. syncSaleStock()
überspringt historische Bestellungen jetzt per Stichtag SALE_STOCK_SINCE.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 09:31:23 +00:00
211aeed384 Warenwirtschaft: AP-13 Shop-Bestandsabzug bei Versand (inkl. Sets)
ProductStockService::syncSaleStock(): idempotenter Differenz-Abgleich der
Verkaufs-Abgänge (source='sale', Referenz = Bestellung) mit dem Versandstatus —
Abzug je Bestellposition bei versendet/abgeschlossen, Sets rekursiv über
product_set_items in Einzelprodukte aufgelöst; Zurücksetzen/Storno führt per
Gegenbuchung zurück (behebt auch das Doppelabzug-Risiko Versand→Zurücksetzen→
Versand). Andockpunkte: SalesController::store (in der Transaktion) und
PaymentReminderService (Auto-Storno per Cron). Verbrauch/Monat zählt
Verkaufs-Abgänge automatisch mit (source != production).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 07:53:52 +00:00
9b6c9def97 Warenwirtschaft: N-1 — Chargen-Gruppierung je Lieferant (Kundenentscheid 15.07.2026)
Chargennummern kommen von extern und können kollidieren. Der Lieferant
gehört jetzt zum Gruppenschlüssel (batchGroupKey b:<supplier>:<lot>) —
gleiche Lot-Nummern verschiedener Lieferanten verschmelzen nicht mehr
(kein gemeinsames min-MHD/Summen-Rest). Batch-Check (AP-27) prüft
zusätzlich den Lieferanten des zu buchenden Eingangs.

Tests: +1 (getrennte Optionen je Lieferant); Chargen-Tests auf neues
Schlüsselformat umgestellt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 13:25:35 +00:00
d34f0a77f4 Warenwirtschaft: Audit-Niedrigbefunde N-2/3/4/5/7/8/9/15
- N-2: Letzter Netto-Preis je Lieferant nur aus tatsächlichen
  Eingängen (status received).
- N-3: Verbrauchsfenster exakt (kein startOfDay-Off-by-one).
- N-4: Kritisch-Zählung vereinheitlicht — Controller liefert die
  Kachel-Zählweise (inkl. critical_ordered), tote View-Überschreibung
  entfernt; Sidenav-Badge bleibt bewusst ohne bestellte Kritische.
- N-5: Ausschuss-Liste zeigt das 500er-Limit an + "Alle anzeigen"
  (?all=1), analog OPT-3.
- N-7: parseQuantity parst Strings konsequent im deutschen Format —
  Server und UI-Ampel interpretieren "1.500" jetzt identisch.
- N-8: Produktions-Kopie übernimmt keine alten Chargen-Nummern mehr
  (Auto-Vorschlag Präfix+ttmmjj greift).
- N-9: recordProductionStock lädt Produkte withTrashed — Korrektur-
  Gegenbuchungen soft-gelöschter Output-Produkte werden nicht mehr
  übersprungen.
- N-15: Hinweise/Leitfaden-Markdown mit html_input=strip +
  allow_unsafe_links=false gerendert.

Bewusst offen (Kundenentscheid/Design): N-1 (Chargen-Gruppierung ohne
supplier_id), N-6 (reFormatNumber-Konvention app-weit), N-10 (manuelle
Bewegung darf ins Minus, Inventur-Korrekturen), N-13 (mfg_row_phase-
Fallback auf phasenlos).

Suite: 231 grün, 823 Assertions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 12:57:26 +00:00
fa44af0a1f Warenwirtschaft: OPT-8 Rezeptur-Robustheit (Audit H-4, H-5, M-8, N-11/12/14)
- 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>
2026-07-15 12:48:55 +00:00
c69721d174 Warenwirtschaft: OPT-7 Buchungs-Härtung (Audit H-2, H-3, M-1, M-9)
- H-2: quantity_used muss > 0 sein (FormRequest-Regel + Service-Guard) —
  negative Zeilen konnten sich in der Summenprüfung aufheben und
  Chargen-Restbestände aufblähen.
- H-3: expandBatchLines() dekrementiert die gecachten Restmengen —
  zwei Zeilen derselben Charge belasten nicht mehr denselben Einkauf
  doppelt (FEFO korrekt über beide Zeilen).
- M-1: Ausschuss validiert Chargen-Konsistenz (gehört zum Rohstoff,
  received) und Restbestand (je Charge bzw. gesamt).
- M-9: lockForUpdate auf die Produktionszeile bei Update und Löschen.

Tests: neuer ProductionHardeningTest (4). Suite: 223 grün, 806 Assertions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 12:45:23 +00:00
84450385e3 Warenwirtschaft: OPT-6 Bestandswahrheit — Ausschuss in Chargen-Restmengen (Audit H-1, M-5)
- consumedByStockEntry(): chargen-bezogener Ausschuss zählt jetzt als
  Verbrauch — entsorgte Chargen verschwinden aus Rohstoff-Detail,
  Produktions-FEFO/Dropdown und AP-27-Batch-Check.
- Rohstoff-Detail: Kopfwert aus remainingByIngredient() (identisch zur
  Index-Seite, inkl. Ausschuss ohne Chargenbezug).
- Aggregationen iterieren über die Key-Vereinigung (received ∪ consumed
  ∪ disposed) — negative Bestände werden nicht mehr als 0 maskiert.
- Standort-Aggregation: Chargen-Ausschuss zählt am Standort der Charge
  (COALESCE), nicht am frei gewählten Formular-Standort.

Tests: neuer ChargeDisposalConsistencyTest (5). Suite: 219 grün, 795 Assertions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 12:42:46 +00:00
35b9076cbc Warenwirtschaft: AP-31 Löschen mit Soft-Delete + Abhängigkeitsprüfung
Anforderung 15.07.2026: Nahezu alle WaWi-Einträge sind jetzt löschbar
(Soft-Delete, deleted_at), mit Abhängigkeitsprüfung und Bestätigungs-
warnung vor jeder Löschung.

- Migration: deleted_at auf 14 WaWi-Tabellen (Stammdaten, ingredients,
  stock_entries, stock_disposals, productions); SoftDeletes-Trait in
  den Models (suppliers/packaging_items hatten es bereits).
- Neuer App\Services\DeletionGuard: zentrale Abhängigkeitsprüfung je
  Entität — referenzierte Einträge sind nicht löschbar, Fehlermeldung
  nennt die Verwendungen (behebt auch Audit M-4: kein 500er/stiller
  Cascade-Verlust mehr beim Löschen verwendeter Stammdaten).
- SettingCrudController::destroy() prüft Blocker; Supplier-,
  PackagingItem-, Ingredient-destroy ebenso (Ingredient: vollständige
  Prüfung inkl. Produktion/Ausschuss, Route GET→DELETE, Audit M-6).
- Wareneingänge: auch gebuchte Eingänge löschbar, sofern kein
  Produktions-Verbrauch/Ausschuss darauf gebucht ist.
- Ausschuss: löschbar (Menge steht dem Bestand wieder zur Verfügung).
- Produktionen: löschbar (admin >= 7); Produktbestand wird per
  Gegenbuchung zurückgeführt (reverseProductionStock, append-only,
  withTrashed), Rohstoffverbrauch zählt nicht mehr (Bestandsqueries
  schließen gelöschte Produktionen aus).
- lastNetPricePerSupplier: DB::query statt Model-Query (Global Scope
  auf Sub-Select-Alias).
- Debug-Log-Reste im PackagingItemController entfernt (Audit N-16).
- Views: Lösch-Buttons mit deutschen Bestätigungswarnungen (Ausschuss,
  Produktionen, gebuchte Wareneingänge, INCI als DELETE-Formular).

Tests: neuer InventoryDeletionTest (10 Tests), StorageSettingsTest an
neue Löschregel angepasst. Volle Suite: 214 grün, 783 Assertions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 12:31:11 +00:00
99a6c92e6c Warenwirtschaft: AP-28 Neue Produktions-Maske + Produktionsergebnis
- production_outputs (Migration inkl. idempotentem Backfill): eine Produktion
  kann mehrere Output-Produkte erzeugen (z. B. 40x50 ml + 50x5 ml)
- ProductStockService bucht je Output-Produkt (idempotenter Diff, append-only);
  die geplante Stückzahl bucht nichts mehr, entfernte Outputs werden rückgebucht
- ProductionService store/update mit outputs[] (leer = Fallback auf Planung
  inkl. suggestedBatchNumber — Backfill-Semantik, Alt-Aufrufer stabil)
- Maske: INCI-Liste (Alternativname/Qualität/Anteil/Gramm/Regal), Chargen-
  Erfassung nach Rezeptur-Phasen mit Notiz + Status-Ampel, Produktionsergebnis-
  Repeater mit Chargen-Nr.-Vorbelegung (Präfix + ttmmjj), Planungs-Hinweis
- Show: Produktionsergebnis-Karte; Index: Ergebnis-Spalte
- Hinweise-Doku + Plan V6.0 §6 fortgeschrieben (nächster Schritt: AP-13)

Tests: ProductionOutputTest (8 neu); Suite 201 grün, 731 Assertionen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:02:54 +00:00
7a5b5e0f7b Warenwirtschaft: AP-27 Wareneingang gleiche Charge zusammenführen
- Chargen-Existenz-Check beim Buchen (JSON-Endpoint batch-check): Hinweis
  „Charge bereits im Haus" + Vorbelegung MHD/Qualität aus dem letzten Eingang
- Rohstoffbestand-Detail: Chargen je batch_number summiert
  (InventoryService::chargeGroupsForIngredient), Einkäufe als Unterzeilen
- Produktion: Charge-Dropdown je Charge mit Summen-Rest (batches im
  Recipe-Payload), Verbrauch wird per expandBatchLines FEFO auf die
  Einzel-Einkäufe der Charge verteilt; Service-API bleibt je stock_entry
- Jeder Einkauf bleibt eigener stock_entry (Preis/Datum/Audit)
- Hinweise-Doku + Plan V6.0 §6 fortgeschrieben

Tests: StockEntryChargeMergeTest (7 neu); Suite 193 grün, 698 Assertions

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:36:19 +00:00
e47d848d3d Warenwirtschaft: OPT-3 Index-Limits + OPT-4 show()-Refactoring
- Wareneingang-/Produktions-Uebersicht: Eingegangene auf 500 gedeckelt
  (offene Bestellungen immer vollstaendig), ?all=1 + Hinweis-Link;
  ungenutzte User-Eager-Loads entfernt
- RawMaterialStockController::show() entschlackt: Chargen-Restmengen (FEFO)
  und offene Bestellungen im InventoryService, letzter Netto-Preis je
  Lieferant als Window-Function-Query im StockEntryRepository

Tests: RawMaterialStockTest +2, volle Suite 186 gruen, 663 Assertions

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:23:20 +00:00
ea36067831 Warenwirtschaft: AP-20 Rohstoffbestand-Filter + Kein-Rohstoffbestand-Flag
- ingredients.exclude_from_stock (Checkbox im INCI-Formular, z. B. Allergene):
  erscheint nie im Rohstoffbestand und nicht im Kritisch-Badge
- Rohstoffbestand-Uebersicht: Umschalter "Alle" / "Nur aus Herstellerrezepturen"
  (?scope=recipe, nutzt scopeUsedInActiveRecipes aus AP-21)
- Fix: AP-21-Migrationen hatten identischen Timestamp (add_storage lief vor
  create_storage und scheiterte auf MySQL am FK) - umbenannt auf 120753,
  Teilreste bereinigt, Migrationen sauber ausgefuehrt
- Hinweise-Doku fortgeschrieben

Tests: RawMaterialStockTest +2 (volle Suite 172 gruen, 624 Assertions)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 11:42:55 +00:00
e53201f229 Warenwirtschaft: Anforderungsrunde 12.06. — Plan V5.0 + AP-26/AP-25/AP-22
Neue Anforderungen (docs/) interpretiert und als Entwicklungsplan V5.0
(AP-20 bis AP-28) aufgenommen; erste drei Pakete umgesetzt:

AP-26 Ausschuss-Gründe konfigurierbar:
- Stammdaten-Tabelle disposal_reasons + CRUD unter Einstellungen → Allgemein
- StockDisposalController liest aktive DB-Gründe statt hartkodierter Liste
- Seeder übernimmt die bisherigen 6 Gründe idempotent

AP-25 Lieferbestand — Datum statt Tage:
- "Nicht vorrätig" wird über Datepicker "Wieder lieferbar ab" gepflegt;
  Resttage-Hinweis zählt täglich automatisch herunter
- Interne Bestellliste wieder kaufbar: Hinweis erscheint zusätzlich zu
  den Mengen-Buttons (VP entscheidet selbst)

AP-22 Produktbestand-Erweiterungen:
- Default-Sortierung nach Dringlichkeit, Status-Kopf toggelt
- Alle vier Status-Kacheln als Filter klickbar
- Neue Spalte "Verbrauch/Monat" (Ø Abgänge der letzten 6 Monate)
- Produkt-Flag "Im Produktbestand anzeigen" (products.show_in_product_stock)

Tests: 77 grün (DisposalReasonSettings 8, ProductOutOfStock 8,
ProductStock 13 + Regression). Hinweise-Doku + Plan-Protokoll fortgeschrieben;
nächster Schritt laut Plan: AP-21 (INCI-Erweiterungen).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 16:28:45 +00:00
3ee2d756e9 Warenwirtschaft: AP-09 bis AP-13 (Produktbestand, Set-Produkte, Ausschuss, Konzepte)
- AP-09 Produktbestand inkl. Bewegungshistorie (product_stock_movements, ProductStockService)
- AP-10 Rohstoffbestand-Ansicht je Lager (RawMaterialStockController)
- AP-11 Bestandsschwellen / Out-of-Stock-Handling fuer Produkte und Shop
- AP-12 Ausgang/Ausschuss (stock_disposals, StockDisposalController, InventoryService)
- Set-Produkte (product_set_items) inkl. Aufloesung
- Produktentwicklung & Hinweise-Verwaltung (Notices)
- AP-13 Entwicklungskonzept Shop-Bestandsabzug im Plan dokumentiert
- Feature-Tests fuer neue Module + aktualisierter Entwicklungsplan

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 11:04:22 +00:00
ca3eb663fe 13-05-2026 Waren Wirtschaft 2026-05-13 18:09:20 +02:00
9ce711d6b2 April 2026 waren Wirtschaft Feedback 2026-04-10 17:14:38 +02:00
Kevin Adametz
02f2a4c23e commit 08-2025 2025-08-12 15:51:04 +02:00
Kevin Adametz
9b54eb0512 Updates to 03-2025 2025-04-01 10:39:21 +02:00
Kevin Adametz
6167273a48 Cron Jobs, Reminder, Fonts, Members / Wizard / Price, Credit and Promotion 2023-01-25 12:42:41 +01:00
Kevin Adametz
a0f4eda6ea testemich Promotion 2022-04-14 13:21:17 +02:00
Kevin Adametz
38e7fd504a 01 2022 Microsite Promotion 2022-01-18 18:30:14 +01:00
Kevin Adametz
3f1fb9377d Zugriff Redakteur, Kundenhoheit API 2022-01-04 11:17:07 +01:00
Kevin Adametz
570d428b1c promotion 1.0 2021-12-25 02:51:22 +01:00
Kevin Adametz
1cc8e025a1 Promotion Frontend dynamic 2021-11-26 18:23:10 +01:00
Kevin Adametz
c9e1545693 #10 Promotion Modul, Kommentar 2 2021-11-09 18:40:18 +01:00
Kevin Adametz
f0da981737 Promotion Backend v1 2021-10-15 16:35:47 +02:00
Kevin Adametz
0ed47d3553 Mulit Submits disable, global Tag 2021-08-03 16:01:11 +02:00
Kevin Adametz
78f43169c8 Komp / Max Produkt, 2021-06-18 15:01:01 +02:00
Kevin Adametz
a4c76d06fa API aktiviert / Anpassungen + User Übersicht Gutschriften Umsätze 2021-05-18 19:02:18 +02:00
Kevin Adametz
c02fffd883 Gutschriften manuell hinzufügen, Yard 0& tax 2021-05-12 15:44:48 +02:00
Kevin Adametz
e670b92f5d Gutschriften Anpassungen 2021-04-29 16:36:11 +02:00
Kevin Adametz
3754f1c571 Guthaben aufladen, löschen, Ansichten 2021-04-26 16:07:03 +02:00
Kevin Adametz
6ac9fcc4d2 Gutschriften 2021-04-23 14:52:25 +02:00