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
*/
$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 = [];
$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"])
// Получаем все уникальные 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];
$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'];
}
// Подсчет должностей сотрудников за неделю
- $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 = [];
// Получаем все уникальные 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 = [];
}
// Подсчет должностей сотрудников за день по всем магазинам
- $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 = [];