get_user_activity_by_positions.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php /** Created by Anton on 05.03.2020. */
  2. require 'tmc/yiiInit.php';
  3. use app\models\entity\Accounts;
  4. use app\models\entity\Jobtypes;
  5. use app\models\entity\ProjectsLocotech;
  6. use app\models\entity\Tasks;
  7. use app\models\entity\Tasktypes;
  8. const DATE_FORMAT = 'Y-m-d H:i:s';
  9. //Получение данных запроса
  10. try {
  11. $date = new DateTime($_GET['date']);
  12. } catch (Exception $e) {
  13. $date = new DateTime();
  14. }
  15. $shift = (int)$_GET['shift'];
  16. $company = (int)$_GET['company'];
  17. $positionIds = (array)$_GET['positions'];
  18. $positions = [];
  19. foreach ($positionIds as $positionId) {
  20. $positions[] = Jobtypes::findOne($positionId)->name;
  21. }
  22. //Временные интервалы
  23. $twelveHour = new DateInterval('PT12H');
  24. $threeHour = new DateInterval('PT3H');
  25. //Установка времени начала смены
  26. $date->add($threeHour);//Смена начинается в 3 ночи
  27. if ($shift) {
  28. $date->add($twelveHour);//Вторая смена через 12 часов
  29. }
  30. //Даты начала и конца смены
  31. $startShift = clone $date;
  32. $date->add($twelveHour);
  33. $endShift = clone $date;
  34. $endShift->add($oneHour);//Захватываем лишний час по просьбам ***
  35. //Получаем проекты компании company, созданные в $date, во время смены $shift
  36. $projects = ProjectsLocotech::find()
  37. ->where(['company' => $company])
  38. ->andWhere(['between', 'created', $startShift->format(DATE_FORMAT), $endShift->format(DATE_FORMAT)])
  39. ->all()
  40. ;
  41. //Получаем массив где ключ это идентификатор локомотива, а значение является массивом задач
  42. //['locoId => ['A' = [tasks], 'Б' => [tasks]]]
  43. $tasksByLocoId = [];
  44. //Массив букв секций локомотива
  45. $lettersByLocoId = [];
  46. //Количество задач для каждого пользователя, для каждого локомотива, для секций к которым привязаны задачи
  47. $counts = [];
  48. //Статусы задач, для подсчёта выполненных
  49. $statuses = [];
  50. foreach ($projects as $project) {
  51. $locoId = $project->loco_type . '-' . $project->loco_number;
  52. //Фильтруем задачи:
  53. $tasks = Tasks::find()
  54. // ->where(['id' => explode(',', $project->tasks)])
  55. ->where(['input_id' => $project->id])
  56. //Задача должна иметь пользователя
  57. ->andWhere(['not', ['assignees_arr' => null]])
  58. //Задача должна попадать во временной интервал
  59. ->andWhere(['between', 'created', $startShift->format(DATE_FORMAT), $endShift->format(DATE_FORMAT)])
  60. ->all()
  61. ;
  62. //Пользователь должен иметь в списке должностей хотябы одну из $positions
  63. foreach ($tasks as $key => $task) {
  64. /** @var Accounts $user */
  65. if ($user = $task->getAccounts()->one()) {
  66. $positionFound = false;
  67. foreach ($user->getPositionIds() as $positionId) {
  68. if (in_array($positionId, $positionIds)) $positionFound = true;
  69. }
  70. }
  71. if ($positionFound) {
  72. $taskType = Tasktypes::findOne($task->type);
  73. $letter = $taskType->letter ? $taskType->letter : '?';
  74. $tasksByLocoId[$locoId][$user->name][$letter][] = $task;
  75. //Сохраняем существующие буквы секции у каждого локомотива
  76. if (!in_array($letter, $lettersByLocoId[$locoId])) {
  77. $lettersByLocoId[$locoId][] = $letter;
  78. }
  79. if (isset($counts[$locoId][$user->name][$letter])) {
  80. $counts[$locoId][$user->name][$letter]++;
  81. } else {
  82. $counts[$locoId][$user->name][$letter] = 1;
  83. }
  84. $statuses[$locoId][$user->name][$letter][] = $task->status;
  85. }
  86. }
  87. }
  88. //Подсчитываем статистику [locoId => [userName => [letter => 50%]]]
  89. $dataForTable = [];
  90. foreach ($tasksByLocoId as $locoId => $tasksByUser) {
  91. foreach ($tasksByUser as $userName => $tasksByLetter) {
  92. foreach ($lettersByLocoId[$locoId] as $letter) {
  93. if (isset($tasksByLocoId[$locoId][$userName][$letter])) {
  94. //Подсчитываем процент выполненных работ для пользователя и секции
  95. $taskCount = $counts[$locoId][$userName][$letter];//Всего задач в секции для пользователя
  96. $taskFinishedCount = 0;
  97. foreach ($tasksByLocoId[$locoId][$userName][$letter] as $task) {
  98. if ($task->status == 5) $taskFinishedCount++;
  99. }
  100. //Процент выполненных задач пользователя от всех задач пользователя по секции
  101. $dataForTable[$locoId][$userName][$letter] = round($taskFinishedCount / $taskCount * 100) . '%';
  102. } else {
  103. $dataForTable[$locoId][$userName][$letter] = '0%';
  104. }
  105. }
  106. }
  107. }
  108. ?>
  109. <div class="for-print">
  110. <h3>Дата: <?= $date->format('d.m.Y') ?>. Смена: <?= $shift ? 'ночная' : 'дневная' ?></h3>
  111. <h4>Должности: <?= implode(', ', $positions)?></h4>
  112. <?php foreach ($lettersByLocoId as $locoId => $letters):
  113. sort($letters);
  114. //Не выводим пустые таблицы
  115. if (!isset($dataForTable[$locoId])) continue;
  116. list($locoSeries, $locoNumber) = explode('-', $locoId)
  117. ?>
  118. <table class="table text-center" border="2">
  119. <thead>
  120. <tr>
  121. <td colspan="<?= count($letters) + 1?>">
  122. <h3>Локомотив серии <?= $locoSeries ?> с номером <?= $locoNumber ?></h3>
  123. </td>
  124. </tr>
  125. </thead>
  126. <tr>
  127. <th>Сотрудник</th>
  128. <?php foreach ($letters as $letter): ?>
  129. <th><?= $letter ?></th>
  130. <?php endforeach; ?>
  131. </tr>
  132. <?php ksort($dataForTable[$locoId]); ?>
  133. <?php foreach ($dataForTable[$locoId] as $userName => $statistics): ?>
  134. <tr>
  135. <td><?= $userName ?></td>
  136. <?foreach ($letters as $letter): ?>
  137. <td><?= $statistics[$letter] ?></td>
  138. <?php endforeach; ?>
  139. </tr>
  140. <?php endforeach; ?>
  141. </table>
  142. <?php endforeach; ?>
  143. </div>
  144. <style type="text/css">
  145. :root {
  146. --border-style: 2px solid #000;
  147. }
  148. #content {
  149. margin-top: 60px;
  150. }
  151. .table td {
  152. padding: 0;
  153. border: var(--border-style);
  154. }
  155. .table th {
  156. border: var(--border-style);
  157. }
  158. h3, h4 {
  159. text-align: center;
  160. }
  161. </style>