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

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);

Источники