Каким образом можно создать эффективный фильтр задач в коробочной версии Битрикс24?

Какова основная задача моего скрипта, который предназначен для добавления нового пользователя в список наблюдателей закрытых задач определенного пользователя? У меня установлен фильтр для задач, где пользователь выступает либо в роли ответственного, либо в качестве постановщика, однако возникает проблема с фильтрацией: работая с двумя субфильтрами, второй субфильтр не применяется должным образом. Можете ли вы помочь мне с этой проблемой? Вот весь код: <br/> <br/> <pre><code class="php">global $USER;

if (empty($_POST["OLDUSER"]) || empty($_POST["NEWUSER"])) {
    echo "Не указаны ID пользователей.";
    exit;
}

$oldUserId = intval($_POST["OLDUSER"]);
$newUserId = intval($_POST["NEWUSER"]);
$creationDateFrom = $_POST['CREATION_DATE_FROM'];
$creationDateTo = $_POST['CREATION_DATE_TO'];
$oldUser = CUser::GetByID($oldUserId)-&gt;Fetch();
$newUser = CUser::GetByID($newUserId)-&gt;Fetch();

if (!$oldUser) {
    echo "Не найден старый пользователь с таким ID";
    exit;
} elseif (!$newUser) {
    echo "Не найден новый пользователь с таким ID";
    exit;
}

$creationDateFrom = !empty($creationDateFrom) ? ConvertTimeStamp(strtotime($creationDateFrom), "FULL") : null;
$creationDateTo = !empty($creationDateTo) ? ConvertTimeStamp(strtotime($creationDateTo) + 86400, "FULL") : null;

if (!$creationDateFrom || !$creationDateTo) {
    echo "Не указаны даты создания задач.";
    exit;
}

