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

CRM

Множественные поля

Работа с множественными полями CRM в коробочном Bitrix24: телефоны, e-mail, сайты, мессенджеры, CCrmFieldMulti, получение, добавление, изменение и удаление.

Телефон, e-mail, сайт и мессенджер — это не обычные поля карточки CRM. Они хранятся как отдельные записи множественных полей и привязываются к лиду, контакту или компании через ENTITY_ID и ELEMENT_ID.

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

Множественные поля нужны там, где у одной CRM-карточки может быть несколько значений одного типа: несколько телефонов, несколько e-mail, несколько сайтов.

Что такое множественные поля

Множественное поле — это отдельная запись с типом, подтипом и значением. Например, рабочий телефон контакта хранится как запись с TYPE_ID = PHONE, VALUE_TYPE = WORK и самим номером в VALUE.

В карточке CRM эти значения выглядят как обычные телефоны и e-mail, но при работе через PHP их нужно получать и изменять отдельно.

Где они хранятся

Для работы с множественными полями в коробочном PHP используется CCrmFieldMulti. Через него можно получить, добавить, изменить или удалить телефон, e-mail, сайт или мессенджер.

Что нужно Класс Метод
Получить значения CCrmFieldMulti GetList()
Добавить значение CCrmFieldMulti Add()
Изменить значение CCrmFieldMulti Update()
Удалить значение CCrmFieldMulti Delete()

Типы полей

Тип лучше задавать через константы CCrmFieldMulti, а не строками руками.

Константа Что означает
CCrmFieldMulti::PHONE Телефон.
CCrmFieldMulti::EMAIL E-mail.
CCrmFieldMulti::WEB Сайт.
CCrmFieldMulti::IM Мессенджер.

Получение

Для чтения множественных полей важно правильно указать владельца: тип CRM-сущности и ID карточки.

Получить все значения карточки

В множественных полях ENTITY_ID — это строковый код сущности: LEAD, CONTACT, COMPANY. А ELEMENT_ID — ID конкретной карточки.

<?php

use Bitrix\Main\Loader;

const CRM_CONTACT_ENTITY_NAME = 'CONTACT';

Loader::includeModule('crm');

/**
 * Получает множественные поля CRM-карточки.
 */
function fetchMultifieldsByOwner(string $entity_name, int $element_id): array
{
    $multifields = [];

    $multifield_result = \CCrmFieldMulti::GetList(
        [
            'ID' => 'ASC',
        ],
        [
            'ENTITY_ID' => $entity_name,
            'ELEMENT_ID' => $element_id,
        ]
    );

    while ($multifield = $multifield_result->Fetch()) {
        $multifields[] = $multifield;
    }

    return $multifields;
}

$multifields = fetchMultifieldsByOwner(CRM_CONTACT_ENTITY_NAME, $contact_id);

print_r($multifields);

Получить телефоны

Чтобы получить только телефоны, добавляем фильтр по TYPE_ID.

<?php

use Bitrix\Main\Loader;

const CRM_CONTACT_ENTITY_NAME = 'CONTACT';

Loader::includeModule('crm');

/**
 * Получает телефоны CRM-карточки.
 */
function fetchPhoneMultifields(string $entity_name, int $element_id): array
{
    $phones = [];

    $multifield_result = \CCrmFieldMulti::GetList(
        [
            'ID' => 'ASC',
        ],
        [
            'ENTITY_ID' => $entity_name,
            'ELEMENT_ID' => $element_id,
            'TYPE_ID' => \CCrmFieldMulti::PHONE,
        ]
    );

    while ($phone = $multifield_result->Fetch()) {
        $phones[] = $phone;
    }

    return $phones;
}

$phones = fetchPhoneMultifields(CRM_CONTACT_ENTITY_NAME, $contact_id);

print_r($phones);

Для e-mail, сайта и мессенджера меняется только TYPE_ID: CCrmFieldMulti::EMAIL, CCrmFieldMulti::WEB, CCrmFieldMulti::IM.

Найти карточки с телефоном или почтой

