Работа с элементами Смарт Процессов через операции в модуле CRM Битрикс24
Операция, это действие или как правило их совокупность для достижения какой-либо цели.
Рассуждая об элементах смарт-процессов в CRM можно запросто запутаться в понятиях и их взаимосвязях. Поначалу неопытные разработчики принимают запись в базу данных значений за совершение действий, однако это вовсе не так. Если удалось записать в таблицу значения, это совершенно не значит что те же действия будут выполнены в связанных компонентах. Запись в базу данных там тоже появится, но это будет лишь вершиной айсберга.
Представим элемент смарт-процесса, который мы хотим добавить. Добавление, это действие которое мы хотим совершить, запись в базу лишь часть большого многоходового процесса, добавления элемента. Здесь мы можем попасть в ловушку и подумать что процесс добавление элемента это и есть фактическое добавление записи в базу данных, однако не стоит забыть что в нем так же участвуют обработчики событий, проверка прав, нормализация данных, поисковая индексация и другие важные этапы, в том числе запуск бизнес-процессов запускаемых при добавлении элемента.
Термин «Операция» наиболее емко описывает необходимый набор действий для достижений конкретной цели. Например Операция добавления элемента описывает комплексный набор действий который нужно выполнить над элементом для его полного и корректного сохранения.
Порядок действий в операции
В общем случае, операция выполняется следующим образом:
- Проверка тарифных ограничений
- Проверка прав доступа к элементу
- Проверка запущенных БП (актуально для удаления)
- Обработка дополнительной логик полей перед операцией
- Проверка заполненных полей (на предмет обязательности)
- Если элемент изменен, запуск действий до сохранения
- Если элемент не изменен, завершение операции
- Обработка дополнительной логики полей после операции
- Обновление прав
- Обновление поискового индекса
- Сохранение записи в историю и
timeline - Запуск действий после сохранения
- Если применимы стадии, отправка
pushсообщения - Запуск бизнес-процессов
- Запуск автоматизации
Порядок выполнения действий строго определен, однако в зависимости от конкретной операции, некоторые действия могут быть пропущены, будет возвращен базовый \Bitrix\Main\Result.
На текущий момент существует несколько зарегистрированных и поддерживаемых операций:
- Добавление
\Bitrix\Crm\Service\Operation\Add - Обновление
\Bitrix\Crm\Service\Operation\Update - Удаление
\Bitrix\Crm\Service\Operation\Delete - Копирование
\Bitrix\Crm\Service\Operation\Copy - Конвертация
\Bitrix\Crm\Service\Operation\Conversion
Выполнение операции
Выполнение операций является очень простым действием, необходимо получить операцию, сконфигурировать операцию если это необходимо, запустить выполнение.
Несмотря на то что существует две возможности получить операцию, прямое создание объекта и с использованием фабрики, в этой статье будет рассмотрено исключительно получение операции через фабрику, этот способ является единственно верным решением для работы.
Под каждую операцию в абстрактном классе фабрике забронированы следующие имена:
- Добавление
getAddOperation - Обновление
getUpdateOperation - Удаление
getDeleteOperation - Копирование
getCopyOperation - Конвертация
getConversionOperation
Например, есть существующий смарт-процесс с ID = 1036, и некоторый элемент смарт процесса с ID = 5, нам необходимо изменить название TITLE у этого элемента на Test:
\Bitrix\Main\Loader::IncludeModule('crm');
// смарт процесс с идентификатором 1036
$entityTypeId = 1036;
// элемент смарт процесса с идентификатором 5
$elementId = 5;
// получаем контейнер и объект фабрики смарт процесса с идентификатором 1036
$factory = \Bitrix\Crm\Service\Container::getInstance()->getFactory($entityTypeId);
// получаем смарт процесс с идентификатором 5
$item = $factory->getItem($elementId);
// обновляим заголовок одним из методв
$item->setTitle('Test');
//$item->set('TITLE', 'Test');
// 1. выполняим нужную операцию
$operation = $factory->getUpdateOperation($item);
// 2. конфигурируем операцию
// 3. сохраняем операцию
$operationResult = $operation->launch();
if ($operationResult->isSuccess()) {
/**
* Operation success
*/
} else {
/**
* Operation failed with error
*
* @operationResult->getErrors();
* @operationResult->getErrorMessages();
*/
}
Конфигурация операций
Каждый смарт-процесс и сущность CRM уникальна, как и каждая выполняемая операция над элементом. Если вы запускаете импорт элементов из консоли нет необходимости проверять права текущего авторизованного пользователя, в этом случае пользователь уже определен, а если это массовое однотипное действие, например замена данных в полях, нет необходимости запускать бизнес-процессы и автоматизации.
Разработчики заложили возможность гибко настраивать каждую операцию:
| Действие | Включение | Выключение | Проверка |
|---|---|---|---|
| Проверка прав доступа к элементу | enableCheckAccess | disableCheckAccess | isCheckAccessEnabled |
| Проверка запущенных БП | enableCheckWorkflows | disableCheckWorkflows | isCheckWorkflowsEnabled |
| Обработка бизнес-логик полей (до и после) | enableFieldProcession | disableFieldProcession | isFieldProcessionEnabled |
| Проверка заполненных полей (на предмет обязательности) | enableCheckFields | disableCheckFields | isCheckFieldsEnabled |
| -- Валидация польз.полей | enableCheckRequiredUserFields | disableCheckRequiredUserFields | isCheckRequiredUserFields |
| Если элемент изменен, запуск Действий до сохранения | enableBeforeSaveActions | disableBeforeSaveActions | isBeforeSaveActionsEnabled |
| Сохранение записи в историю и timeline | enableSaveToHistory | disableSaveToHistory | isSaveToHistoryEnabled |
| Запуск Действий после сохранения | enableAfterSaveActions | disableAfterSaveActions | isAfterSaveActionsEnabled |
| Запуск бизнес-процессов | enableBizProc | disableBizProc | isBizProcEnabled |
| Запуск автоматизации | enableAutomation | disableAutomation | isAutomationEnabled |
Выключение всех проверок, один вызов эквивалентен disableCheckWorkflows, disableCheckAccess, disableCheckFields, disableCheckRequiredUserFields |
enableAllChecks | disableAllChecks | - |
Например, повторим код выше, но с определенными настройками, выключим проверки бизнес-процессов и стандартных полей:
\Bitrix\Main\Loader::IncludeModule('crm');
// смарт процесс с идентификатором 1036
$entityTypeId = 1036;
// элемент смарт процесса с идентификатором 5
$elementId = 5;
// получаем контейнер и объект фабрики смарт процесса с идентификатором 1036
$factory = \Bitrix\Crm\Service\Container::getInstance()->getFactory($entityTypeId);
// получаем смарт процесс с идентификатором 5
$item = $factory->getItem($elementId);
// обновляим заголовок одним из методв
$item->setTitle('Test');
//$item->set('TITLE', 'Test');
// 1. выполняим нужную операцию
$operation = $factory->getUpdateOperation($item);
// 2. конфигурируем операцию
$operation->disableCheckWorkflows();
$operation->disableCheckRequiredUserFields();
$operation->disableBizProc();
$operation->disableAutomation();
// 3. сохраняем операцию
$operationResult = $operation->launch();
if ($operationResult->isSuccess()) {
/**
* Operation success
*/
} else {
/**
* Operation failed with error
*
* @operationResult->getErrors();
* @operationResult->getErrorMessages();
*/
}
Действия в операции
Одна и та же опция для разных типов сущностей может выполнять разные действия в процессе своего выполнения. Чтобы иерархия классов не разрасталась, разработчики приняли решение вынести возможность дополнительных действий в отдельную иерархию классов, чтобы каждый тип сущности мог управлять действиями при запуске операций.
Класс \Bitrix\Crm\Service\Operation\Action является абстрактным с единственным методом abstract public function process(\Bitrix\Crm\Item $item): \Bitrix\Main\Result, метод process() может как прекратить выполнение операции, так и изменить состояние объекта над которым выполняется операция.
Для действий выполняемых после сохранения, можно вызвать сохранение элемента $item->save() повторно.
Метод addAction() принимает два ключевых параметра:
Operation::ACTION_BEFORE_SAVEдо сохранения элемента в БДOperation::ACTION_AFTER_SAVEпосле успешного сохранения элемента в БД
Пример добавления действий к полученной операции:
\Bitrix\Main\Loader::IncludeModule('crm');
// смарт процесс с идентификатором 1036
$entityTypeId = 1036;
// получаем контейнер и объект фабрики смарт процесса с идентификатором 1036
$factory = \Bitrix\Crm\Service\Container::getInstance()->getFactory($entityTypeId);
// описываем массив полей смарт процесса, включая кастомные
$item = $factory->createItem([
'TITLE' => 'Новый смарт процесс222',
'UF_CRM_3_1766692211591' => 10.0
]);
// 1. выполняим нужную операцию
$operation = $factory->getAddOperation($item);
// 2. конфигурируем операцию
$operation->addAction(
\Bitrix\Crm\Service\Operation::ACTION_BEFORE_SAVE,
new class extends \Bitrix\Crm\Service\Operation\Action {
public function process(\Bitrix\Crm\Item $item): \Bitrix\Main\Result
{
global $operation;
$result = new \Bitrix\Main\Result();
// запретим добавлять элемент смарт процесса если длина TITLE больше 10 символов
if (mb_strlen($operation->getItem()->getTitle()) > 10) {
$result->addError(new \Bitrix\Main\Error('Название слишком длинное, требуется не более 10 символов'));
}
return $result;
}
}
);
// 3. сохраняем операцию
$operationResult = $operation->launch();
if ($operationResult->isSuccess()) {
/**
* Operation success
*/
} else {
/**
* Operation failed with error
*
* @operationResult->getErrors();
* @operationResult->getErrorMessages();
*/
var_dump($operationResult->getErrorMessages());
}