]);
}
+ public function actionWeeklyBouquetProductsForecast()
+ {
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+
+ $request = Yii::$app->request;
+ $storeId = $request->get('storeId');
+ $month = $request->get('month');
+ $year = $request->get('year');
+ $week = $request->get('week');
+
+ if (!$month || !$year || $week === null) {
+ return ['success' => false, 'message' => 'Нет параметров'];
+ }
+
+ $service = new AutoPlannogrammaService();
+ $result = $service->getWeeklyBouquetProductsForecast($month, $year, $storeId);
+
+ if (!is_array($result)) {
+ return ['success' => false, 'message' => 'Ошибка структуры данных'];
+ }
+
+ $filtered = array_filter($result, function ($item) use ($week) {
+ return (int)$item['week'] === (int)$week;
+ });
+
+ return [
+ 'success' => true,
+ 'data' => array_values($filtered),
+ ];
+ }
}
return $pricesMap;
}
+ public function getWeeklyBouquetProductsForecast($month, $year, $storeId)
+ {
+ $matrixGroups = ArrayHelper::map(
+ MatrixBouquetForecast::find()->select(['group'])->distinct()->asArray()->all(),
+ 'group',
+ 'group'
+ );
+ $date = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT) . '-01';
+ $result = StorePlanService::getBouquetSpiecesMonthGoalFromForecast($month, $year, $storeId, $matrixGroups);
+ $weekShares = $this->getHistoricalSpeciesShareByWeek($date);
+ $flatData = $result['flatData'];
+ $weekIndex = [];
+ foreach ($weekShares as $shareRow) {
+ $key = implode('|', [
+ $shareRow['store_id'],
+ $shareRow['category'],
+ $shareRow['subcategory'],
+ $shareRow['species'],
+ ]);
+ $weekIndex[$key][] = $shareRow;
+ }
+
+ $weeklyForecasts = [];
+
+ foreach ($flatData as $item) {
+ $key = implode('|', [
+ $item['store_id'],
+ $item['category'],
+ $item['subcategory'],
+ $item['species'],
+ ]);
+
+ if (!isset($weekIndex[$key])) {
+ continue;
+ }
+
+ foreach ($weekIndex[$key] as $weekShare) {
+ $weeklyForecasts[] = [
+ 'store_id' => $item['store_id'],
+ 'category' => $item['category'],
+ 'subcategory' => $item['subcategory'],
+ 'species' => $item['species'],
+ 'type' => $item['type'],
+ 'product_guid' => $item['product_guid'],
+ 'week_forecast' => round($item['full_forecast'] * $weekShare['share'], 2),
+ 'full_forecast' => $item['full_forecast'],
+ 'week' => $weekShare['week'],
+ 'matrix_group' => $item['matrix_group'],
+ 'month' => $item['month'],
+ 'year' => $item['year'],
+ ];
+ }
+ }
+ return $weeklyForecasts;
+
+ }
+
}
\ No newline at end of file
$resultData = [];
$detailData = [];
$priceCache = [];
- $speciesCache = [];
+ $flatData = [];
foreach ($matrixGroups as $matrixGroup) {
$forecasts = MatrixBouquetForecast::find()
$price = $priceCache[$regionId][$guid] ?? 0;
$raw = $price * $product['count'] * $typeSalesValue;
$cost = round($raw * BouquetCompositionPrice::SURCHARGE_ASSEMBLY, 2);
-
+ $fullForecast = $product['count'] * $typeSalesValue;
$resultData[$sid][$category][$subcategory][$species][$typeSales] = ($resultData[$sid][$category][$subcategory][$species][$typeSales] ?? 0) + $cost;
$detailData[$sid][$species][$typeSales][] = [
'product_guid' => $guid,
'price' => $price,
'count' => $product['count'],
'forecast' => $typeSalesValue,
+ 'full_forecast' => $fullForecast,
'guid' => $forecast['guid'],
'raw_calculation' => $raw,
'rounded' => $cost,
+ 'matrix_group' => $matrixGroup,
+ ];
+ $flatData[] = [
+ 'store_id' => $sid,
+ 'category' => $category,
+ 'subcategory' => $subcategory,
+ 'species' => $species,
+ 'type' => $typeSales,
+ 'product_guid' => $guid,
+ 'full_forecast' => $fullForecast,
+ 'matrix_group' => $matrixGroup,
+ 'month' => $month,
+ 'year' => $year,
];
}
}
return [
'detail' => $resultData,
'final' => $finalResult,
- 'fullDetail' => $detailData
+ 'fullDetail' => $detailData,
+ 'flatData' => $flatData,
];
}