]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Оптимизация установки грейда
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 1 Dec 2025 06:39:49 +0000 (09:39 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Mon, 1 Dec 2025 06:39:49 +0000 (09:39 +0300)
erp24/actions/grade/AdminUpdateAction.php
erp24/records/AdminGroup.php
erp24/views/grade/admin-update.php

index c086b25be65990ef4534af43f314e366bb1e749d..ed7152430dbc91507cec0014b23eb1136c7fde7c 100644 (file)
@@ -20,9 +20,9 @@ class AdminUpdateAction extends Action
     /**
      * Обновляет данные администратора, включая назначение должности и группы
      * 
-     * Ð\94лÑ\8f Ñ\80абоÑ\87иÑ\85 Ð³Ñ\80Ñ\83пп (group_id = 50 Ð¸ Ð²Ñ\81е Ð³Ñ\80Ñ\83ппÑ\8b Ñ\81 parent_id = 50) Ð¿Ñ\80и Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¸
-     * employee_position_id заполняет group_name значением из AdminGroup->name.
-     * Для остальных групп использует текстовое поле custom_position.
+     * Ð\94лÑ\8f Ñ\81пеÑ\86иалÑ\8cнÑ\8bÑ\85 Ð³Ñ\80Ñ\83пп Ñ\80абоÑ\82ников (Ñ\84лоÑ\80иÑ\81Ñ\82Ñ\8b, Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\8b, Ð¿Ð¾Ð´Ñ\80абоÑ\82Ñ\87ики)
+     * устанавливает group_name из AdminGroup->name и сохраняет employee_position_id.
+     * Ð\94лÑ\8f Ð¾Ñ\81Ñ\82алÑ\8cнÑ\8bÑ\85 Ð³Ñ\80Ñ\83пп Ð¾Ñ\87иÑ\89аеÑ\82 employee_position_id Ð¸ Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82 Ñ\82екÑ\81Ñ\82овое Ð¿Ð¾Ð»Ðµ custom_position.
      * 
      * @param int $id ID администратора
      * @return string|\yii\web\Response Отрендеренный вид или редирект
@@ -32,6 +32,10 @@ class AdminUpdateAction extends Action
             return "Нет доступа";
         }
         $model = Admin::findOne($id);
+        
+        // Определяем специальные группы работников (используется в POST обработке и при рендеринге)
+        $workersGroup = AdminGroup::getWorkersGroups();
+        
         if (Yii::$app->user->can("updateAdminSettings", ['id' => $model->id])) {
             if (Yii::$app->request->isPost) {
                 $attributes = Yii::$app->request->post()['Admin'];
@@ -53,10 +57,15 @@ class AdminUpdateAction extends Action
                 $attributes['store_arr_guid'] = empty($attributes['storeGuidArray']) ? '' : implode(',', $attributes['storeGuidArray']);
                 unset($attributes['storeGuidArray']);
                 
-                // Ð¡Ð¾Ñ\85Ñ\80анÑ\8fем Ñ\84лаг, Ð¼Ð¾Ð¶Ð½Ð¾ Ð»Ð¸ Ð¸Ð·Ð¼ÐµÐ½Ñ\8fÑ\82Ñ\8c group_id Ð²Ñ\80Ñ\83Ñ\87нÑ\83Ñ\8e
+                // Ð\9fÑ\80овеÑ\80Ñ\8fем Ð¿Ñ\80ава Ð½Ð° Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ group_id
                 $originalGroupId = $attributes['group_id'] ?? $model->group_id;
                 $canChangeGroupId = Yii::$app->user->can("updateAdminSettingsGroupId", ['group_id' => $originalGroupId]);
                 
+                // Если нет прав на изменение group_id - используем текущий group_id из модели
+                if (!$canChangeGroupId) {
+                    $attributes['group_id'] = $model->group_id;
+                }
+                
                 if (!Yii::$app->user->can("updateAdminSettingsOnlyByHrAndAdministrator")) {
                     unset($attributes['store_dostup_all']);
                     unset($attributes['store_id']);
@@ -92,138 +101,30 @@ class AdminUpdateAction extends Action
                     Yii::$app->cache->set("dirtyAuthSettings", true);
                 }
 
-                // Определяем специальные группы с parent_id = 50
-                $specialGroups = [
-                    AdminGroup::GROUP_FLORIST_DAY,      // 30
-                    AdminGroup::GROUP_FLORIST_NIGHT,    // 35
-                    AdminGroup::GROUP_FLORIST_SUPPORT_DAY, // 40
-                    AdminGroup::GROUP_WORKERS,          // 45
-                    AdminGroup::GROUP_ADMINISTRATORS,   // 50
-                    AdminGroup::GROUP_FLORIST_SUPPORT_NIGHT, // 72
-                ];
-
-                // Ищем группу "Работники магазинов" по имени
-                $workersGroup = AdminGroup::find()->where(['name' => AdminGroup::GROUP_STORE_WORKERS_NAME])->one();
-                if ($workersGroup) {
-                    $specialGroups[] = $workersGroup->id;
-                }
-
-                // Определяем рабочие группы: group_id = 50 и все группы с parent_id = 50
-                $workGroups = [AdminGroup::GROUP_ADMINISTRATORS]; // 50
-                $childGroups = AdminGroup::find()->where(['parent_id' => AdminGroup::GROUP_ADMINISTRATORS])->all();
-                foreach ($childGroups as $childGroup) {
-                    $workGroups[] = $childGroup->id;
-                }
-
-                $isSpecialGroup = in_array((int)$attributes['group_id'], $specialGroups);
-                $isWorkGroup = in_array((int)$attributes['group_id'], $workGroups);
-
-                // Сохраняем старое значение employee_position_id для проверки изменения
-                $oldPositionId = $model->employee_position_id;
-                $oldGroupId = $model->group_id;
+                // Получаем группу один раз для всех последующих операций
+                $currentGroup = AdminGroup::findOne($attributes['group_id']);
+                $isSpecialGroup = in_array((int)$attributes['group_id'], $workersGroup);
                 
-                // Ð\9fÑ\80и Ñ\81мене Ð³Ñ\80Ñ\83ппÑ\8b Ð¿Ñ\80оÑ\81Ñ\82авлÑ\8fем group_name Ð¸Ð· AdminGroup->name Ð½Ð° Ð¾Ñ\81нове group_id
-                if (isset($attributes['group_id']) && $oldGroupId != (int)$attributes['group_id']) {
-                    $newAdminGroup = AdminGroup::findOne($attributes['group_id']);
-                    if ($newAdminGroup) {
-                        $attributes['group_name'] = $newAdminGroup->name;
-                    }
+                // Ð£Ñ\81Ñ\82анавливаем group_name Ð¸Ð· AdminGroup->name
+                if ($currentGroup) {
+                    $attributes['group_name'] = $currentGroup->name;
+                } else if (isset($attributes['custom_position'])) {
+                    // Если группа не найдена, используем текстовое поле как fallback
+                    $attributes['group_name'] = $attributes['custom_position'];
                 }
                 
+                // Обработка специфичных полей в зависимости от типа группы
                 if ($isSpecialGroup) {
-                    if ($isWorkGroup) {
-                        // Для рабочих групп (group_id = 50 и parent_id = 50) при заполнении employee_position_id
-                        // заполняем group_name значением из AdminGroup->name
-                        if (!empty($attributes['employee_position_id'])) {
-                            $adminGroup = AdminGroup::findOne($attributes['group_id']);
-                            if ($adminGroup) {
-                                $attributes['group_name'] = $adminGroup->name;
-                            }
-                        }
-                    } else {
-                        // Для остальных специальных групп синхронизируем группу с грейдом
-                        if (!empty($attributes['employee_position_id'])) {
-                            $employeePosition = EmployeePosition::findOne($attributes['employee_position_id']);
-                            if ($employeePosition) {
-                                $positionName = trim($employeePosition->name);
-                                $currentGroup = AdminGroup::findOne($attributes['group_id']);
-                                $currentGroupName = $currentGroup ? trim($currentGroup->name) : '';
-                                
-                                // Проверяем частичное совпадение группы и грейда
-                                $hasPartialMatch = false;
-                                if ($currentGroupName) {
-                                    // Нормализуем названия для сравнения (убираем "день", "ночь" и лишние пробелы)
-                                    $normalizedGroupName = mb_strtolower(preg_replace('/\s*(день|ночь)\s*/iu', '', $currentGroupName));
-                                    $normalizedPositionName = mb_strtolower($positionName);
-                                    
-                                    // Проверяем частичное совпадение
-                                    if (mb_strpos($normalizedGroupName, $normalizedPositionName) !== false || 
-                                        mb_strpos($normalizedPositionName, $normalizedGroupName) !== false) {
-                                        $hasPartialMatch = true;
-                                    }
-                                }
-                                
-                                // При назначении грейда проставляем group_name из AdminGroup->name на основе group_id
-                                if ($currentGroup) {
-                                    $attributes['group_name'] = $currentGroup->name;
-                                }
-                                
-                                if (!$hasPartialMatch) {
-                                    // Если не совпадают - ищем группу по названию грейда
-                                    $matchingGroup = self::findGroupByPositionName($positionName, $attributes['group_id']);
-                                    
-                                    if ($matchingGroup) {
-                                        // Найдена группа - меняем группу (только если есть права или группа не менялась вручную)
-                                        if ($canChangeGroupId || $originalGroupId == $oldGroupId) {
-                                            $attributes['group_id'] = $matchingGroup->id;
-                                            $attributes['group_name'] = $matchingGroup->name;
-                                            
-                                            if ($oldGroupId != $matchingGroup->id) {
-                                                Yii::$app->session->setFlash('info', 
-                                                    "Группа изменена с '{$currentGroupName}' на '{$matchingGroup->name}' в соответствии с грейдом '{$positionName}'"
-                                                );
-                                            }
-                                        } else {
-                                            // Нет прав на изменение группы - group_name уже установлен из текущей группы выше
-                                            Yii::$app->session->setFlash('warning', 
-                                                "Грейд '{$positionName}' не соответствует группе '{$currentGroupName}'. Недостаточно прав для автоматического изменения группы."
-                                            );
-                                        }
-                                    } else {
-                                        // Группа не найдена - group_name уже установлен из текущей группы выше
-                                        if ($oldGroupId != $attributes['group_id']) {
-                                            Yii::$app->session->setFlash('warning', 
-                                                "Группа для грейда '{$positionName}' не найдена. Текущая группа сохранена."
-                                            );
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-
-                    // Очищаем shift
+                    // Для специальных групп работников сохраняем employee_position_id
                     unset($attributes['shift']);
                 } else {
-                    // Для остальных групп group_name берем из AdminGroup->name на основе group_id
-                    $adminGroup = AdminGroup::findOne($attributes['group_id']);
-                    if ($adminGroup) {
-                        $attributes['group_name'] = $adminGroup->name;
-                    } else if (isset($attributes['custom_position'])) {
-                        // Если группа не найдена, используем текстовое поле как fallback
-                        $attributes['group_name'] = $attributes['custom_position'];
-                    }
-                    unset($attributes['custom_position']);
-                    // Очищаем employee_position_id и shift для не-специальных групп
+                    // Для остальных групп очищаем employee_position_id
                     $attributes['employee_position_id'] = null;
                     unset($attributes['shift']);
                 }
-
-                // Проверяем права на изменение group_id после всех автоматических изменений
-                if (!$canChangeGroupId) {
-                    // Если нет прав - убираем group_id из атрибутов, чтобы не изменить его
-                    unset($attributes['group_id']);
-                }
+                
+                // Очищаем custom_position в любом случае
+                unset($attributes['custom_position']);
 
                 $model->setAttributes($attributes, false);
 
@@ -304,113 +205,7 @@ class AdminUpdateAction extends Action
         $companies = ArrayHelper::map(Companies::find()->all(), 'id', 'name');
 
         return $this->controller->render('admin-update', compact('model', 'adminGroups', 'admins',
-            'cityStores', 'adminHistoryCategories', 'companies', 'positions'));
+            'cityStores', 'adminHistoryCategories', 'companies', 'positions', 'workersGroup'));
     }
 