$filter = array(
    '::LOGIC' =&gt; 'AND',
    '&gt;=CREATED_DATE' =&gt; $creationDateFrom,
    '&lt;=CREATED_DATE' =&gt; $creationDateTo,
    '::SUBFILTER-1' =&gt; array(
        '::LOGIC' =&gt; 'OR',
        'RESPONSIBLE_ID' =&gt; $oldUserId,
        'REAL_STATUS' =&gt; array(CTasks::STATE_COMPLETED),
    ),
    '::SUBFILTER-2' =&gt; array(
        'CREATED_BY' =&gt; $oldUserId,
        'REAL_STATUS'
  • 25 октября 2024 г. 5:42
Ответы на вопрос 2
Для создания эффективного фильтра задач в Box-версии Битрикс24, ключевой момент заключается в правильной настройке фильтрации по всем нужным параметрам, включая использование субфильтров. Ваша проблема, связанная с использованием двух субфильтров, возможно, может быть решена следующим образом.

Проблема, с которой вы столкнулись, может быть связана с тем, что условие между двумя субфильтрами должно быть задано правильно, а также не забывайте об использовании логики `AND` или `OR` между условиями. Предполагаю, что ваши два субфильтра должны быть объединены с использованием логики `OR`, так как вы хотите объединить задачи, где пользователь выставлен ответственно или является создателем задачи.

Ваш код может быть переписан следующим образом для корректного применения субфильтров:

```php
global $USER;

if (empty($_POST["OLDUSER"]) || empty($_POST["NEWUSER"])) {
    echo "Не указаны ID пользователей.";
    exit;
}

$oldUserId = intval($_POST["OLDUSER"]);
$newUserId = intval($_POST["NEWUSER"]);
$creationDateFrom = $_POST['CREATION_DATE_FROM'];
$creationDateTo = $_POST['CREATION_DATE_TO'];
$oldUser = CUser::GetByID($oldUserId)->Fetch();
$newUser = CUser::GetByID($newUserId)->Fetch();

if (!$oldUser) {
    echo "Не найден старый пользователь с таким ID";
    exit;
} elseif (!$newUser) {
    echo "Не найден новый пользователь с таким ID";
    exit;
}

$creationDateFrom = !empty($creationDateFrom) ? ConvertTimeStamp(strtotime($creationDateFrom), "FULL") : null;
$creationDateTo = !empty($creationDateTo) ? ConvertTimeStamp(strtotime($creationDateTo) + 86400, "FULL") : null;

if (!$creationDateFrom || !$creationDateTo) {
    echo "Не указаны даты создания задач.";
    exit;
}

$filter = array(
    '::LOGIC' => 'AND',
    '>=CREATED_DATE' => $creationDateFrom,
    '<=CREATED_DATE' => $creationDateTo,
    '::SUBFILTER' => array(
        '::LOGIC' => 'OR',
        array(
            'RESPONSIBLE_ID' => $oldUserId,
            'REAL_STATUS' => array(CTasks::STATE_COMPLETED)
        ),
        array(
            'CREATED_BY' => $oldUserId,
            'REAL_STATUS' => array(CTasks::STATE_COMPLETED)
        )
    )
);

// Здесь добавьте код для выборки задач с помощью $filter
```

### Основные изменения:
1. **Упрощение субфильтров:** Вместо двух отдельных субфильтров (`SUBFILTER-1` и `SUBFILTER-2`), создается один общий субфильтр с использованием логики `OR`, объединяющей условия для `RESPONSIBLE_ID` и `CREATED_BY`. Это обеспечит правильную фильтрацию задач.
2. **Обработка ошибок:** Убедитесь, что все проверки на валидные вводимые данные выполняются до использования фильтра.
3. **Тестирование результатов:** После выполнения фильтра проверьте, что задачи возвращаются корректно и содержат нужные данные.

Не забудьте протестировать код и убедиться, что фильтрация работает правильно в зависимости от ваших требований.
В общем решил сделать другим путём, сначала запускаю поиск по ответственным, потом по наблюдателям, насколько это правильно или производительней незнаю. 
КОД
global $USER;

if (empty($_POST["OLDUSER"]) || empty($_POST["NEWUSER"])) {
    echo "Не указаны ID пользователей.";
    exit;
}

$oldUserId = intval($_POST["OLDUSER"]);
$newUserId = intval($_POST["NEWUSER"]);
$creationDateFrom = $_POST['CREATION_DATE_FROM'];
$creationDateTo = $_POST['CREATION_DATE_TO'];
$oldUser = CUser::GetByID($oldUserId)->Fetch();
$newUser = CUser::GetByID($newUserId)->Fetch();

if (!$oldUser) {
    echo "Не найден старый пользователь с таким ID";
    exit;
} elseif (!$newUser) {
    echo "Не найден новый пользователь с таким ID";
    exit;
}

$creationDateFrom = !empty($creationDateFrom) ? ConvertTimeStamp(strtotime($creationDateFrom), "FULL") : null;
$creationDateTo = !empty($creationDateTo) ? ConvertTimeStamp(strtotime($creationDateTo) + 86400, "FULL") : null;

if (!$creationDateFrom || !$creationDateTo) {
    echo "Не указаны даты создания задач.";
    exit;
}

// Первый этап: ищем задачи, где старый пользователь является ответственным
$filterForResponsible = array(
    '::LOGIC' => 'AND',
    '>=CREATED_DATE' => $creationDateFrom,
    '<=CREATED_DATE' => $creationDateTo,
    'RESPONSIBLE_ID' => $oldUserId,
    'REAL_STATUS' => array(CTasks::STATE_COMPLETED),
);

// Обновляем наблюдателей
$messages = [];
$tasksUpdated = processTasks($filterForResponsible, $newUserId, $USER->GetID(), $messages);

if ($tasksUpdated === 0) {
    // Второй этап: ищем задачи, где старый пользователь является постановщиком
    $filterForCreator = array(
        '::LOGIC' => 'AND',
        '>=CREATED_DATE' => $creationDateFrom,
        '<=CREATED_DATE' => $creationDateTo,
        'CREATED_BY' => $oldUserId,
        'REAL_STATUS' => array(CTasks::STATE_COMPLETED),
    );

    $tasksUpdated += processTasks($filterForCreator, $newUserId, $USER->GetID(), $messages);
}

if ($tasksUpdated === 0) {
    $messages[] = "Не найдено задач для обновления.";
}

echo implode("<br>", $messages);

function processTasks($filter, $newUserId, $currentUserId, &$messages) {
    $res = CTasks::GetList([], $filter);
    $tasksUpdated = 0;

    while ($arTask = $res->GetNext()) {
        $taskId = $arTask["ID"];
        $taskItem = new CTaskItem($taskId, $currentUserId);
        $taskData = $taskItem->getData();
        
        $auditors = $taskData["AUDITORS"] ?? [];

        if (!in_array($newUserId, $auditors)) {
            $auditors[] = $newUserId;
            $obTask = new CTasks;
            $updateFields = [
                "AUDITORS" => $auditors
            ];

            $success = $obTask->Update($taskId, $updateFields);

            if ($success) {
                $messages[] = "Задача с ID $taskId: Новый наблюдатель добавлен.";
                $tasksUpdated++;
            } else {
                if ($e = $APPLICATION->GetException()) {
                    $messages[] = "Ошибка при обновлении задачи ID $taskId: " . htmlspecialchars($e->GetString());
                }
            }
        } else {
            $messages[] = "Задача с ID $taskId: Наблюдатель с ID $newUserId уже существует.";
        }
    }

    return $tasksUpdated;
}
Похожие вопросы