From 9f81dd1a375503510d9fc8824d1e243dbf711ccd Mon Sep 17 00:00:00 2001 From: Vladimir Fomichev Date: Wed, 10 Dec 2025 11:54:36 +0300 Subject: [PATCH] =?utf8?q?=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB=20?= =?utf8?q?=D0=BD=D0=B0=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/api3/core/services/ReportService.php | 61 +++++++++++++++------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/erp24/api3/core/services/ReportService.php b/erp24/api3/core/services/ReportService.php index 2fa6981e..ea698f99 100644 --- a/erp24/api3/core/services/ReportService.php +++ b/erp24/api3/core/services/ReportService.php @@ -300,6 +300,33 @@ class ReportService return $employeePositionsOnShift; } + /** + * Агрегирует данные по сотрудникам на смене без дедупликации + * + * @param array $stores Список магазинов с данными по смене + * @param callable $positionsExtractor Функция, возвращающая массив вида [position => count] + * @param callable $countExtractor Функция, возвращающая количество сотрудников на смене + * @return array{positions: array, count: int} + */ + private function aggregateEmployeesOnShift(array $stores, callable $positionsExtractor, callable $countExtractor): array + { + $positions = []; + $count = 0; + + foreach ($stores as $storeData) { + $count += (int)$countExtractor($storeData); + + foreach ($positionsExtractor($storeData) as $positionName => $positionCount) { + $positions[$positionName] = ($positions[$positionName] ?? 0) + (int)$positionCount; + } + } + + return [ + 'positions' => $positions, + 'count' => $count, + ]; + } + /** * Генерирует отчет по продажам и сотрудникам за период * @@ -320,7 +347,6 @@ class ReportService $currentDate = $data->date_start; $reports = []; - $totalEmployeePositionsOnShift = []; $totalEmployeeSkillsScores = []; // Получаем все уникальные admin_id сотрудников за период из фактических смен @@ -883,14 +909,11 @@ class ReportService } // Агрегируем сотрудников по магазинам без дедупликации - $totalEmployeePositionsOnShift = []; - $totalEmployeeCountOnShift = 0; - foreach ($report["stores"] as $storeData) { - $totalEmployeeCountOnShift += $storeData["employee_count_on_shift"]; - foreach ($storeData["employee_positions_on_shift"] as $positionName => $count) { - $totalEmployeePositionsOnShift[$positionName] = ($totalEmployeePositionsOnShift[$positionName] ?? 0) + $count; - } - } + $employeeShiftTotals = $this->aggregateEmployeesOnShift( + $report["stores"], + static fn(array $store): array => $store["employee_positions_on_shift"] ?? [], + static fn(array $store): int => (int)($store["employee_count_on_shift"] ?? 0) + ); $report['total'] = [ "sale_total" => $storeSaleTotalTotal, @@ -918,9 +941,9 @@ class ReportService "total_wrap_per_day" => $totalWrapPerDayTotal, "total_services_per_day" => $totalServicePerDayTotal, "total_potted_per_day" => $totalPottedPerDayTotal, - "employee_positions_on_shift" => $totalEmployeePositionsOnShift, + "employee_positions_on_shift" => $employeeShiftTotals['positions'], "employee_skills_score" => $totalEmployeeSkillsScore, - "employee_count_on_shift" => $totalEmployeeCountOnShift, + "employee_count_on_shift" => $employeeShiftTotals['count'], ]; // Создаем итоговый массив для дня с правильным порядком полей @@ -1380,13 +1403,11 @@ class ReportService } // Суммы по всем магазинам без дедупликации сотрудников - $totalEmployeePositionsOnShift = []; - foreach ($stores as $storeData) { - foreach ($storeData['data']['employee_positions_on_shift'] as $position => $count) { - $totalEmployeePositionsOnShift[$position] = ($totalEmployeePositionsOnShift[$position] ?? 0) + $count; - } - } - $totalEmployeeCountOnShift = array_sum($employeeCount); + $employeeShiftTotals = $this->aggregateEmployeesOnShift( + $stores, + static fn(array $store): array => $store['data']['employee_positions_on_shift'] ?? [], + static fn(array $store): int => (int)($store['data']['employee_count_on_shift'] ?? 0) + ); $total["sale_avg"] = $total["sale_quantity"] > 0 ? floor($total["sale_total"] / $total["sale_quantity"]) : 0; $total["total_write_offs_per_date_percent"] = $total["sale_total"] > 0 ? floor($total["total_write_offs_per_date"] / $total["sale_total"] * 100) : 0; @@ -1396,8 +1417,8 @@ 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"] = $totalEmployeePositionsOnShift; - $total["employee_count_on_shift"] = $totalEmployeeCountOnShift; + $total["employee_positions_on_shift"] = $employeeShiftTotals['positions']; + $total["employee_count_on_shift"] = $employeeShiftTotals['count']; $report = [ "date_from" => $dateStartEnd[0], -- 2.39.5