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

CRM

Компании

Работа с компаниями CRM через PHP и фабрики: получение, добавление, изменение, удаление, связи с контактами, реквизитами и события.

Компания — CRM-сущность с типом CCrmOwnerType::Company. Через фабрику удобно получать и менять основные поля, а связи с контактами и реквизитами лучше смотреть отдельно.

Основные операции

Базовая работа с компаниями через новое API CRM и фабрики.

Получить компанию

Фабрика компании получается по типу CCrmOwnerType::Company. После этого можно получить компанию по ID и обращаться к её полям через методы или через get().

<?php

use Bitrix\Main\Loader;
use Bitrix\Crm\Service;

const CRM_COMPANY_TYPE_ID = \CCrmOwnerType::Company;

Loader::includeModule('crm');

/**
 * Получает фабрику компаний.
 */
function fetchCompanyFactory()
{
    $container = Service\Container::getInstance();

    return $container->getFactory(CRM_COMPANY_TYPE_ID);
}

/**
 * Получает компанию по ID.
 */
function fetchCompanyItem(int $company_id)
{
    $factory = fetchCompanyFactory();

    if ($factory === null) {
        return null;
    }

    return $factory->getItem($company_id);
}

$company_item = fetchCompanyItem($company_id);

if ($company_item !== null) {
    $company_data = $company_item->toArray();
    $title = $company_item->getTitle();

    print_r($company_data);
}

Получить список компаний

В getItems() можно передавать привычные параметры: filter, select, order, limit, offset.

<?php

use Bitrix\Main\Loader;
use Bitrix\Crm\Service;

const CRM_COMPANY_TYPE_ID = \CCrmOwnerType::Company;
const COMPANY_LIMIT = 100;

Loader::includeModule('crm');

/**
 * Получает фабрику компаний.
 */
function fetchCompanyFactory()
{
    return Service\Container::getInstance()->getFactory(CRM_COMPANY_TYPE_ID);
}

/**
 * Получает список компаний по фильтру.
 */
function fetchCompanyItems(int $last_company_id): array
{
    $factory = fetchCompanyFactory();

    if ($factory === null) {
        return [];
    }

    return $factory->getItems([
        'select' => [
            'ID',
            'TITLE',
            'ASSIGNED_BY_ID',
            'DATE_CREATE',
        ],
        'filter' => [
            '>ID' => $last_company_id,
        ],
        'order' => [
            'ID' => 'ASC',
        ],
        'limit' => COMPANY_LIMIT,
    ]);
}

$company_items = fetchCompanyItems(0);

foreach ($company_items as $company_item) {
    print_r($company_item->toArray());
}

Добавить компанию

Для добавления лучше использовать операцию getAddOperation(), а не прямой save(). Так будут выполнены проверки и связанные действия CRM.

<?php

use Bitrix\Main\Loader;
use Bitrix\Crm\Service;

const CRM_COMPANY_TYPE_ID = \CCrmOwnerType::Company;

Loader::includeModule('crm');

/**
 * Получает фабрику компаний.
 */
function fetchCompanyFactory()
{
    return Service\Container::getInstance()->getFactory(CRM_COMPANY_TYPE_ID);
}

/**
 * Создаёт компанию.
 */
function addCompany(string $title, int $assigned_by_id): array
{
    $factory = fetchCompanyFactory();

    if ($factory === null) {
        return [
            'is_success' => false,
            'company_id' => 0,
            'error_messages' => ['Фабрика компаний не найдена'],
        ];
    }

    $company_item = $factory->createItem([
        'TITLE' => $title,
        'ASSIGNED_BY_ID' => $assigned_by_id,
    ]);

    $operation = $factory->getAddOperation($company_item);
    $operation_result = $operation->launch();

    return [
        'is_success' => $operation_result->isSuccess(),
        'company_id' => (int) $company_item->getId(),
        'error_messages' => $operation_result->getErrorMessages(),
    ];
}

$add_result = addCompany($title, $assigned_by_id);

print_r($add_result);

Изменить компанию

Поля можно менять через именованные методы, например setTitle(), или через универсальный метод set().

<?php

use Bitrix\Main\Loader;
use Bitrix\Crm\Service;

const CRM_COMPANY_TYPE_ID = \CCrmOwnerType::Company;

Loader::includeModule('crm');

/**
 * Получает фабрику компаний.
 */
