From 579c7b53cd2614cde5c8fe832a58762ce19b3e27 Mon Sep 17 00:00:00 2001 From: Vladimir Fomichev Date: Sat, 1 Nov 2025 14:28:32 +0300 Subject: [PATCH] =?utf8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D1=80?= =?utf8?q?=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/actions/grade/AdminUpdateAction.php | 11 +- erp24/api3/core/services/ReportService.php | 229 ++++++++++----------- erp24/records/AdminGroup.php | 2 + erp24/views/grade/admin-update.php | 9 +- 4 files changed, 125 insertions(+), 126 deletions(-) diff --git a/erp24/actions/grade/AdminUpdateAction.php b/erp24/actions/grade/AdminUpdateAction.php index cc4c8a1a..6d1ce704 100644 --- a/erp24/actions/grade/AdminUpdateAction.php +++ b/erp24/actions/grade/AdminUpdateAction.php @@ -17,6 +17,15 @@ use yii_app\services\HistoryService; class AdminUpdateAction extends Action { + /** + * Обновляет данные администратора, включая назначение должности и группы + * + * Для специальных групп формирует group_name из EmployeePosition и смены. + * Для остальных групп использует текстовое поле custom_position. + * + * @param int $id ID администратора + * @return string|\yii\web\Response Отрендеренный вид или редирект + */ public function run($id) { if (!Yii::$app->user->can("seeAdminSettings", ['id' => $id])) { return "Нет доступа"; @@ -91,7 +100,7 @@ class AdminUpdateAction extends Action ]; // Ищем группу "Работники магазинов" по имени - $workersGroup = AdminGroup::find()->where(['name' => 'Работники магазинов'])->one(); + $workersGroup = AdminGroup::find()->where(['name' => AdminGroup::GROUP_STORE_WORKERS_NAME])->one(); if ($workersGroup) { $specialGroups[] = $workersGroup->id; } diff --git a/erp24/api3/core/services/ReportService.php b/erp24/api3/core/services/ReportService.php index cd1a6a13..647dd5ff 100644 --- a/erp24/api3/core/services/ReportService.php +++ b/erp24/api3/core/services/ReportService.php @@ -23,6 +23,96 @@ use yii_app\records\WriteOffsErp; class ReportService { /** + * Создает карту должностей для массива admin_id + * + * Строит соответствие между ID администратора и названием их должности. + * Использует EmployeePosition::name если назначена, иначе имя AdminGroup. + * + * @param array $adminIds Массив ID администраторов + * @return array Карта вида [admin_id => position_name] + */ + private function buildPositionMap(array $adminIds): array + { + if (empty($adminIds)) { + return []; + } + + $employeePositions = EmployeePosition::find() + ->select(['id', 'name']) + ->indexBy('id') + ->asArray() + ->all(); + + $adminPositions = Admin::find() + ->select(['id', 'employee_position_id', 'group_id']) + ->where(['id' => $adminIds]) + ->indexBy('id') + ->asArray() + ->all(); + + $groupIds = array_filter(array_column($adminPositions, 'group_id')); + $adminGroups = AdminGroup::find() + ->select(['id', 'name']) + ->where(['id' => $groupIds]) + ->indexBy('id') + ->asArray() + ->all(); + + $positionMap = []; + foreach ($adminPositions as $adminId => $admin) { + $positionName = ''; + + if (!empty($admin['employee_position_id']) && isset($employeePositions[$admin['employee_position_id']])) { + $positionName = $employeePositions[$admin['employee_position_id']]['name']; + } elseif (!empty($admin['group_id']) && isset($adminGroups[$admin['group_id']])) { + $positionName = $adminGroups[$admin['group_id']]['name']; + } + + $positionMap[$adminId] = $positionName; + } + + return $positionMap; + } + + /** + * Подсчитывает количество сотрудников по должностям + * + * Группирует список сотрудников по должностям и подсчитывает количество + * для каждой должности. + * + * @param array $employees Массив сотрудников с полем admin_id + * @param array $positionMap Карта должностей [admin_id => position_name] + * @return array Массив [position_name => count] + */ + private function countEmployeesByPosition(array $employees, array $positionMap): array + { + $employeePositionsOnShift = []; + foreach ($employees as $employee) { + $adminId = $employee['admin_id']; + $positionName = $positionMap[$adminId] ?? ''; + + if (!empty($positionName)) { + if (!isset($employeePositionsOnShift[$positionName])) { + $employeePositionsOnShift[$positionName] = 0; + } + $employeePositionsOnShift[$positionName]++; + } + } + return $employeePositionsOnShift; + } + + /** + * Генерирует отчет по продажам и сотрудникам за период + * + * Создает дневной отчет с подробными данными о количестве продаж, + * посетителей, сотрудников и их должностей на каждый день в период. + * + * @param object $data Объект с параметрами: + * - date_start: дата начала периода (Y-m-d) + * - date_end: дата окончания периода (Y-m-d) + * - stores: массив ID магазинов + * - shift_type: тип смены (0=все, 1=день, 2=ночь) + * @return array Массив отчетов по дням * @throws \yii\base\Exception * @throws Exception */ @@ -55,33 +145,8 @@ class ReportService $adminIdsInPeriod = ArrayHelper::getColumn($allAdminsInPeriod, 'admin_id'); - $employeePositions = EmployeePosition::find()->select(['id', 'name'])->indexBy('id')->asArray()->all(); - - $adminPositions = Admin::find()->select(['id', 'employee_position_id', 'group_id']) - ->where(['id' => $adminIdsInPeriod]) - ->indexBy('id') - ->asArray()->all(); - - // Получаем данные групп администраторов - $groupIds = array_filter(array_column($adminPositions, 'group_id')); - $adminGroups = AdminGroup::find()->select(['id', 'name']) - ->where(['id' => $groupIds]) - ->indexBy('id') - ->asArray()->all(); - - // Создаем карту должностей для каждого admin_id - $positionMap = []; - foreach ($adminPositions as $adminId => $admin) { - $positionName = ''; - - if (!empty($admin['employee_position_id']) && isset($employeePositions[$admin['employee_position_id']])) { - $positionName = $employeePositions[$admin['employee_position_id']]['name']; - } elseif (!empty($admin['group_id']) && isset($adminGroups[$admin['group_id']])) { - $positionName = $adminGroups[$admin['group_id']]['name']; - } + $positionMap = $this->buildPositionMap($adminIdsInPeriod); - $positionMap[$adminId] = $positionName; - } while ($currentDate <= $data->date_end) { $report = []; @@ -107,23 +172,14 @@ class ReportService $adminIds = ArrayHelper::getColumn($timetables, 'admin_id'); // Подсчет должностей на смене для этого дня - $employeePositionsOnShift = []; - foreach ($timetables as $timetable) { - $adminId = $timetable['admin_id']; - $positionName = $positionMap[$adminId] ?? ''; - - if (!empty($positionName)) { - if (!isset($employeePositionsOnShift[$positionName])) { - $employeePositionsOnShift[$positionName] = 0; - } - $employeePositionsOnShift[$positionName]++; - - // Суммируем для общего отчета - if (!isset($totalEmployeePositionsOnShift[$positionName])) { - $totalEmployeePositionsOnShift[$positionName] = 0; - } - $totalEmployeePositionsOnShift[$positionName]++; + $employeePositionsOnShift = $this->countEmployeesByPosition($timetables, $positionMap); + + // Суммируем для общего отчета + foreach ($employeePositionsOnShift as $positionName => $count) { + if (!isset($totalEmployeePositionsOnShift[$positionName])) { + $totalEmployeePositionsOnShift[$positionName] = 0; } + $totalEmployeePositionsOnShift[$positionName] += $count; } $adminPayrollDaysMonth = AdminPayrollDays::find()->select(["FLOOR(SUM(day_payroll)) as total", "store_id"]) @@ -547,33 +603,7 @@ class ReportService // Получаем все уникальные admin_id сотрудников за период $adminIdsInPeriod = ArrayHelper::getColumn($employeesTotal, 'admin_id'); - $employeePositions = EmployeePosition::find()->select(['id', 'name'])->indexBy('id')->asArray()->all(); - - $adminPositions = Admin::find()->select(['id', 'employee_position_id', 'group_id']) - ->where(['id' => $adminIdsInPeriod]) - ->indexBy('id') - ->asArray()->all(); - - // Получаем данные групп администраторов - $groupIds = array_filter(array_column($adminPositions, 'group_id')); - $adminGroups = AdminGroup::find()->select(['id', 'name']) - ->where(['id' => $groupIds]) - ->indexBy('id') - ->asArray()->all(); - - // Создаем карту должностей для каждого admin_id - $positionMap = []; - foreach ($adminPositions as $adminId => $admin) { - $positionName = ''; - - if (!empty($admin['employee_position_id']) && isset($employeePositions[$admin['employee_position_id']])) { - $positionName = $employeePositions[$admin['employee_position_id']]['name']; - } elseif (!empty($admin['group_id']) && isset($adminGroups[$admin['group_id']])) { - $positionName = $adminGroups[$admin['group_id']]['name']; - } - - $positionMap[$adminId] = $positionName; - } + $positionMap = $this->buildPositionMap($adminIdsInPeriod); foreach ($data->date as $ind => $dateStartEnd) { $currentDate = $dateStartEnd[0]; @@ -830,11 +860,13 @@ class ReportService $totalSpecificPerDay = []; foreach (['matrix', 'wrap', 'services', 'potted'] as $spec) { - $totalSpecificPerDay[$store_id][$spec] = 0; - foreach ($specificSales[$spec][$store_id] ?? [] as $specificSale) { - $totalSpecificPerDay[$store_id][$spec] += (float)($specificSale ?? 0); + $totalSpecificPerDay[$store_id][$spec] = 0.0; + if (isset($specificSales[$spec][$store_id])) { + $totalSpecificPerDay[$store_id][$spec] += (float)$specificSales[$spec][$store_id]['total']; } + //Yii::warning($totalSpecificPerDay[$store_id][$spec], 'specificSales'); } + $totalMatrixPerDay[$store_id] = $totalSpecificPerDay[$store_id]['matrix']; $totalWrapPerDay[$store_id] = $totalSpecificPerDay[$store_id]['wrap']; $totalServicePerDay[$store_id] = $totalSpecificPerDay[$store_id]['services']; @@ -850,18 +882,7 @@ class ReportService } // Подсчет должностей сотрудников за неделю - $employeePositionsOnShift = []; - foreach ($weekEmployees as $employee) { - $adminId = $employee['admin_id']; - $positionName = $positionMap[$adminId] ?? ''; - - if (!empty($positionName)) { - if (!isset($employeePositionsOnShift[$positionName])) { - $employeePositionsOnShift[$positionName] = 0; - } - $employeePositionsOnShift[$positionName]++; - } - } + $employeePositionsOnShift = $this->countEmployeesByPosition($weekEmployees, $positionMap); $stores = []; @@ -1024,33 +1045,8 @@ class ReportService // Получаем все уникальные admin_id сотрудников за период $adminIdsInPeriod = ArrayHelper::getColumn($employeesTotal, 'admin_id'); - $employeePositions = EmployeePosition::find()->select(['id', 'name'])->indexBy('id')->asArray()->all(); - - $adminPositions = Admin::find()->select(['id', 'employee_position_id', 'group_id']) - ->where(['id' => $adminIdsInPeriod]) - ->indexBy('id') - ->asArray()->all(); - - // Получаем данные групп администраторов - $groupIds = array_filter(array_column($adminPositions, 'group_id')); - $adminGroups = AdminGroup::find()->select(['id', 'name']) - ->where(['id' => $groupIds]) - ->indexBy('id') - ->asArray()->all(); - - // Создаем карту должностей для каждого admin_id - $positionMap = []; - foreach ($adminPositions as $adminId => $admin) { - $positionName = ''; - - if (!empty($admin['employee_position_id']) && isset($employeePositions[$admin['employee_position_id']])) { - $positionName = $employeePositions[$admin['employee_position_id']]['name']; - } elseif (!empty($admin['group_id']) && isset($adminGroups[$admin['group_id']])) { - $positionName = $adminGroups[$admin['group_id']]['name']; - } + $positionMap = $this->buildPositionMap($adminIdsInPeriod); - $positionMap[$adminId] = $positionName; - } foreach ($days as $ind => $day) { $employeeCount = []; @@ -1424,18 +1420,7 @@ class ReportService } // Подсчет должностей сотрудников за день по всем магазинам - $employeePositionsOnShift = []; - foreach ($allDayEmployees as $employee) { - $adminId = $employee['admin_id']; - $positionName = $positionMap[$adminId] ?? ''; - - if (!empty($positionName)) { - if (!isset($employeePositionsOnShift[$positionName])) { - $employeePositionsOnShift[$positionName] = 0; - } - $employeePositionsOnShift[$positionName]++; - } - } + $employeePositionsOnShift = $this->countEmployeesByPosition($allDayEmployees, $positionMap); $total = []; diff --git a/erp24/records/AdminGroup.php b/erp24/records/AdminGroup.php index 5a53070a..f5f1a3cb 100755 --- a/erp24/records/AdminGroup.php +++ b/erp24/records/AdminGroup.php @@ -39,6 +39,8 @@ class AdminGroup extends ActiveRecord const GROUP_IT = 81; const GROUP_FINANCE_DIRECTOR = 9; + const GROUP_STORE_WORKERS_NAME = 'Работники магазинов'; + public static function getGroupsForEmployeeController() { return [ self::GROUP_HR, diff --git a/erp24/views/grade/admin-update.php b/erp24/views/grade/admin-update.php index 1da82266..2a823474 100644 --- a/erp24/views/grade/admin-update.php +++ b/erp24/views/grade/admin-update.php @@ -61,12 +61,15 @@ use yii_app\services\FileService; ]; // Ищем группу "Работники магазинов" по имени - $workersGroup = AdminGroup::find()->where(['name' => 'Работники магазинов'])->one(); + $workersGroup = AdminGroup::find()->where(['name' => AdminGroup::GROUP_STORE_WORKERS_NAME])->one(); if ($workersGroup) { $specialGroups[] = $workersGroup->id; } $isSpecialGroup = in_array((int)$model->group_id, $specialGroups); + + // Преобразуем в JSON для использования в JavaScript + $specialGroupsJson = json_encode($specialGroups, JSON_NUMERIC_CHECK); ?>
@@ -276,7 +279,7 @@ use yii_app\services\FileService; } function changePositionFieldVisibility(groupId) { - var specialGroups = [30, 35, 40, 45, 50, 72]; // Известные ID специальных групп + var specialGroups = ; // Получаем специальные группы из PHP var isSpecialGroup = specialGroups.includes(parseInt(groupId)); @@ -297,7 +300,7 @@ use yii_app\services\FileService; changePositionFieldVisibility(initialGroupId); // Для не-специальных групп очищаем employee_position_id при загрузке - var specialGroups = [30, 35, 40, 45, 50, 72]; + var specialGroups = ; var isSpecialGroup = specialGroups.includes(parseInt(initialGroupId)); if (!isSpecialGroup) { $('select[name="Admin[employee_position_id]"]').val(''); -- 2.39.5