У лидов, контактов и компаний есть служебные признаки вроде HAS_PHONE и HAS_EMAIL. Их удобно использовать, когда нужно найти карточки, у которых вообще есть телефон или e-mail, не вытаскивая сразу все значения.

<?php

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

const CRM_CONTACT_TYPE_ID = \CCrmOwnerType::Contact;

Loader::includeModule('crm');

/**
 * Получает контакты, у которых есть телефон.
 */
function fetchContactsWithPhone(): array
{
    $factory = Service\Container::getInstance()->getFactory(CRM_CONTACT_TYPE_ID);

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

    return $factory->getItems([
        'select' => [
            'ID',
            'NAME',
            'LAST_NAME',
            'HAS_PHONE',
            'HAS_EMAIL',
        ],
        'filter' => [
            '=HAS_PHONE' => 'Y',
        ],
        'order' => [
            'ID' => 'ASC',
        ],
        'limit' => 100,
    ]);
}

$contacts = fetchContactsWithPhone();

foreach ($contacts as $contact) {
    print_r($contact->toArray());
}

Такой фильтр не возвращает сами номера. Он только помогает найти карточки, у которых есть хотя бы одно значение нужного типа.

Изменение

Для изменения множественных полей используется ID конкретной записи множественного поля. Это не ID контакта, компании или лида.

Добавить значение

Пример добавляет рабочий телефон контакта.

<?php

use Bitrix\Main\Loader;

const CRM_CONTACT_ENTITY_NAME = 'CONTACT';

Loader::includeModule('crm');

/**
 * Добавляет множественное поле CRM.
 */
function addMultifield(
    string $entity_name,
    int $element_id,
    string $type_id,
    string $value_type,
    string $value
): int {
    $field_multi = new \CCrmFieldMulti();

    $multifield_id = $field_multi->Add(
        [
            'ENTITY_ID' => $entity_name,
            'ELEMENT_ID' => $element_id,
            'TYPE_ID' => $type_id,
            'VALUE_TYPE' => $value_type,
            'VALUE' => $value,
        ],
        [
            'ENABLE_NOTIFICATION' => true,
        ]
    );

    return (int) $multifield_id;
}

$phone_id = addMultifield(
    CRM_CONTACT_ENTITY_NAME,
    $contact_id,
    \CCrmFieldMulti::PHONE,
    'WORK',
    '+7 999 111-22-33'
);

Изменить значение

Для обновления нужен ID записи множественного поля. Его можно получить через GetList().

<?php

use Bitrix\Main\Loader;

Loader::includeModule('crm');

/**
 * Изменяет множественное поле CRM.
 */
function updateMultifield(int $multifield_id, string $value_type, string $value): bool
{
    $field_multi = new \CCrmFieldMulti();

    $is_updated = $field_multi->Update(
        $multifield_id,
        [
            'VALUE_TYPE' => $value_type,
            'VALUE' => $value,
        ],
        [
            'ENABLE_NOTIFICATION' => true,
        ]
    );

    return (bool) $is_updated;
}

$is_updated = updateMultifield(
    $multifield_id,
    'WORK',
    '+7 999 555-44-33'
);

Удалить значение

Удаление выполняется по ID записи множественного поля.

<?php

use Bitrix\Main\Loader;

Loader::includeModule('crm');

/**
 * Удаляет множественное поле CRM.
 */
function deleteMultifield(int $multifield_id): bool
{
    $field_multi = new \CCrmFieldMulti();

    $is_deleted = $field_multi->Delete(
        $multifield_id,
        [
            'ENABLE_NOTIFICATION' => true,
        ]
    );

    return (bool) $is_deleted;
}

$is_deleted = deleteMultifield($multifield_id);

Заменить телефоны карточки

Если нужно заменить все телефоны карточки, сначала получаем текущие телефоны, удаляем их, затем добавляем новые значения.

<?php

use Bitrix\Main\Loader;

const CRM_CONTACT_ENTITY_NAME = 'CONTACT';

Loader::includeModule('crm');

/**
 * Получает множественные поля нужного типа.
 */