function fetchCompanyFactory()
{
    return Service\Container::getInstance()->getFactory(CRM_COMPANY_TYPE_ID);
}

/**
 * Изменяет название компании.
 */
function updateCompanyTitle(int $company_id, string $title): array
{
    $factory = fetchCompanyFactory();

    if ($factory === null) {
        return [
            'is_success' => false,
            'error_messages' => ['Фабрика компаний не найдена'],
        ];
    }

    $company_item = $factory->getItem($company_id);

    if ($company_item === null) {
        return [
            'is_success' => false,
            'error_messages' => ['Компания не найдена'],
        ];
    }

    $company_item->setTitle($title);

    $operation = $factory->getUpdateOperation($company_item);
    $operation_result = $operation->launch();

    return [
        'is_success' => $operation_result->isSuccess(),
        'error_messages' => $operation_result->getErrorMessages(),
    ];
}

$update_result = updateCompanyTitle($company_id, $title);

print_r($update_result);

Удалить компанию

Удаление лучше делать через операцию getDeleteOperation(). Перед удалением стоит проверить, нет ли связанных сделок, контактов, реквизитов и документов.

<?php

use Bitrix\Main\Loader;
use Bitrix\Crm\Service;

const CRM_COMPANY_TYPE_ID = \CCrmOwnerType::Company;

Loader::includeModule('crm');

/**
 * Получает фабрику компаний.
 */
function fetchCompanyFactory()
{
    return Service\Container::getInstance()->getFactory(CRM_COMPANY_TYPE_ID);
}

/**
 * Удаляет компанию.
 */
function deleteCompany(int $company_id): array
{
    $factory = fetchCompanyFactory();

    if ($factory === null) {
        return [
            'is_success' => false,
            'error_messages' => ['Фабрика компаний не найдена'],
        ];
    }

    $company_item = $factory->getItem($company_id);

    if ($company_item === null) {
        return [
            'is_success' => false,
            'error_messages' => ['Компания не найдена'],
        ];
    }

    $operation = $factory->getDeleteOperation($company_item);
    $operation_result = $operation->launch();

    return [
        'is_success' => $operation_result->isSuccess(),
        'error_messages' => $operation_result->getErrorMessages(),
    ];
}

$delete_result = deleteCompany($company_id);

print_r($delete_result);

Связи

Компания часто нужна не сама по себе, а вместе с контактами, реквизитами и сделками.

Контакты компании

Связи компании с контактами можно смотреть через \Bitrix\Crm\Binding\ContactCompanyTable.

<?php

use Bitrix\Main\Loader;
use Bitrix\Crm\Binding\ContactCompanyTable;

Loader::includeModule('crm');

/**
 * Получает ID контактов компании.
 */
function fetchCompanyContactIds(int $company_id): array
{
    return ContactCompanyTable::getCompanyContactIDs($company_id);
}

$contact_ids = fetchCompanyContactIds($company_id);

print_r($contact_ids);

Реквизиты компании

Реквизиты — отдельная сущность. Для компании они ищутся по ENTITY_TYPE_ID = CCrmOwnerType::Company и ENTITY_ID компании.

<?php

use Bitrix\Main\Loader;
use Bitrix\Crm\EntityRequisite;

const CRM_COMPANY_TYPE_ID = \CCrmOwnerType::Company;

Loader::includeModule('crm');

/**
 * Получает реквизиты компании.
 */
function fetchCompanyRequisites(int $company_id): array
{
    $requisites = [];
    $entity_requisite = new EntityRequisite();

    $requisite_result = $entity_requisite->getList([
        'select' => [
            'ID',
            'ENTITY_ID',
            'NAME',
            'RQ_COMPANY_FULL_NAME',
            'RQ_INN',
            'RQ_KPP',
        ],
        'filter' => [
            '=ENTITY_TYPE_ID' => CRM_COMPANY_TYPE_ID,
            '=ENTITY_ID' => $company_id,
        ],
        'order' => [
            'SORT' => 'ASC',
            'ID' => 'ASC',
        ],
    ]);

    while ($requisite = $requisite_result->fetch()) {
        $requisites[] = $requisite;
    }

    return $requisites;
}

$requisites = fetchCompanyRequisites($company_id);

print_r($requisites);

События

События компаний позволяют выполнить свой PHP-код перед добавлением, после добавления, перед изменением, после изменения, перед удалением и после удаления компании.

Список событий