-    /**
-     * Поиск группы администраторов по названию грейда (должности)
-     * 
-     * @param string $positionName Название грейда
-     * @param int|null $currentGroupId ID текущей группы (для приоритета)
-     * @return AdminGroup|null Найденная группа или null
-     */
-    private static function findGroupByPositionName($positionName, $currentGroupId = null) {
-        $normalizedPositionName = mb_strtolower(trim($positionName));
-        $exactMatches = []; // Точные совпадения (после нормализации)
-        $containsMatches = []; // Группы, содержащие полное название грейда
-        $partialMatches = []; // Частичные совпадения
-        
-        // Ищем все группы, соответствующие грейду
-        $groups = AdminGroup::find()->all();
-        
-        foreach ($groups as $group) {
-            $groupName = mb_strtolower(trim($group->name));
-            $normalizedGroupName = preg_replace('/\s*(день|ночь)\s*/iu', '', $groupName);
-            
-            // 1. Проверяем точное совпадение после нормализации
-            if ($normalizedGroupName === $normalizedPositionName) {
-                $exactMatches[] = $group;
-                continue;
-            }
-            
-            // 2. Проверяем, содержит ли группа полное название грейда (более специфичное совпадение)
-            if (mb_strpos($normalizedGroupName, $normalizedPositionName) === 0 || 
-                mb_strpos($normalizedGroupName, ' ' . $normalizedPositionName) !== false ||
-                mb_strpos($normalizedGroupName, $normalizedPositionName . ' ') !== false) {
-                $containsMatches[] = $group;
-                continue;
-            }
-            
-            // 3. Проверяем обратное - содержит ли грейд название группы (менее специфичное)
-            if (mb_strpos($normalizedPositionName, $normalizedGroupName) !== false) {
-                $partialMatches[] = $group;
-            }
-        }
-        
-        // Приоритет выбора:
-        // 1. Точные совпадения
-        if (!empty($exactMatches)) {
-            // Если текущая группа в точных совпадениях - оставляем её
-            if ($currentGroupId) {
-                foreach ($exactMatches as $group) {
-                    if ($group->id == $currentGroupId) {
-                        return $group;
-                    }
-                }
-            }
-            // Ищем базовую группу без "день"/"ночь" среди точных совпадений
-            foreach ($exactMatches as $group) {
-                $groupName = mb_strtolower(trim($group->name));
-                if (mb_stripos($groupName, 'день') === false && mb_stripos($groupName, 'ночь') === false) {
-                    return $group;
-                }
-            }
-            // Если все с "день"/"ночь" - возвращаем первую
-            return $exactMatches[0];
-        }
-        
-        // 2. Группы, содержащие полное название грейда (более специфичные)
-        if (!empty($containsMatches)) {
-            // Если текущая группа в списке - оставляем её
-            if ($currentGroupId) {
-                foreach ($containsMatches as $group) {
-                    if ($group->id == $currentGroupId) {
-                        return $group;
-                    }
-                }
-            }
-            // Ищем базовую группу без "день"/"ночь"
-            foreach ($containsMatches as $group) {
-                $groupName = mb_strtolower(trim($group->name));
-                if (mb_stripos($groupName, 'день') === false && mb_stripos($groupName, 'ночь') === false) {
-                    return $group;
-                }
-            }
-            // Если все с "день"/"ночь" - возвращаем первую
-            return $containsMatches[0];
-        }
-        
-        // 3. Частичные совпадения (менее приоритетные)
-        if (!empty($partialMatches)) {
-            // Если текущая группа в списке - оставляем её
-            if ($currentGroupId) {
-                foreach ($partialMatches as $group) {
-                    if ($group->id == $currentGroupId) {
-                        return $group;
-                    }
-                }
-            }
-            // Ищем базовую группу без "день"/"ночь"
-            foreach ($partialMatches as $group) {
-                $groupName = mb_strtolower(trim($group->name));
-                if (mb_stripos($groupName, 'день') === false && mb_stripos($groupName, 'ночь') === false) {
-                    return $group;
-                }
-            }
-            // Если все с "день"/"ночь" - возвращаем первую
-            return $partialMatches[0];
-        }
-        
-        return null;
-    }
 }