function fetchMultifieldsByType(string $entity_name, int $element_id, string $type_id): array
{
    $multifields = [];

    $multifield_result = \CCrmFieldMulti::GetList(
        [
            'ID' => 'ASC',
        ],
        [
            'ENTITY_ID' => $entity_name,
            'ELEMENT_ID' => $element_id,
            'TYPE_ID' => $type_id,
        ]
    );

    while ($multifield = $multifield_result->Fetch()) {
        $multifields[] = $multifield;
    }

    return $multifields;
}

/**
 * Удаляет множественное поле.
 */
function deleteMultifield(int $multifield_id): bool
{
    $field_multi = new \CCrmFieldMulti();

    return (bool) $field_multi->Delete(
        $multifield_id,
        [
            'ENABLE_NOTIFICATION' => true,
        ]
    );
}

/**
 * Добавляет множественное поле.
 */
function addMultifield(
    string $entity_name,
    int $element_id,
    string $type_id,
    string $value_type,
    string $value
): int {
    $field_multi = new \CCrmFieldMulti();

    return (int) $field_multi->Add(
        [
            'ENTITY_ID' => $entity_name,
            'ELEMENT_ID' => $element_id,
            'TYPE_ID' => $type_id,
            'VALUE_TYPE' => $value_type,
            'VALUE' => $value,
        ],
        [
            'ENABLE_NOTIFICATION' => true,
        ]
    );
}

/**
 * Заменяет телефоны CRM-карточки.
 */
function replacePhoneMultifields(string $entity_name, int $element_id, array $phone_values): void
{
    $old_phones = fetchMultifieldsByType(
        $entity_name,
        $element_id,
        \CCrmFieldMulti::PHONE
    );

    foreach ($old_phones as $old_phone) {
        deleteMultifield((int) $old_phone['ID']);
    }

    foreach ($phone_values as $phone_value) {
        addMultifield(
            $entity_name,
            $element_id,
            \CCrmFieldMulti::PHONE,
            'WORK',
            $phone_value
        );
    }
}

replacePhoneMultifields(
    CRM_CONTACT_ENTITY_NAME,
    $contact_id,
    [
        '+7 999 111-22-33',
        '+7 999 555-44-33',
    ]
);

Поля

Основные поля записи множественного поля и значения, которые чаще всего приходится использовать в фильтрах.

Основные поля записи

Поле Что означает
ID ID записи множественного поля.
ENTITY_ID Строковый тип владельца: LEAD, CONTACT, COMPANY.
ELEMENT_ID ID карточки CRM.
TYPE_ID Тип значения: PHONE, EMAIL, WEB, IM.
VALUE_TYPE Подтип значения: рабочий, домашний, мобильный и т. д.
COMPLEX_ID Составной код вида PHONE_WORK или EMAIL_HOME.
VALUE Само значение: номер телефона, e-mail, сайт или идентификатор мессенджера.

VALUE_TYPE

VALUE_TYPE уточняет назначение значения. Для телефона это может быть рабочий, мобильный или домашний номер. Для e-mail — рабочая или домашняя почта.

VALUE_TYPE Когда использовать
WORK Рабочий телефон, e-mail или сайт.
HOME Домашний телефон или e-mail.
MOBILE Мобильный телефон.
OTHER Другое значение, если точный тип не подходит.

Список доступных подтипов может отличаться в зависимости от типа поля и версии портала. Для служебного скрипта обычно достаточно сначала вывести уже существующие записи и посмотреть, какие VALUE_TYPE используются на портале.

ENTITY_ID и ELEMENT_ID

Самая частая ошибка — передать в ENTITY_ID числовой тип CCrmOwnerType::Contact. В множественных полях туда нужен строковый код сущности.

Карточка ENTITY_ID ELEMENT_ID
Лид LEAD ID лида.
Контакт CONTACT ID контакта.
Компания COMPANY ID компании.

У сделки обычно нет собственных телефонов и e-mail как у клиента. Телефоны и почта обычно находятся у связанного контакта, компании или лида.

Источники