add($threeHour);//Смена начинается в 3 ночи if ($shift) { $date->add($twelveHour);//Вторая смена через 12 часов } //Даты начала и конца смены $startShift = clone $date; $date->add($twelveHour); $endShift = clone $date; $endShift->add($oneHour);//Захватываем лишний час по просьбам *** //Получаем всех сотрудников попадающих во временной интервал $pdo = \classes\PDO::getInsatance(); $stmt = $pdo->query('' . 'select tu.id, ta.id, ta.name, ta.jobtypes, ta.overplan_mode, tu.start, tu.end ' . 'from user_activity tu ' . 'left join accounts_internal ta on tu.employee = ta.id ' . 'where ' . 'ta.company = ' . $company . ' ' . 'and (' //Если активность попадает в интервал смены . ' (tu.start >= \'' . $startShift->format(DATE_FORMAT) . '\' ' . ' and tu.end <= \'' . $endShift->format(DATE_FORMAT) . '\') ' //Если активность больше смены и длится всю смену . ' or (tu.start <= \'' . $startShift->format(DATE_FORMAT) . '\' ' . ' and tu.end >= \'' . $endShift->format(DATE_FORMAT) . '\') ' //Если начало или конец активности попадает в смену . ' or (' . ' (tu.start between \'' . $startShift->format(DATE_FORMAT) . '\' and \'' . $endShift->format(DATE_FORMAT) . '\') ' . ' or ' . ' (tu.end between \'' . $startShift->format(DATE_FORMAT) . '\' and \'' . $endShift->format(DATE_FORMAT) . '\') ' . ' ) ' . ')' ); if (!$stmt->rowCount()) { echo '

Нет данных за этот период

'; exit; } //Ключ - пользователь, значение - массив его интервалов //['name' => 0 => ['start' => time, 'end' => time], 1 =>.. $usersWithIntervals = []; //[<имя пользователя> => , ...] $users = []; foreach ($stmt->fetchAll() as $item) { $usersWithIntervals[$item['name']]['id'] = $item['id']; $users[$item['name']] = $item['id']; if ($item['overplan_mode']) { $usersWithIntervals[$item['name']]['overplan'] = 1; } if (!isset($usersWithIntervals[$item['name']]['specialty'])) { $specialtyIds = explode(',', $item['jobtypes']); $specialtyIds = array_diff($specialtyIds, ['']); foreach ($specialtyIds as $specialtyId) { $specialty = Jobtypes::findOne($specialtyId); if ($specialty) { $usersWithIntervals[$item['name']]['specialty'][] = $specialty->name; } } } $usersWithIntervals[$item['name']]['list'][] = [ 'start' => $item['start'], 'end' => $item['end'] ]; } //Количетво задач пользователя $tasksByUser = []; foreach ($users as $userName => $userId) { $assignedTasks = Tasks::find() ->where([ 'assignees_arr' => $userId, 'parent_id' => 0 ]) ->andWhere(['between', 'created', $startShift->format(DATE_FORMAT), $endShift->format(DATE_FORMAT)]) ->all() ; //Количество назначенных сотруднику задач $tasksByUser[$userName]['assigned'] = count($assignedTasks); $finished = 0; foreach ($assignedTasks as $task) { /** @var Tasks $task */ foreach ($task->getCommands() as $command) { if ($command->finished_time) { $finished++; break; } } } //Количество задач завершённых через МП $tasksByUser[$userName]['finished'] = $finished; } //Данные подготовленные для вставки в таблицу $dataForTable = []; foreach ($usersWithIntervals as $user => $data) { $userTasks = Tasks::findAll(['assignees_arr' => $data['id']]);//, 'accepted_time is not null' //Забиваем сотруднику по STEP нулей за каждый час временного интервала $dataForTable[$user] = []; for ($i = 0; $i < LENGTH_SHIFT * STEP; $i++) { $dataForTable[$user][] = 0; } //Время, к которому будем добавлять по 10 минут $date = clone $startShift; $date->add(new DateInterval('PT5M')); //Сравниваем каждые 10 минут попадает ли это время в интервалы. Если попадает меняем 0 на 1 foreach ($dataForTable[$user] as $key => $value) { $timeString = $date->format(DATE_FORMAT); foreach ($data['list'] as $interval) { if ($interval['start'] <= $timeString && $timeString <= $interval['end']) { $dataForTable[$user][$key] = 1; //Внеплан? if ($data['overplan']) { $dataForTable[$user][$key] = 3; } else { //Проверка попадает ли во время исполнения задачи /** @var Tasks $task */ foreach ($userTasks as $task) { if ( $task->accepted_time <= $timeString && ($timeString <= $task->finished_time) ) { $dataForTable[$user][$key] = 2; } else { //Попадает ли принятие или завершение задачи в предыдущие 10 минут //Костыль, ибо таблица создавалась как "активность пользователей в МП" $previousDateInterval = clone $date; $previousDateInterval->sub($tenMin); $prevTimeString = $previousDateInterval->format(DATE_FORMAT); if ( ($prevTimeString <= $task->accepted_time && $task->accepted_time <= $timeString) || ($prevTimeString <= $task->finished_time && $task->finished_time <= $timeString) ) { $dataForTable[$user][$key] = 2; } } } } $date->add($tenMin); continue 2; } } $date->add($tenMin); } if (isset($data['specialty']) && $data['specialty'] !== 1) { $dataForTable[$user]['specialty'] = $data['specialty']; } else { $dataForTable[$user]['specialty'] = []; } if (isset($data['overplan'])) { array_pop($dataForTable[$user]); $dataForTable[$user]['overplan'] = 1; } } $tmpDate = clone $startShift; ?> add($oneHour) ?> $values): ?>

Начало смены - format('d.m.Y H:i') ?> МСК

Сотрудник format('H:i') ?>
(, )
()

     - не в сети

     - в сети

     - в сети и выполнял задачу

     - внеплан