index f5f1a3cb984c788d248666f5a851201ca8893263..f713c5adf584a65d9b33381a0ea5f6390895683b 100755 (executable)
@@ -39,7 +39,22 @@ class AdminGroup extends ActiveRecord
     const GROUP_IT = 81;
     const GROUP_FINANCE_DIRECTOR = 9;
 
-    const GROUP_STORE_WORKERS_NAME = 'Работники магазинов';
+    /**
+     * Возвращает список специальных групп работников (нужно для JS и логики грейдов)
+     * @return int[]
+     */
+    public static function getWorkersGroups(): array
+    {
+        return [
+            self::GROUP_FLORIST_DAY,      // 30
+            self::GROUP_FLORIST_NIGHT,    // 35
+            self::GROUP_FLORIST_SUPPORT_DAY, // 40
+            self::GROUP_WORKERS,          // 45
+            self::GROUP_ADMINISTRATORS,   // 50
+            self::GROUP_FLORIST_SUPPORT_NIGHT, // 72
+            self::GROUP_FLORIST,          // 89
+        ];
+    }
 
     public static function getGroupsForEmployeeController() {
         return [
index 1d62b02a926f88e10b2be12d399f6df8dcbb74a4..eccb345a40d02ccb57cf5ce3daa3ed1714277f44 100644 (file)
@@ -21,17 +21,7 @@ use yii_app\services\FileService;
 /** @var array $adminHistoryCategories */
 /** @var array $companies */
 /** @var EmployeePosition[] $positions */
-
-// Определяем специальные группы с parent_id = 50 (нужно для JS)
-$specialGroups = [
-    AdminGroup::GROUP_FLORIST_DAY,      // 30
-    AdminGroup::GROUP_FLORIST_NIGHT,    // 35
-    AdminGroup::GROUP_FLORIST_SUPPORT_DAY, // 40
-    AdminGroup::GROUP_WORKERS,          // 45
-    AdminGroup::GROUP_ADMINISTRATORS,   // 50
-    AdminGroup::GROUP_FLORIST_SUPPORT_NIGHT, // 72
-    AdminGroup::GROUP_FLORIST,          // 89
-];
+/** @var array $workersGroup */
 
 // Подключаем CSS и JS файлы
 $this->registerCssFile('/css/grade/admin-update.css');
@@ -40,7 +30,7 @@ $this->registerJsFile('/js/grade/admin-update.js', ['position' => View::POS_END,
 // Передаем PHP переменные в JavaScript
 $this->registerJs("
     window.gradeAdminUpdateData = {
-        specialGroups: " . json_encode($specialGroups, JSON_NUMERIC_CHECK) . ",
+        specialGroups: " . json_encode($workersGroup, JSON_NUMERIC_CHECK) . ",
         adminGroups: " . json_encode($adminGroups ?? [], JSON_UNESCAPED_UNICODE) . ",
         positionsData: " . json_encode(ArrayHelper::map($positions ?? [], 'id', 'name'), JSON_UNESCAPED_UNICODE) . ",
         groupsData: " . json_encode($adminGroups ?? [], JSON_UNESCAPED_UNICODE) . "
@@ -78,7 +68,7 @@ $this->registerJs("
     ?>
 
     <?php
-    $isSpecialGroup = in_array((int)$model->group_id, $specialGroups);
+    $isSpecialGroup = in_array((int)$model->group_id, $workersGroup);
     ?>
 
     <div id="positionFieldSpecial" style="display: <?= $isSpecialGroup ? 'block' : 'none' ?>;">