From: Vladimir Fomichev Date: Fri, 26 Sep 2025 06:34:12 +0000 (+0300) Subject: Контроль X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=87ab97cdfdd38391b3bea9619702a308adbf4424;p=erp24_rep%2Fyii-erp24%2F.git Контроль --- diff --git a/erp24/controllers/AutoPlannogrammaController.php b/erp24/controllers/AutoPlannogrammaController.php index 8b8bd5f9..80caaa42 100644 --- a/erp24/controllers/AutoPlannogrammaController.php +++ b/erp24/controllers/AutoPlannogrammaController.php @@ -1367,9 +1367,21 @@ class AutoPlannogrammaController extends BaseController $service = new AutoPlannogrammaService(); //$goals = $service->calculateFullGoalChain($filters); //$forecast = $service->calculateFullForecastForWeek($filters); + //$noHistoryProductData = $service->calculateSpeciesForecastForProductsWithoutHistory($filters['plan_date'], $filters); + + $historyProductData = $service->calculateSpeciesForecastForProductsWithHistory($filters['plan_date'], $filters, []); + var_dump($historyProductData); die(); + $salesProductForecastShare = $service->calculateProductForecastShare($noHistoryProductData, $historyProductData); + + $productForecastSpecies = $service->calculateProductSalesBySpecies($salesProductForecastShare, $cleanedSpeciesGoals); + + $monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters); + $monthCategoryGoal = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date']); + $monthSubcategoryShare = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters); + $monthSubcategoryGoal = $service->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal); $monthSpeciesShare = $service->getMonthSpeciesShareOrWriteOff($filters['plan_date'], $filters); $goals = $service->getMonthSpeciesGoalDirty($monthSpeciesShare, $monthSubcategoryGoal); @@ -1439,7 +1451,7 @@ class AutoPlannogrammaController extends BaseController $cleanedSpeciesGoals = $service->subtractSpeciesGoals($goals, [], []); $salesProductForecastShare = $service->calculateProductForecastShare($noHistoryProductData, $historyProductData); - + var_dump($salesProductForecastShare); die(); $productForecastSpecies = $service->calculateProductSalesBySpecies($salesProductForecastShare, $cleanedSpeciesGoals); $weeklySales = $service->getHistoricalSpeciesShareByWeek($filters['plan_date'], $filters); @@ -1978,7 +1990,7 @@ class AutoPlannogrammaController extends BaseController $salesProductForecastShare = $service->calculateProductForecastShare($noHistoryProductData, $productSalesForecast); - + var_dump($salesProductForecastShare);die(); $productForecastSpecies = $service->calculateProductSalesBySpecies($salesProductForecastShare, $cleanedSpeciesGoals); diff --git a/erp24/services/AutoPlannogrammaService.php b/erp24/services/AutoPlannogrammaService.php index ed872016..2767dc9f 100644 --- a/erp24/services/AutoPlannogrammaService.php +++ b/erp24/services/AutoPlannogrammaService.php @@ -373,7 +373,7 @@ class AutoPlannogrammaService 'subcategory' => 'main.subcategory', 'total_sum' => 'main.total_sum', 'percent' => new Expression('ROUND(CAST(main.total_sum AS DECIMAL) / NULLIF(totals.total, 0), 4)'), - 'type' => new Expression(':type', ['type' => $type]), + 'type' => new Expression(':type', [':type' => $type]), 'totals_total' => 'totals.total', ]) ->from([ @@ -429,41 +429,64 @@ class AutoPlannogrammaService foreach ($storeIds as $sid) { foreach ($periods as $dt) { - $items = $this->getProductsComponentsInCategory( - $sid, - (int)$dt->format('n'), - (int)$dt->format('Y'), - $type - ); - if (empty($items)) { + try { + $items = $this->getProductsComponentsInCategory( + $sid, + (int)$dt->format('n'), + (int)$dt->format('Y'), + $type + ); + } catch (\Throwable $e) { continue; } - $filtered = match ($mode) { - 'offline' => array_filter($items, fn($it) => in_array($it['order_id'], ['', '0'], true)), - 'online' => array_filter($items, fn($it) => !in_array($it['order_id'], ['', '0'], true)), - default => $items, // для writeOffs — всё + if (empty($items) || !is_array($items)) { + continue; + } + + $normalizeOrderId = static function($row): string { + if (!is_array($row)) return ''; + $oid = $row['order_id'] ?? ''; + if ($oid === null) return ''; + return (string)$oid; }; - $allComponentsProductIds[$sid] = array_merge( - $allComponentsProductIds[$sid] ?? [], - array_column($filtered, 'product_id') - ); + try { + $filtered = match ($mode) { + 'offline' => array_filter($items, fn($it) => in_array($normalizeOrderId($it), ['', '0'], true)), + 'online' => array_filter($items, fn($it) => !in_array($normalizeOrderId($it), ['', '0'], true)), + default => $items, + }; + } catch (\Throwable $e) { - $sums = $this->sumProductsComponentsByGroup($filtered, $type, 'subcategory'); + $filtered = $items; + } - $allComponentsProductIds[$sid] = array_values(array_unique($allComponentsProductIds[$sid])); + + $productIds = []; + foreach ($filtered as $row) { + if (is_array($row) && array_key_exists('product_id', $row)) { + $productIds[] = $row['product_id']; + } + } + $allComponentsProductIds[$sid] = array_values(array_unique(array_merge( + $allComponentsProductIds[$sid] ?? [], + $productIds + ))); + + $sums = $this->sumProductsComponentsByGroup($filtered, $type, 'subcategory') ?? []; foreach ($sums as $sr) { - $cat = $sr['category']; - $subcat = $sr['subcategory']; - $val = $sr['sum']; + if (!is_array($sr)) { continue; } + $cat = $sr['category'] ?? null; + $subcat = $sr['subcategory'] ?? null; + $val = (float)($sr['sum'] ?? 0); - $componentAdds[$sid][$cat][$subcat] = - ($componentAdds[$sid][$cat][$subcat] ?? 0) + $val; + if ($cat === null || $subcat === null) { continue; } + + $componentAdds[$sid][$cat][$subcat] = ($componentAdds[$sid][$cat][$subcat] ?? 0) + $val; + $componentAddsSumAll[$sid][$cat] = ($componentAddsSumAll[$sid][$cat] ?? 0) + $val; - $componentAddsSumAll[$sid][$cat] = - ($componentAddsSumAll[$sid][$cat] ?? 0) + $val; } } } @@ -1820,8 +1843,8 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ } $productSalesShare = StorePlanService::calculateProductSalesShareProductsWithHistory( - $filters['store_id'], - $filters['month'], + $storeId, + $month, $productsWithHistory ); @@ -1830,8 +1853,8 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ } $productSalesForecast = $this->calculateProductForecastInPiecesProductsWithHistory( - $filters['store_id'], - $filters['month'], + $storeId, + $month, $year, $goals, $productSalesShare @@ -1923,6 +1946,7 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ foreach ($productSalesShare as $productId => $data) { $share = $data['share'] ?? 0.0; + $avgWeightedSumm = $data['avgWeightedSum'] ?? 0.0; if ($share <= 0.0) { continue; @@ -1942,15 +1966,18 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ $goalsMap[$storeId], $goalsMap[$storeId][$cat], $goalsMap[$storeId][$cat][$sub], - $goalsMap[$storeId][$cat][$sub][$spec] + // $goalsMap[$storeId][$cat][$sub][$spec] ) ) { continue; } - - $goal = $goalsMap[$storeId][$cat][$sub][$spec]; - - $forecastSum = $goal * $share; + $isGoalExists = isset($goalsMap[$storeId][$cat][$sub][$spec]); + $goal = $goalsMap[$storeId][$cat][$sub][$spec] ?? 0; + if ($goal !== 0) { + $forecastSum = $goal * $share; + } else { + $forecastSum = $avgWeightedSumm; + } $forecastCount = $forecastSum / $price; @@ -1966,6 +1993,7 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ 'category' => $data['category'], 'subcategory' => $data['subcategory'], 'species' => $data['species'], + 'is_goal_exists' => $isGoalExists ]; } diff --git a/erp24/services/StorePlanService.php b/erp24/services/StorePlanService.php index 805fb6e4..af18f492 100755 --- a/erp24/services/StorePlanService.php +++ b/erp24/services/StorePlanService.php @@ -29,6 +29,8 @@ use yii_app\records\WriteOffsErp; class StorePlanService { + const PERIOD_COUNT = 3; + /** * @param int $month * @param int $year @@ -258,7 +260,7 @@ class StorePlanService $baseDate = strtotime("{$selectedYear}-{$selectedMonth}-01"); // Получаем периоды за 3 предыдущих месяца. - $periods = self::getPeriods($baseDate, 3, true); + $periods = self::getPeriods($baseDate, self::PERIOD_COUNT, true); // Получаем историю продаж для каждого периода. $salesHistory = self::getSalesHistory($storeId, $periods, $category, $subcategory, $species); @@ -492,7 +494,7 @@ class StorePlanService public static function calculateMedianSalesForProductsWithoutHistoryExtended($storeId, $selectedMonth, $selectedYear, $productsWithoutHistory) { $targetDate = strtotime("{$selectedYear}-{$selectedMonth}-01"); - $periods = self::getPeriods($targetDate, 3); + $periods = self::getPeriods($targetDate, self::PERIOD_COUNT); $medianSalesResults = []; @@ -782,7 +784,7 @@ class StorePlanService array $productsWithoutHistory ): array { $targetDate = strtotime("{$selectedYear}-{$selectedMonth}-01"); - $periods = self::getPeriods($targetDate, 3); + $periods = self::getPeriods($targetDate, self::PERIOD_COUNT); $results = []; foreach ($productsWithoutHistory as $prod) { @@ -985,7 +987,7 @@ class StorePlanService { $targetDate = strtotime(date('Y') . "-$selectedMonth-01"); - $weightedPeriods = self::getPeriods($targetDate, 3, false, true); + $weightedPeriods = self::getPeriods($targetDate, self::PERIOD_COUNT, false, true); $productsData = []; $globalTotal = 0; @@ -999,6 +1001,12 @@ class StorePlanService foreach ($productsData as $guid => &$data) { $data['share'] = ($globalTotal > 0) ? $data['weightedSum'] / $globalTotal : 0; + if (!empty($weightedPeriods)) { + $countPeriods = count($weightedPeriods); + } else { + $countPeriods = self::PERIOD_COUNT; + } + $data['avgWeightedSum'] = $data['weightedSum'] ? $data['weightedSum'] / $countPeriods : 0; } unset($data);