Обработчики обычно регистрируют в /local/php_interface/init.php или внутри своего модуля. Для коробочной разработки это удобный способ реагировать на изменения компаний без REST-приложения.

Событие Когда вызывается Метод
OnBeforeCrmCompanyAdd Перед добавлением компании. CCrmCompany::Add
OnAfterCrmCompanyAdd После добавления компании. CCrmCompany::Add
OnBeforeCrmCompanyUpdate Перед изменением компании. CCrmCompany::Update
OnAfterCrmCompanyUpdate После изменения компании. CCrmCompany::Update
OnBeforeCrmCompanyDelete Перед удалением компании. CCrmCompany::Delete
OnAfterCrmCompanyDelete После удаления компании. CCrmCompany::Delete
OnAfterExternalCrmCompanyAdd После добавления внешней компании. CCrmCompany::Add

Перед добавлением

В OnBeforeCrmCompanyAdd можно изменить поля до сохранения или отменить создание компании. Например, можно запретить создание компании без названия или заполнить ответственному значение по умолчанию.

<?php

use Bitrix\Main\EventManager;

$event_manager = EventManager::getInstance();

/**
 * Регистрирует обработчик перед добавлением компании.
 */
function registerBeforeCompanyAddHandler(EventManager $event_manager): void
{
    $event_manager->addEventHandlerCompatible(
        'crm',
        'OnBeforeCrmCompanyAdd',
        'handleBeforeCompanyAdd'
    );
}

/**
 * Обрабатывает поля перед добавлением компании.
 */
function handleBeforeCompanyAdd(array &$company_fields): bool
{
    global $APPLICATION;

    $title = trim((string) ($company_fields['TITLE'] ?? ''));

    if ($title === '') {
        $APPLICATION->ThrowException('Не заполнено название компании');

        return false;
    }

    if (empty($company_fields['OPENED'])) {
        $company_fields['OPENED'] = 'N';
    }

    return true;
}

registerBeforeCompanyAddHandler($event_manager);

В событиях до сохранения массив полей передаётся по ссылке. Если изменить значение в $company_fields, оно попадёт в сохраняемую компанию.

После изменения

OnAfterCrmCompanyUpdate удобно использовать для логирования, синхронизации со своими таблицами или запуска вспомогательной логики после изменения компании.

<?php

use Bitrix\Main\EventManager;

$event_manager = EventManager::getInstance();

/**
 * Регистрирует обработчик после изменения компании.
 */
function registerAfterCompanyUpdateHandler(EventManager $event_manager): void
{
    $event_manager->addEventHandlerCompatible(
        'crm',
        'OnAfterCrmCompanyUpdate',
        'handleAfterCompanyUpdate'
    );
}

/**
 * Обрабатывает изменение компании.
 */
function handleAfterCompanyUpdate(array &$company_fields): void
{
    $company_id = isset($company_fields['ID']) ? (int) $company_fields['ID'] : 0;

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

    AddMessage2Log(
        [
            'message' => 'Компания изменена',
            'company_id' => $company_id,
            'fields' => $company_fields,
        ],
        'company_events'
    );
}

registerAfterCompanyUpdateHandler($event_manager);

Событие после изменения не всегда содержит полный набор полей компании. Если нужно проверить поле, которого нет в $company_fields, лучше отдельно получить компанию по ID.

Перед удалением

OnBeforeCrmCompanyDelete можно использовать, если удаление нужно проверить или запретить.

<?php

use Bitrix\Main\EventManager;

$event_manager = EventManager::getInstance();

/**
 * Регистрирует обработчик перед удалением компании.
 */
function registerBeforeCompanyDeleteHandler(EventManager $event_manager): void
{
    $event_manager->addEventHandlerCompatible(
        'crm',
        'OnBeforeCrmCompanyDelete',
        'handleBeforeCompanyDelete'
    );
}

/**
 * Проверяет возможность удаления компании.
 */
function handleBeforeCompanyDelete(int $company_id): bool
{
    global $APPLICATION;

    $has_delete_access = true;

    if (!$has_delete_access) {
        $APPLICATION->ThrowException('Удаление компании запрещено');

        return false;
    }

    AddMessage2Log(
        [
            'message' => 'Проверка перед удалением компании',
            'company_id' => $company_id,
        ],
        'company_events'
    );

    return true;
}

registerBeforeCompanyDeleteHandler($event_manager);

Источники