CRM
Лиды
Работа с лидами CRM через PHP и фабрики: получение, добавление, изменение, удаление, статусы и события.
Лид — CRM-сущность с типом CCrmOwnerType::Lead. В отличие от сделки у лида
используется STATUS_ID, а не STAGE_ID.
Основные операции
Базовая работа с лидами через фабрику CRM.
Получить лид
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Service;
const CRM_LEAD_TYPE_ID = \CCrmOwnerType::Lead;
Loader::includeModule('crm');
/**
* Получает фабрику лидов.
*/
function fetchLeadFactory()
{
return Service\Container::getInstance()->getFactory(CRM_LEAD_TYPE_ID);
}
/**
* Получает лид по ID.
*/
function fetchLeadItem(int $lead_id)
{
$factory = fetchLeadFactory();
if ($factory === null) {
return null;
}
return $factory->getItem($lead_id);
}
$lead_item = fetchLeadItem($lead_id);
if ($lead_item !== null) {
$lead_data = $lead_item->toArray();
$title = $lead_item->getTitle();
$status_id = $lead_item->getStageId();
print_r($lead_data);
}
В новом API именованный метод getStageId() унифицирует работу со стадией
или статусом. Для лида фактическое поле в данных — STATUS_ID.
Получить список лидов
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Service;
const CRM_LEAD_TYPE_ID = \CCrmOwnerType::Lead;
const LEAD_LIMIT = 100;
Loader::includeModule('crm');
/**
* Получает фабрику лидов.
*/
function fetchLeadFactory()
{
return Service\Container::getInstance()->getFactory(CRM_LEAD_TYPE_ID);
}
/**
* Получает список лидов по статусу.
*/
function fetchLeadItems(string $status_id): array
{
$factory = fetchLeadFactory();
if ($factory === null) {
return [];
}
return $factory->getItems([
'select' => [
'ID',
'TITLE',
'STATUS_ID',
'NAME',
'LAST_NAME',
'COMPANY_TITLE',
'ASSIGNED_BY_ID',
'DATE_CREATE',
],
'filter' => [
'=STATUS_ID' => $status_id,
],
'order' => [
'ID' => 'ASC',
],
'limit' => LEAD_LIMIT,
]);
}
$lead_items = fetchLeadItems($status_id);
foreach ($lead_items as $lead_item) {
print_r($lead_item->toArray());
} Добавить лид
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Service;
const CRM_LEAD_TYPE_ID = \CCrmOwnerType::Lead;
Loader::includeModule('crm');
/**
* Получает фабрику лидов.
*/
function fetchLeadFactory()
{
return Service\Container::getInstance()->getFactory(CRM_LEAD_TYPE_ID);
}
/**
* Создаёт лид.
*/
function addLead(array $lead_fields): array
{
$factory = fetchLeadFactory();
if ($factory === null) {
return [
'is_success' => false,
'lead_id' => 0,
'error_messages' => ['Фабрика лидов не найдена'],
];
}
$lead_item = $factory->createItem($lead_fields);
$operation = $factory->getAddOperation($lead_item);
$operation_result = $operation->launch();
return [
'is_success' => $operation_result->isSuccess(),
'lead_id' => (int) $lead_item->getId(),
'error_messages' => $operation_result->getErrorMessages(),
];
}
$lead_fields = [
'TITLE' => $title,
'NAME' => $name,
'LAST_NAME' => $last_name,
'COMPANY_TITLE' => $company_title,
'STATUS_ID' => $status_id,
'SOURCE_ID' => $source_id,
'ASSIGNED_BY_ID' => $assigned_by_id,
];
$add_result = addLead($lead_fields);
print_r($add_result); Изменить лид
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Service;
const CRM_LEAD_TYPE_ID = \CCrmOwnerType::Lead;
Loader::includeModule('crm');
/**
* Получает фабрику лидов.
*/
function fetchLeadFactory()
{
return Service\Container::getInstance()->getFactory(CRM_LEAD_TYPE_ID);
}
/**
* Меняет статус лида.
*/
function updateLeadStatus(int $lead_id, string $status_id): array
{
$factory = fetchLeadFactory();
if ($factory === null) {
return [
'is_success' => false,
'error_messages' => ['Фабрика лидов не найдена'],
];
}
$lead_item = $factory->getItem($lead_id);
if ($lead_item === null) {
return [
'is_success' => false,
'error_messages' => ['Лид не найден'],
];
}
$lead_item->set('STATUS_ID', $status_id);
$operation = $factory->getUpdateOperation($lead_item);
$operation_result = $operation->launch();
return [
'is_success' => $operation_result->isSuccess(),
'error_messages' => $operation_result->getErrorMessages(),
];
}
$update_result = updateLeadStatus($lead_id, $status_id);
print_r($update_result); Удалить лид
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Service;
const CRM_LEAD_TYPE_ID = \CCrmOwnerType::Lead;
Loader::includeModule('crm');
/**
* Получает фабрику лидов.
*/
function fetchLeadFactory()
{
return Service\Container::getInstance()->getFactory(CRM_LEAD_TYPE_ID);
}
/**
* Удаляет лид.
*/
function deleteLead(int $lead_id): array
{
$factory = fetchLeadFactory();
if ($factory === null) {
return [
'is_success' => false,
'error_messages' => ['Фабрика лидов не найдена'],
];
}
$lead_item = $factory->getItem($lead_id);
if ($lead_item === null) {
return [
'is_success' => false,
'error_messages' => ['Лид не найден'],
];
}
$operation = $factory->getDeleteOperation($lead_item);
$operation_result = $operation->launch();
return [
'is_success' => $operation_result->isSuccess(),
'error_messages' => $operation_result->getErrorMessages(),
];
}
$delete_result = deleteLead($lead_id);
print_r($delete_result); События
События лидов позволяют выполнить свой PHP-код перед добавлением, после добавления, перед изменением, после изменения, перед удалением и после удаления лида.
Список событий
Обработчики обычно регистрируют в /local/php_interface/init.php или внутри
своего модуля. Для коробочной разработки это удобный способ реагировать на изменения
лидов без REST-приложения.
| Событие | Когда вызывается | Метод |
|---|---|---|
OnBeforeCrmLeadAdd | Перед добавлением лида. | CCrmLead::Add |
OnAfterCrmLeadAdd | После добавления лида. | CCrmLead::Add |
OnBeforeCrmLeadUpdate | Перед изменением лида. | CCrmLead::Update |
OnAfterCrmLeadUpdate | После изменения лида. | CCrmLead::Update |
OnBeforeCrmLeadDelete | Перед удалением лида. | CCrmLead::Delete |
OnAfterCrmLeadDelete | После удаления лида. | CCrmLead::Delete |
OnAfterExternalCrmLeadAdd | После добавления внешнего лида. | CCrmLead::Add |
OnAfterCrmLeadProductRowsSave | После сохранения товарных строк лида. | CCrmLead::SaveProductRows |
Перед добавлением
В OnBeforeCrmLeadAdd можно изменить поля до сохранения или отменить
создание лида. Например, можно заполнить источник по умолчанию или запретить создание
лида без названия.
<?php
use Bitrix\Main\EventManager;
$event_manager = EventManager::getInstance();
/**
* Регистрирует обработчик перед добавлением лида.
*/
function registerBeforeLeadAddHandler(EventManager $event_manager): void
{
$event_manager->addEventHandlerCompatible(
'crm',
'OnBeforeCrmLeadAdd',
'handleBeforeLeadAdd'
);
}
/**
* Обрабатывает поля перед добавлением лида.
*/
function handleBeforeLeadAdd(array &$lead_fields): bool
{
global $APPLICATION;
if (empty($lead_fields['TITLE'])) {
$APPLICATION->ThrowException('Не заполнено название лида');
return false;
}
if (empty($lead_fields['SOURCE_ID'])) {
$lead_fields['SOURCE_ID'] = 'OTHER';
}
return true;
}
registerBeforeLeadAddHandler($event_manager);
В событиях до сохранения массив полей передаётся по ссылке. Если изменить значение в
$lead_fields, оно попадёт в сохраняемый лид.
После изменения
OnAfterCrmLeadUpdate удобно использовать для логирования, синхронизации со
своими таблицами или запуска вспомогательной логики после изменения лида.
<?php
use Bitrix\Main\EventManager;
$event_manager = EventManager::getInstance();
/**
* Регистрирует обработчик после изменения лида.
*/
function registerAfterLeadUpdateHandler(EventManager $event_manager): void
{
$event_manager->addEventHandlerCompatible(
'crm',
'OnAfterCrmLeadUpdate',
'handleAfterLeadUpdate'
);
}
/**
* Обрабатывает изменение лида.
*/
function handleAfterLeadUpdate(array &$lead_fields): void
{
$lead_id = isset($lead_fields['ID']) ? (int) $lead_fields['ID'] : 0;
if ($lead_id <= 0) {
return;
}
AddMessage2Log(
[
'message' => 'Лид изменён',
'lead_id' => $lead_id,
'fields' => $lead_fields,
],
'lead_events'
);
}
registerAfterLeadUpdateHandler($event_manager);
Событие после изменения не всегда содержит полный набор полей лида. Если нужно
проверить поле, которого нет в $lead_fields, лучше отдельно получить лид по
ID.
Перед удалением
OnBeforeCrmLeadDelete можно использовать, если удаление нужно проверить или
запретить.
<?php
use Bitrix\Main\EventManager;
$event_manager = EventManager::getInstance();
/**
* Регистрирует обработчик перед удалением лида.
*/
function registerBeforeLeadDeleteHandler(EventManager $event_manager): void
{
$event_manager->addEventHandlerCompatible(
'crm',
'OnBeforeCrmLeadDelete',
'handleBeforeLeadDelete'
);
}
/**
* Проверяет возможность удаления лида.
*/
function handleBeforeLeadDelete(int $lead_id): bool
{
global $APPLICATION;
$has_delete_access = true;
if (!$has_delete_access) {
$APPLICATION->ThrowException('Удаление лида запрещено');
return false;
}
AddMessage2Log(
[
'message' => 'Проверка перед удалением лида',
'lead_id' => $lead_id,
],
'lead_events'
);
return true;
}
registerBeforeLeadDeleteHandler($event_manager);