From 91ac3a6828e3fa4cc62a500132c1ab599df7dddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Gla=CC=88ser?= Date: Tue, 8 Sep 2026 19:34:21 +0200 Subject: [PATCH] Start forecast demand at first sale --- .../processes/main/erp.lager.stock_lot_forecast_refresh.md | 2 +- modules/erp/lager/forecast.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/modules/erp/lager/processes/main/erp.lager.stock_lot_forecast_refresh.md b/docs/modules/erp/lager/processes/main/erp.lager.stock_lot_forecast_refresh.md index 8d3f14b..1c1b996 100644 --- a/docs/modules/erp/lager/processes/main/erp.lager.stock_lot_forecast_refresh.md +++ b/docs/modules/erp/lager/processes/main/erp.lager.stock_lot_forecast_refresh.md @@ -22,7 +22,7 @@ Direkt ausgeführter Lager-Prozess mit zwei Triggern: synchron nach jeder erfolg 3. Verkaufsallokationen der letzten 365 Tage aus `sales_order_line_lot_allocation`, `sales_order_line` und `sales_order` laden. 4. `allocated`- und `reserved`-Mengen nach Bestell- beziehungsweise OTC-Verkaufsdatum je Produkt und Kalendertag aggregieren. 5. Stornierte Auftrags- und Positionsmengen aus der Nachfrage herausrechnen. -6. Den gewichteten Tagesabsatz mit einer Halbwertszeit von 60 Tagen berechnen. +6. Den gewichteten Tagesabsatz ab dem ersten gültigen Verkaufstag innerhalb des geladenen Zeitraums mit einer Halbwertszeit von 60 Tagen berechnen; Tage vor dem ersten Verkauf werden nicht als Nullabsatz berücksichtigt. 7. Das Leer-Datum der aktuellen Charge aus ihrem physischen Bestand und der gewichteten Nachfrage berechnen. Das Leer-Datum der nächsten Charge wird mit derselben Nachfrage ab dem Leer-Datum der aktuellen Charge weitergerechnet; bei bereits leerer aktueller Charge beginnt es am aktuellen Datum. 8. Jede erfolgreiche Berechnung je Charge in `stock_lot_forecast_history` speichern und den jeweiligen Snapshot in `stock_lot` aktualisieren. 9. Im Cron Fehler einzelner Produkte sammeln und mit den übrigen Produkten fortfahren. diff --git a/modules/erp/lager/forecast.php b/modules/erp/lager/forecast.php index 36a5231..7e35d37 100644 --- a/modules/erp/lager/forecast.php +++ b/modules/erp/lager/forecast.php @@ -131,13 +131,15 @@ function lager_forecast_calculate( ?DateTimeImmutable $forecastStartDate = null ): array { - $lookbackDays = 365; + $firstSaleDate = empty($dailySales) ? null : min(array_keys($dailySales)); + $lookbackDays = $firstSaleDate === null + ? 0 + : $asOfDate->diff(new DateTimeImmutable($firstSaleDate))->days + 1; $halfLifeDays = 60; $weightedUnits = 0.0; $weightTotal = 0.0; $salesUnits = 0.0; $salesDays = 0; - $firstSaleDate = null; $lastSaleDate = null; for ($age = 0; $age < $lookbackDays; $age++) { @@ -150,7 +152,6 @@ function lager_forecast_calculate( if ($units > 0) { $salesUnits += $units; $salesDays++; - $firstSaleDate = $dateKey; $lastSaleDate ??= $dateKey; } }