← Назад к справке

Бизнес-процессы

События бизнес-процессов

Рабочая справка по событиям бизнес-процессов: внешние события workflow, SendExternalEvent и запуск процессов от событий документа.

В бизнес-процессах слово «событие» может означать разные вещи: событие документа, которое запускает процесс, или внешнее событие, которое продолжает уже запущенный workflow.

Общее понимание

Сначала нужно разделить запуск процесса и продолжение уже запущенного процесса.

Какие события бывают

Тип Что делает Пример
Событие документа Запускает бизнес-процесс при создании или изменении документа. Создали сделку — стартовал шаблон БП.
Внешнее событие workflow Продолжает уже запущенный процесс, который ждёт событие. Процесс ждёт ответ внешней системы.
Событие CRM PHP-обработчик реагирует на изменение CRM-сущности. OnAfterCrmDealUpdate запускает нужный БП.

Внешнее событие workflow

Если процесс уже запущен и остановлен на ожидании внешнего события, его можно продолжить через CBPDocument::SendExternalEvent().

Для этого нужно знать workflow_id запущенного процесса и имя события, которое ждёт действие внутри шаблона.

Отправка события

Внешнее событие отправляется в конкретный workflow.

SendExternalEvent

\Bitrix\Main\Loader::includeModule('bizproc');

/**
 * Отправляет внешнее событие в бизнес-процесс.
 */
function sendWorkflowExternalEvent(
    string $workflow_id,
    string $event_name,
    array $event_parameters = []
): array {
    $error_messages = [];

    \CBPDocument::SendExternalEvent(
        $workflow_id,
        $event_name,
        $event_parameters,
        $error_messages
    );

    return [
        'is_success' => empty($error_messages),
        'error_messages' => $error_messages,
    ];
}

$send_result = sendWorkflowExternalEvent(
    $workflow_id,
    'ExternalSystemAnswer',
    [
        'status' => 'success',
        'external_id' => 123,
    ]
);

print_r($send_result);

Параметры события

Параметры внешнего события зависят от того, как настроено действие ожидания события в шаблоне. Для диагностики лучше сначала передавать простой массив и писать результат в журнал процесса.

$event_parameters = [
    'result_text' => 'Согласовано внешней системой',
    'result_code' => 'APPROVED',
    'external_user_id' => 15,
];

$send_result = sendWorkflowExternalEvent(
    $workflow_id,
    'ExternalApproveEvent',
    $event_parameters
);

if (!$send_result['is_success']) {
    AddMessage2Log(
        [
            'message' => 'Ошибка отправки внешнего события',
            'result' => $send_result,
        ],
        'bizproc_event'
    );
}

События документа

Если нужно запустить процесс при событии CRM, проще связать обработчик CRM-события и CBPDocument::StartWorkflow().

Запуск при изменении CRM

Пример регистрирует обработчик изменения сделки и запускает нужный шаблон бизнес-процесса.

<?php

use Bitrix\Main\EventManager;

const WORKFLOW_TEMPLATE_ID = 123;

/**
 * Регистрирует обработчик изменения сделки.
 */
function registerDealUpdateWorkflowStartHandler(): void
{
    EventManager::getInstance()->addEventHandlerCompatible(
        'crm',
        'OnAfterCrmDealUpdate',
        'handleDealUpdateWorkflowStart'
    );
}

/**
 * Запускает бизнес-процесс после изменения сделки.
 */
function handleDealUpdateWorkflowStart(array &$deal_fields): void
{
    $deal_id = isset($deal_fields['ID']) ? (int) $deal_fields['ID'] : 0;

    if ($deal_id <= 0) {
        return;
    }

    \Bitrix\Main\Loader::includeModule('bizproc');

    $error_messages = [];

    \CBPDocument::StartWorkflow(
        WORKFLOW_TEMPLATE_ID,
        [
            'crm',
            'CCrmDocumentDeal',
            'DEAL_' . $deal_id,
        ],
        [],
        $error_messages
    );

    if (!empty($error_messages)) {
        AddMessage2Log(
            [
                'message' => 'Ошибка запуска БП из события сделки',
                'deal_id' => $deal_id,
                'errors' => $error_messages,
            ],
            'bizproc_event'
        );
    }
}

registerDealUpdateWorkflowStartHandler();

Связь с запуском БП

Если обработчик события сам меняет ту же CRM-сущность, нужно добавить защиту от повторного запуска, иначе можно получить цикл: событие → запуск кода → изменение сущности → событие снова.

/**
 * Обрабатывает изменение сделки с защитой от повторного запуска.
 */
function handleSafeDealUpdateWorkflowStart(array &$deal_fields): void
{
    static $is_handler_running = false;

    if ($is_handler_running) {
        return;
    }

    $is_handler_running = true;

    try {
        handleDealUpdateWorkflowStart($deal_fields);
    } finally {
        $is_handler_running = false;
    }
}

Источники