From 5bbaab47217a9abad814222a4d6e06e4b0e7c67f Mon Sep 17 00:00:00 2001 From: Vladimir Fomichev Date: Thu, 30 Oct 2025 10:30:35 +0300 Subject: [PATCH] =?utf8?q?=D0=9E=D1=82=D1=87=D0=B5=D1=82=D1=8B=20=D0=B7?= =?utf8?q?=D0=B0=20=D0=B4=D0=B5=D0=BD=D1=8C=20=D0=B8=20=D0=BD=D0=B5=D0=B4?= =?utf8?q?=D0=B5=D0=BB=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/api3/core/services/ReportService.php | 184 +++++++++++++++++++-- 1 file changed, 167 insertions(+), 17 deletions(-) diff --git a/erp24/api3/core/services/ReportService.php b/erp24/api3/core/services/ReportService.php index 97f98620..cd1a6a13 100644 --- a/erp24/api3/core/services/ReportService.php +++ b/erp24/api3/core/services/ReportService.php @@ -8,6 +8,7 @@ use yii\db\Expression; use yii\helpers\ArrayHelper; use yii_app\api3\modules\v1\models\timetable\Timetable; use yii_app\records\Admin; +use yii_app\records\AdminGroup; use yii_app\records\AdminPayrollDays; use yii_app\records\CityStore; use yii_app\records\EmployeePosition; @@ -56,11 +57,18 @@ class ReportService $employeePositions = EmployeePosition::find()->select(['id', 'name'])->indexBy('id')->asArray()->all(); - $adminPositions = Admin::find()->select(['id', 'employee_position_id', 'group_name']) + $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) { @@ -68,21 +76,8 @@ class ReportService if (!empty($admin['employee_position_id']) && isset($employeePositions[$admin['employee_position_id']])) { $positionName = $employeePositions[$admin['employee_position_id']]['name']; - } elseif (!empty($admin['group_name'])) { - // Ищем похожее название в employee_positions - $groupNameLower = mb_strtolower(trim($admin['group_name'])); - $found = false; - foreach ($employeePositions as $empPos) { - if (mb_strpos($groupNameLower, mb_strtolower(trim($empPos['name']))) !== false || - mb_strpos(mb_strtolower(trim($empPos['name'])), $groupNameLower) !== false) { - $positionName = $empPos['name']; - $found = true; - break; - } - } - if (!$found) { - $positionName = $admin['group_name']; - } + } elseif (!empty($admin['group_id']) && isset($adminGroups[$admin['group_id']])) { + $positionName = $adminGroups[$admin['group_id']]['name']; } $positionMap[$adminId] = $positionName; @@ -549,10 +544,43 @@ class ReportService ->groupBy(['admin_id'])->asArray()->all(); $employeeCountTotal = count($employeesTotal); + // Получаем все уникальные 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; + } + foreach ($data->date as $ind => $dateStartEnd) { $currentDate = $dateStartEnd[0]; $employeeCount = []; + $weekEmployees = []; // Собираем сотрудников за неделю + $storeWeekEmployees = []; // Сотрудники по магазинам за неделю foreach ($data->stores as $store_id) { $employees = Sales::find()->select(["COUNT(*) as cnt", "admin_id"]) ->where(['between', 'date', @@ -561,6 +589,14 @@ class ReportService ->andWhere(['store_id' => $store_id]) ->groupBy(['admin_id'])->asArray()->all(); $employeeCount[$store_id] = count($employees); + + // Сохраняем сотрудников для этого магазина + $storeWeekEmployees[$store_id] = $employees; + + // Добавляем сотрудников этого магазина в массив за неделю + foreach ($employees as $employee) { + $weekEmployees[$employee['admin_id']] = $employee; + } } $storeVisitorsQuantityTotal = []; @@ -813,10 +849,41 @@ class ReportService $currentDate = date("Y-m-d", strtotime("+1 day", strtotime($currentDate))); } + // Подсчет должностей сотрудников за неделю + $employeePositionsOnShift = []; + foreach ($weekEmployees as $employee) { + $adminId = $employee['admin_id']; + $positionName = $positionMap[$adminId] ?? ''; + + if (!empty($positionName)) { + if (!isset($employeePositionsOnShift[$positionName])) { + $employeePositionsOnShift[$positionName] = 0; + } + $employeePositionsOnShift[$positionName]++; + } + } + + $stores = []; $total = []; foreach ($data->stores as $store_id) { + // Рассчитываем employee_positions_on_shift для этого магазина за неделю + $storeEmployeePositionsOnShift = []; + if (isset($storeWeekEmployees[$store_id])) { + foreach ($storeWeekEmployees[$store_id] as $employee) { + $adminId = $employee['admin_id']; + $positionName = $positionMap[$adminId] ?? ''; + + if (!empty($positionName)) { + if (!isset($storeEmployeePositionsOnShift[$positionName])) { + $storeEmployeePositionsOnShift[$positionName] = 0; + } + $storeEmployeePositionsOnShift[$positionName]++; + } + } + } + $store = [ "sale_month_total" => ($salesMonth[$store_guids[$store_id]]["total"] ?? 0), "sale_total" => $storeSaleTotalTotal[$store_id] ?? 0, @@ -846,6 +913,7 @@ class ReportService "total_wrap_per_day" => $totalWrapPerDayTotal[$store_id] ?? 0, "total_services_per_day" => $totalServicePerDayTotal[$store_id] ?? 0, "total_potted_per_day" => $totalPottedPerDayTotal[$store_id] ?? 0, + "employee_positions_on_shift" => $storeEmployeePositionsOnShift, ]; $stores []= ['id' => $store_id, 'guid' => $eitStores[$store_id]['export_val'], 'name' => $cityStoreNames[$store_id], 'data' => $store]; @@ -885,6 +953,7 @@ class ReportService $total["employee_sale_avg"] = $employeeCountTotal > 0 ? floor($total["sale_total"] / $employeeCountTotal) : 0; $total["conversion"] = $total["visitors_quantity"] > 0 ? floor($total["sale_quantity"] / $total["visitors_quantity"] * 100) : 0;; $total["bonus_user_per_sale_percent"] = $total["sale_quantity"] > 0 ? floor($total["bonus_user_count"] / $total["sale_quantity"] * 100) : 0; + $total["employee_positions_on_shift"] = $employeePositionsOnShift; $report = [ "date_from" => $dateStartEnd[0], @@ -952,8 +1021,41 @@ class ReportService ->groupBy(['admin_id'])->asArray()->all(); $employeeCountTotal = count($employeesTotal); + // Получаем все уникальные 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; + } + foreach ($days as $ind => $day) { $employeeCount = []; + $allDayEmployees = []; // Собираем всех сотрудников за день по всем магазинам + $storeEmployeesData = []; // Данные о сотрудниках по магазинам foreach ($data->stores as $store_id) { $employees = Sales::find()->select(["COUNT(*) as cnt", "admin_id"]) ->where([ @@ -965,6 +1067,14 @@ class ReportService ->andWhere(['store_id' => $store_id]) ->groupBy(['admin_id'])->asArray()->all(); $employeeCount[$store_id] = count($employees); + + // Сохраняем данные сотрудников для этого магазина + $storeEmployeesData[$store_id] = $employees; + + // Добавляем сотрудников этого магазина в общий массив за день + foreach ($employees as $employee) { + $allDayEmployees[$employee['admin_id']] = $employee; + } } $storeVisitorsQuantityTotal = []; @@ -1237,6 +1347,22 @@ class ReportService foreach ($data->stores as $store_id) { if (!empty($eitStores[$store_id])){ + // Рассчитываем employee_positions_on_shift для этого магазина + $storeEmployeePositionsOnShift = []; + if (isset($storeEmployeesData[$store_id])) { + foreach ($storeEmployeesData[$store_id] as $employee) { + $adminId = $employee['admin_id']; + $positionName = $positionMap[$adminId] ?? ''; + + if (!empty($positionName)) { + if (!isset($storeEmployeePositionsOnShift[$positionName])) { + $storeEmployeePositionsOnShift[$positionName] = 0; + } + $storeEmployeePositionsOnShift[$positionName]++; + } + } + } + $store = [ "sale_month_total" => ($salesMonth[$store_guids[$store_id]]["total"] ?? 0), "sale_total" => $storeSaleTotalTotal[$store_id] ?? 0, @@ -1286,6 +1412,7 @@ class ReportService "total_wrap_per_day" => $totalWrapPerDayTotal[$store_id] ?? 0, "total_services_per_day" => $totalServicePerDayTotal[$store_id] ?? 0, "total_potted_per_day" => $totalPottedPerDayTotal[$store_id] ?? 0, + "employee_positions_on_shift" => $storeEmployeePositionsOnShift, ]; $stores [] = [ 'id' => $store_id, @@ -1294,7 +1421,28 @@ class ReportService 'data' => $store ]; - $total["sale_month_total"] = ($total["sale_month_total"] ?? 0) + ($salesMonth[$store_guids[$store_id]]["total"] ?? 0); + } + + // Подсчет должностей сотрудников за день по всем магазинам + $employeePositionsOnShift = []; + foreach ($allDayEmployees as $employee) { + $adminId = $employee['admin_id']; + $positionName = $positionMap[$adminId] ?? ''; + + if (!empty($positionName)) { + if (!isset($employeePositionsOnShift[$positionName])) { + $employeePositionsOnShift[$positionName] = 0; + } + $employeePositionsOnShift[$positionName]++; + } + } + + + $total = []; + + foreach ($data->stores as $store_id) { + if (!empty($eitStores[$store_id])) { + $total["sale_month_total"] = ($total["sale_month_total"] ?? 0) + ($salesMonth[$store_guids[$store_id]]["total"] ?? 0); $total["sale_total"] = ($total["sale_total"] ?? 0) + ($storeSaleTotalTotal[$store_id] ?? 0); $total["sale_quantity"] = ($total["sale_quantity"] ?? 0) + ($storeSaleQuantityTotal[$store_id] ?? 0); $total["sale_avg"] = 0; @@ -1322,6 +1470,7 @@ class ReportService $total["total_wrap_per_day"] = ($total["total_wrap_per_day"] ?? 0) + ($totalWrapPerDayTotal[$store_id] ?? 0); $total["total_services_per_day"] = ($total["total_services_per_day"] ?? 0) + ($totalServicePerDayTotal[$store_id] ?? 0); $total["total_potted_per_day"] = ($total["total_potted_per_day"] ?? 0) + ($totalPottedPerDayTotal[$store_id] ?? 0); + } } } $total["sale_avg"] = $total["sale_quantity"] > 0 ? floor( @@ -1348,6 +1497,7 @@ class ReportService $total["bonus_user_per_sale_percent"] = $total["sale_quantity"] > 0 ? floor( $total["bonus_user_count"] / $total["sale_quantity"] * 100 ) : 0; + $total["employee_positions_on_shift"] = $employeePositionsOnShift; $report = [ "date" => $day, -- 2.39.5