/**
+ * Генерирует отчет по дням за период
+ *
+ * Собирает статистику по продажам, сотрудникам, посетителям и другим метрикам
+ * за каждый день указанного периода.
+ *
+ * ВАЖНО: При расчете количества сотрудников на смене учитывается тип смены:
+ * - shift_type = 1 (дневная): учитываются только сотрудники с shift_id = 1
+ * - shift_type = 2 (ночная): учитываются только сотрудники с shift_id = 2
+ * - shift_type = 0 (обе смены): учитываются все смены, причем если сотрудник
+ * работает и в дневную, и в ночную смену, он учитывается как 2 человека (дважды)
+ *
+ * @param object $data Параметры запроса:
+ * - date: дата окончания периода (начало = первое число месяца)
+ * - stores: массив ID магазинов
+ * - shift_type: тип смены (0 = обе, 1 = дневная, 2 = ночная)
+ * @return array Массив отчетов по дням
* @throws \yii\base\Exception
* @throws Exception
*/
}
// Получаем все уникальные admin_id сотрудников за период из фактических смен
- $allAdminsInPeriod = TimetableFactModel::find()
- ->select(['admin_id'])
- ->distinct()
+ $allAdminsInPeriodQuery = TimetableFactModel::find()
->where(['store_id' => $data->stores])
->andWhere(['>=', 'date', date("Y-m-01", strtotime($data->date))])
->andWhere(['<=', 'date', date("Y-m-d", strtotime($data->date))])
- ->andWhere(['>', 'work_time', 0])
- ->asArray()
- ->all();
+ ->andWhere(['>', 'work_time', 0]);
- $adminIdsInPeriod = ArrayHelper::getColumn($allAdminsInPeriod, 'admin_id');
- $employeeCountTotal = count($adminIdsInPeriod);
+ // Для типа смены 0 (обе смены) считаем каждую смену отдельно
+ if ($data->shift_type == 0) {
+ // Для обеих смен нужны все записи смен
+ $allAdminsInPeriod = $allAdminsInPeriodQuery
+ ->select(['admin_id', 'shift_id'])
+ ->asArray()
+ ->all();
+ $employeeCountTotal = count($allAdminsInPeriod);
+
+ // Для карт нужны уникальные admin_id
+ $adminIdsInPeriod = array_unique(ArrayHelper::getColumn($allAdminsInPeriod, 'admin_id'));
+ } else {
+ // Для конкретной смены используем фильтр и distinct
+ if ($data->shift_type == 1) {
+ $allAdminsInPeriodQuery->andWhere(['shift_id' => \yii_app\records\Shift::DAY]);
+ } elseif ($data->shift_type == 2) {
+ $allAdminsInPeriodQuery->andWhere(['shift_id' => \yii_app\records\Shift::NIGHT]);
+ }
+
+ $allAdminsInPeriod = $allAdminsInPeriodQuery
+ ->select(['admin_id'])
+ ->distinct()
+ ->asArray()
+ ->all();
+ $adminIdsInPeriod = ArrayHelper::getColumn($allAdminsInPeriod, 'admin_id');
+ $employeeCountTotal = count($adminIdsInPeriod);
+ }
$positionMap = $this->buildPositionMap($adminIdsInPeriod);
$adminSkillMap = $this->buildAdminSkillMap($adminIdsInPeriod);
// Получаем сотрудников из фактических смен за день
foreach ($data->stores as $store_id) {
- $employees = TimetableFactModel::find()
- ->select(['admin_id'])
- ->distinct()
+ $employeesQuery = TimetableFactModel::find()
->where(['store_id' => $store_id])
->andWhere(['date' => $day])
- ->andWhere(['>', 'work_time', 0])
- ->asArray()
- ->all();
+ ->andWhere(['>', 'work_time', 0]);
+
+ // Фильтрация по типу смены
+ if ($data->shift_type == 1) {
+ // Дневная смена
+ $employeesQuery->andWhere(['shift_id' => \yii_app\records\Shift::DAY]);
+ } elseif ($data->shift_type == 2) {
+ // Ночная смена
+ $employeesQuery->andWhere(['shift_id' => \yii_app\records\Shift::NIGHT]);
+ }
+ // Для shift_type == 0 не фильтруем по shift_id
+
+ // Для shift_type == 0 считаем каждую смену отдельно
+ if ($data->shift_type == 0) {
+ $employees = $employeesQuery
+ ->select(['admin_id', 'shift_id'])
+ ->asArray()
+ ->all();
+ } else {
+ // Для конкретной смены используем distinct
+ $employees = $employeesQuery
+ ->select(['admin_id'])
+ ->distinct()
+ ->asArray()
+ ->all();
+ }
$employeeCount[$store_id] = count($employees);
// Добавляем сотрудников этого магазина в общий массив за день
foreach ($employees as $employee) {
- $allDayEmployees[$employee['admin_id']] = $employee;
+ if ($data->shift_type == 0) {
+ // Для обеих смен создаем уникальный ключ с учетом shift_id
+ $key = $employee['admin_id'] . '_' . $employee['shift_id'];
+ $allDayEmployees[$key] = $employee;
+ } else {
+ // Для одной смены используем только admin_id
+ $allDayEmployees[$employee['admin_id']] = $employee;
+ }
}
}