/**
* Обновляет данные администратора, включая назначение должности и группы
*
- * Ð\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 Отрендеренный вид или редирект
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'];
$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']);
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);
$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;
- }
}