/
vchechun
/
task_checklist_export
Обзор
Документация
Войти
/
vchechun
/
task_checklist_export
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/TaskDates.php
202 строки
5 KB
Vsevolod Chechun
init
07 май 2026, 07:31
07 май 2026, 07:31
fde5953
Код
Авторство
О чём код?
<?php namespace BitrixExt\TaskChecklistExport; use Bitrix\Main\Application; use Bitrix\Main\Loader; use Bitrix\Main\Type\DateTime; use Bitrix\Tasks\Internals\Task\LogTable; use Bitrix\Tasks\Internals\Task\Status; use Bitrix\Tasks\Internals\TaskTable; final class TaskDates { private const STATUS_SUPPOSEDLY_COMPLETED = 4; private const STATUS_COMPLETED = 5; public static function getFormattedByTaskIds(array $taskIds): array { $taskIds = array_values(array_unique(array_filter(array_map('intval', $taskIds)))); if (empty($taskIds) || !Loader::includeModule('tasks')) { return []; } $taskDates = self::loadTaskDates($taskIds); $executorCompletedDates = self::loadLatestStatusDates($taskIds, self::getExecutorCompletedStatus()); $acceptedDates = self::loadLatestStatusDates($taskIds, self::getAcceptedStatus()); $result = []; foreach ($taskIds as $taskId) { $task = $taskDates[$taskId] ?? []; $executorCompletedDate = $executorCompletedDates[$taskId] ?? null; $acceptedDate = $acceptedDates[$taskId] ?? null; if ($executorCompletedDate === null && (int)($task['STATUS'] ?? 0) === self::getExecutorCompletedStatus()) { $executorCompletedDate = $task['CHANGED_DATE'] ?? null; } if ($acceptedDate === null && (int)($task['STATUS'] ?? 0) === self::getAcceptedStatus()) { $acceptedDate = $task['CLOSED_DATE'] ?? null; } $result[$taskId] = [ 'executorCompletedDate' => self::formatDate($executorCompletedDate), 'acceptedDate' => self::formatDate($acceptedDate), ]; } return $result; } private static function loadTaskDates(array $taskIds): array { if (class_exists(TaskTable::class)) { return self::loadTaskDatesViaOrm($taskIds); } return self::loadTaskDatesViaSql($taskIds); } private static function loadTaskDatesViaOrm(array $taskIds): array { $result = []; $rows = TaskTable::getList([ 'select' => ['ID', 'STATUS', 'CHANGED_DATE', 'CLOSED_DATE'], 'filter' => ['@ID' => $taskIds], ]); while ($row = $rows->fetch()) { $result[(int)$row['ID']] = $row; } return $result; } private static function loadTaskDatesViaSql(array $taskIds): array { $connection = Application::getConnection(); $ids = implode(',', array_map('intval', $taskIds)); $sql = " SELECT ID, STATUS, CHANGED_DATE, CLOSED_DATE FROM b_tasks WHERE ID IN ({$ids}) "; $result = []; $rows = $connection->query($sql); while ($row = $rows->fetch()) { $result[(int)$row['ID']] = $row; } return $result; } private static function loadLatestStatusDates(array $taskIds, int $status): array { if (class_exists(LogTable::class)) { return self::loadLatestStatusDatesViaOrm($taskIds, $status); } return self::loadLatestStatusDatesViaSql($taskIds, $status); } private static function loadLatestStatusDatesViaOrm(array $taskIds, int $status): array { $result = []; $rows = LogTable::getList([ 'select' => ['TASK_ID', 'CREATED_DATE'], 'filter' => [ '@TASK_ID' => $taskIds, '=FIELD' => 'STATUS', '=TO_VALUE' => (string)$status, ], 'order' => [ 'TASK_ID' => 'ASC', 'CREATED_DATE' => 'DESC', 'ID' => 'DESC', ], ]); while ($row = $rows->fetch()) { $taskId = (int)$row['TASK_ID']; if (!isset($result[$taskId])) { $result[$taskId] = $row['CREATED_DATE']; } } return $result; } private static function loadLatestStatusDatesViaSql(array $taskIds, int $status): array { $connection = Application::getConnection(); $ids = implode(',', array_map('intval', $taskIds)); $status = (int)$status; $sql = " SELECT TASK_ID, MAX(CREATED_DATE) AS STATUS_DATE FROM b_tasks_log WHERE TASK_ID IN ({$ids}) AND FIELD = 'STATUS' AND TO_VALUE = '{$status}' GROUP BY TASK_ID "; $result = []; $rows = $connection->query($sql); while ($row = $rows->fetch()) { $result[(int)$row['TASK_ID']] = $row['STATUS_DATE']; } return $result; } private static function getExecutorCompletedStatus(): int { return class_exists(Status::class) && defined(Status::class . '::SUPPOSEDLY_COMPLETED') ? (int)Status::SUPPOSEDLY_COMPLETED : self::STATUS_SUPPOSEDLY_COMPLETED; } private static function getAcceptedStatus(): int { return class_exists(Status::class) && defined(Status::class . '::COMPLETED') ? (int)Status::COMPLETED : self::STATUS_COMPLETED; } private static function formatDate($value): string { if ($value instanceof DateTime) { return $value->toString(); } $value = trim((string)$value); if ($value === '') { return ''; } if (function_exists('MakeTimeStamp') && function_exists('FormatDate')) { $timestamp = MakeTimeStamp($value); if ($timestamp > 0) { return FormatDate(defined('FORMAT_DATETIME') ? FORMAT_DATETIME : 'FULL', $timestamp); } } return $value; } }