Как модуль находит пару — поиск, защита от дублей и зацикливания
Каждый обмен начинается с одного вопроса: «Есть ли у этой записи уже пара во второй системе?» Ответ решает всё: есть — модуль обновит пару, нет — создаст новую. Ошибка на этом шаге — это и есть дубль. Поэтому поиск пары — самая важная настройка обмена.
Как идёт поиск
- Поля поиска — это пары полей: поле Битрикс24 и поле МойСклад, значения которых должны совпасть. Например, «ID сделки» ↔ «Внешний код» заказа.
- Поиск идёт сверху вниз. Если полей несколько, модуль пробует их по порядку и останавливается на первой находке. Порядок меняется перетаскиванием — ставьте самое надёжное поле первым.
- Пустое поле пропускается. У новой сделки ещё нет идентификатора МойСклад — это нормально, модуль просто перейдёт к следующей паре.
- Связка сохраняется. Если у пары полей включено «Сохранять соответствия», модуль после создания или находки записывает в неё идентификатор пары. В следующий раз поиск найдёт пару с первой попытки.
Какие поля можно использовать
| Что ищем | Поля Битрикс24 | Поля МойСклад |
|---|---|---|
| Сделка ↔ заказ | ID, внешний идентификатор, строковые пользовательские поля | UUID, Код, Внешний код, Наименование |
| Контакт или компания ↔ контрагент | ID, «Идентификатор элемента во внешнем источнике», «Телефон (первый)», «Email (первый)», строковые пользовательские поля | UUID, Код, Внешний код, Наименование, Телефон, Email, Номер дисконтной карты, ИНН, КПП, ОГРН, ОКПО |
| Оплата ↔ входящий платёж | ID, Внешний код, Номер оплаты | UUID, Код, Внешний код, Наименование, Входящий номер |
Искать контрагента по реквизиту «ИНН» карточки Битрикс24 нельзя: реквизиты хранятся отдельно от карточки. Если нужно сопоставлять компании по ИНН, заведите у компании строковое пользовательское поле с ИНН и свяжите его с полем «ИНН» контрагента МойСклад.
Рекомендуемая связка
Самый надёжный способ — хранить в записи Битрикс24 идентификатор пары из МойСклад и включить для этого поля «Сохранять соответствия»:
- для сделок кнопка «Управление полем для поиска» в настройках документа сама создаёт поле «Идентификатор МС» и добавляет его в поиск;
- можно связать ID записи Битрикс24 с «Внешним кодом» МойСклад или, наоборот, UUID МойСклад — с внешним идентификатором записи CRM;
- для оплат рекомендуются пары «Внешний код» оплаты ↔ UUID платежа и ID оплаты ↔ «Внешний код» платежа.
Поиск по наименованию, телефону или e-mail тоже работает, но он менее надёжен: два клиента с одинаковым названием или общий телефон офиса приведут к неверной паре. Используйте такие поля как запасные, ниже идентификаторов.
Проверить, как модуль находит пары при текущих настройках, можно кнопкой «Проверить поиск» в настройках поиска — подробнее на странице Заказ покупателя.
Почему модуль не плодит дубли
- Без связки обмен не стартует. Пока в настройках документа, контрагентов или оплат нет ни одного поля поиска с сохранением связки, этот вид обмена не запускается вовсе. Это встроенная проверка, а не рекомендация.
- Сбой поиска — не повод создавать. Если при поиске МойСклад не ответил или поле поиска оказалось удалено, модуль не создаёт новую запись вслепую: задача уходит в ошибку и повтор. Лучше подождать минуту, чем получить двойника.
- Неподходящее значение отбрасывается. Например, строку «00123» модуль не станет искать в числовом поле ID — иначе нашлась бы посторонняя запись.
- Связка чинится сама. Если запись нашлась по одной паре полей, а вторая пара разошлась, модуль приводит её в порядок при обновлении.
- Одна задача на запись. Пока задача по сделке ждёт в очереди, новые сохранения этой сделки не создают второй задачи — значит, не будет и двух параллельных созданий одного заказа. См. Очередь.
Тип документа при поиске
Заказы покупателя и поставщику в Битрикс24 — одинаковые сделки. Чтобы при загрузке из МойСклад заказ поставщику не «нашёл» сделку-продажу, есть настройка «Учёт типа документа при поиске»:
| Вариант | Когда выбирать |
|---|---|
| С учётом типа (по умолчанию) | Обмен настраивается с нуля |
| Без учёта типа | Обмен работал раньше, а тип документа в старых сделках не заполнен |
| Гибридный поиск | Переходный режим: сначала с учётом типа, затем без него; найденной сделке тип проставляется |
Тип контрагента при поиске
Контрагент ищется по всей базе МойСклад, независимо от типа. Если найденный контрагент — другого типа (например, был физлицом, а в CRM теперь компания), модуль поменяет его тип, только если нашёл его по ID или внешнему коду. Найденный по имени, телефону, e-mail или реквизитам — тип не меняет и пишет предупреждение в логи.
Как находятся товары
Товары в заказе ищутся отдельно, по настройкам страницы Корзина:
- в Битрикс24 — по внешнему коду товара (XML_ID) или по строковому свойству инфоблока; для модификаций — своё поле поиска;
- в МойСклад — по внешнему коду или по идентификатору.
Не нашёл товар — модуль создаёт его во второй системе по образцу: с названием, описанием, картинками, единицей измерения, в разделе или группе, заданных для этого типа товара. Для модификации сначала находится или создаётся родительский товар, для комплекта — все его компоненты. Подробнее — Корзина.
Защита от «пинг-понга»
Обмен двусторонний, а значит, есть риск бесконечного круга: модуль обновил сделку → Битрикс24 сообщил «сделка изменена» → модуль выгрузил её в МойСклад → МойСклад прислал вебхук → модуль снова обновил сделку… Модуль разрывает этот круг в нескольких местах.
- Модуль узнаёт свои правки. Пока модуль сам пишет в сделку, контакт, компанию или оплату, встречные события Битрикс24 игнорируются — задача на обратную выгрузку не создаётся.
- Пишется только изменённое. Перед записью модуль сравнивает данные с тем, что уже лежит во второй системе, и отправляет только реально изменившиеся поля. Если после выгрузки в МойСклад придёт вебхук о «собственном» изменении, сравнение покажет, что менять в сделке нечего, — и круг заканчивается.
- Повторы вебхуков отсеиваются. Одинаковые уведомления МойСклад, пришедшие подряд за несколько секунд, обрабатываются один раз.
- Одно сохранение — одна задача. Битрикс24 порой генерирует несколько событий на одно сохранение сделки; модуль ставит одну задачу.
Если одно и то же поле поменяли в обеих системах почти одновременно, в итоге останется значение той стороны, чей обмен выполнился последним. Модуль не сливает и не сравнивает правки разных пользователей.