*/
public function actionIndex()
{
- // Создание поисковой модели
+
$searchModel = new ClusterSearch();
$dataProvider = $searchModel->search($this->request->queryParams);
- // Получение всех кустовых директоров
+
$clusterManagers = Admin::find()
->select(['name', 'id', 'store_arr'])
->where(['group_id' => 7, 'group_name' => 'Кустовой директор'])
->indexBy('id')
->all();
- // Получение параметра 'date' из GET-запроса или текущей даты
+
$currentDate = Yii::$app->request->get('ClusterSearch')['date'] ?? date('Y-m-d');
- // Минимально допустимая дата
- $minDate = '2024-09-12';
- // Проверка: если текущая дата меньше минимальной, устанавливаем минимальную дату
- if (strtotime($currentDate) < strtotime($minDate)) {
- $currentDate = $minDate;
- }
- $storeData = ClusterCalendar::find()
+
+ $storeData = StoreDynamic::find()
->select([
- 'cluster_id',
- 'string_agg(DISTINCT value_int::text, \',\') AS stores',
- 'COUNT(DISTINCT value_int) AS store_count',
+ 'value_int AS cluster_id',
+ 'string_agg(store_id::text, \',\') AS stores',
+ 'COUNT(store_id) AS store_count',
'MAX(date_from) AS last_update'
])
- ->where(['>=', 'date_from', $minDate])
+ ->where(['active' => 1])
->andWhere(['<=', 'date_from', $currentDate])
- ->andWhere(['>', 'date_to', $currentDate])
- ->groupBy('cluster_id')
+ ->groupBy('value_int')
->asArray()
->all();
- // Если и их нет, создаем новые записи на основе StoreDynamic
+
if (empty($storeData)) {
- // Данные по динамике магазинов, связанных с кустами
- $storeDynamic = StoreDynamic::find()
+ $storeData = StoreDynamic::find()
->select([
'value_int AS cluster_id',
- 'string_agg(store_id::text, \',\') AS stores', // Используем string_agg для PostgreSQL
+ 'string_agg(store_id::text, \',\') AS stores',
'COUNT(store_id) AS store_count',
- 'MAX(date_from) AS last_update'
+ 'MIN(date_from) AS first_update'
])
- ->where(['active' => 1])
- ->groupBy('value_int') // Группируем по идентификатору куста
- ->asArray()
- ->all();
-
- // Преобразуем данные о магазинах в удобный формат
- $storeLists = ArrayHelper::map($storeDynamic, 'cluster_id', 'stores'); // Список магазинов для каждого куста
- $storeCounts = ArrayHelper::map($storeData, 'cluster_id', 'store_count');
- $lastUpdates = ArrayHelper::map($storeData, 'cluster_id', 'last_update');
- //var_dump($storeDynamic);
- foreach ($storeDynamic as $cluster) {
- $clusterId = $cluster['cluster_id'];
- $stores = explode(',', $cluster['stores']);
- $lastUpdate = $cluster['last_update'];
-
- foreach ($stores as $storeId) {
- $newCalendar = new ClusterCalendar();
- $newCalendar->cluster_id = $clusterId;
- $newCalendar->value_type = 'int';
- $newCalendar->value_int = (int) $storeId;
- $newCalendar->year = '2024';
- $newCalendar->category_id = 1;
- $newCalendar->date_from = $minDate;
- $newCalendar->date_to = '2100-01-01';
- $newCalendar->created_admin_id = Yii::$app->user->id;
- $newCalendar->save(false);
- }
- }
-
- // Обновляем список магазинов после добавления записей
- $storeData = ClusterCalendar::find()
- ->select([
- 'cluster_id',
- 'string_agg(DISTINCT value_int::text, \',\') AS stores',
- 'COUNT(DISTINCT value_int) AS store_count',
- 'MAX(date_from) AS last_update'
- ])
- ->where(['>=', 'date_from', $minDate])
- ->andWhere(['<=', 'date_from', $currentDate])
- ->andWhere(['>', 'date_to', $currentDate])
- ->groupBy('cluster_id')
+ ->groupBy('value_int')
->asArray()
->all();
}
- //var_dump($storeData);
- // Преобразуем данные о магазинах в удобный формат
- $storeLists = ArrayHelper::map($storeData, 'cluster_id', 'stores'); // Список магазинов для каждого куста
+
+
+ $storeLists = ArrayHelper::map($storeData, 'cluster_id', 'stores'); // List of stores for each cluster
$storeCounts = ArrayHelper::map($storeData, 'cluster_id', 'store_count');
- // Инициализируем массив соответствий кустов и менеджеров
+ $lastUpdates = ArrayHelper::map($storeData, 'cluster_id', 'last_update');
+
+
$clusterToManager = [];
$matchedManagers = [];
- // Сопоставляем менеджеров и кусты по спискам магазинов
+
foreach ($storeData as $store) {
$clusterId = $store['cluster_id'];
- $storeIds = explode(',', $store['stores']); // Магазины, прикрепленные к кусту
+ $storeIds = explode(',', $store['stores']); // Stores attached to cluster
$assignedManager = null;
foreach ($clusterManagers as $manager) {
if (!empty($manager->store_arr)) {
- $managerStores = explode(',', $manager->store_arr); // Магазины, прикрепленные к менеджеру
- $intersection = array_intersect($storeIds, $managerStores); // Находим пересечение
+ $managerStores = explode(',', $manager->store_arr); // Stores attached to manager
+ $intersection = array_intersect($storeIds, $managerStores); // Find intersection
+
- // Если большинство магазинов совпадают, то менеджер сопоставляется с кустом
if (count($intersection) >= count($storeIds) / 2) {
$assignedManager = $manager->name;
- $matchedManagers[] = $manager->id; // Добавляем менеджера в список использованных
- break; // Останавливаем поиск для этого куста
+ $matchedManagers[] = $manager->id; // Add manager to list of used
+ break; // Stop searching for this cluster
}
}
}
- // Если менеджер не найден по магазину, оставляем его "не назначенным"
+
$clusterToManager[$clusterId] = $assignedManager ?? 'Не назначен';
}
- // Проверка на оставшегося менеджера и куст
- $unassignedClusters = array_filter($clusterToManager, fn($manager) => $manager === 'Не назначен'); // Кусты без менеджера
- $unassignedManagers = array_filter($clusterManagers, fn($manager) => !in_array($manager->id, $matchedManagers)); // Менеджеры без кластера
- // Если остался один менеджер и один куст, их нужно сопоставить
- if (count($unassignedClusters) === 1 && count($unassignedManagers) === 1) {
- $unassignedClusterId = array_key_first($unassignedClusters); // ID куста без менеджера
- $unassignedManager = reset($unassignedManagers); // Менеджер без куста
- $clusterToManager[$unassignedClusterId] = $unassignedManager->name; // Назначаем последнего менеджера на куст
+ $unassignedClusters = array_filter($clusterToManager, function ($manager) {
+ return $manager === 'Не назначен';
+ });
+ $unassignedManagers = array_filter($clusterManagers, function ($manager) use ($matchedManagers) {
+ return !in_array($manager->id, $matchedManagers);
+ });
+
+ if (count($unassignedClusters) === 1 && count($unassignedManagers) === 1) {
+ $unassignedClusterId = array_key_first($unassignedClusters);
+ $unassignedManager = reset($unassignedManagers);
+ $clusterToManager[$unassignedClusterId] = $unassignedManager->name;
}
- // Делаем выборку по кластерам с учетом даты
+
foreach ($storeData as $store) {
$clusterId = $store['cluster_id'];
- $calendar = ClusterCalendar::find()
- ->where(['cluster_id' => $clusterId])
+ $calendar = StoreDynamic::find()
+ ->where(['value_int' => $clusterId])
->andWhere(['<=', 'date_from', $currentDate])
- ->andWhere(['>', 'date_to', $currentDate])
- ->andWhere(['>=', 'date_from', '2024-09-12']) // Ограничение на минимальную дату
->orderBy(['date_from' => SORT_DESC])
->one();
'lastUpdates' => $lastUpdates,
'storeLists' => $storeLists,
'clusterToManager' => $clusterToManager,
- 'currentDate' => Yii::$app->request->get('ClusterSearch')['date'] ?? $currentDate,
+ 'currentDate' => $currentDate,
]);
}