Как настроить интеграцию нескольких баз 1С:ERP с одной базой 1С:Документооборот без дублирования контрагентов?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием IT и автоматизация бизнеса
← На главную

При построении ИТ-ландшафта крупных холдингов часто возникает задача подключения нескольких информационных баз 1С:ERP Управление предприятием к единой централизованной базе 1С:Документооборот 3.0 (ДО 3). Если базы 1С:ERP являются распределенными (РИБ) и имеют идентичную нормативно-справочную информацию (НСИ) с одинаковыми уникальными идентификаторами (УИД/GUID), то стандартная бесшовная интеграция работает корректно. Однако, если базы 1С:ERP принадлежат разным юридическим лицам, не имеют между собой синхронизации НСИ и ведутся независимо, возникает серьезная проблема.

При попытке открыть карточку контрагента из «своей» ERP, система ищет связь в регистре сведений СвязиОбъектовИнтегрированныхСистем на стороне ДО 3. Не найдя сопоставления по УИД, система предлагает создать нового контрагента. В результате в базе 1С:Документооборот лавинообразно плодятся дубли контрагентов, имеющих одинаковые ИНН и КПП, но разные УИД в разных базах ERP. В этой статье мы подробно разберем, как решить эту проблему, переопределив стандартный механизм поиска бесшовной интеграции.

Почему стандартный механизм подмены dataBaseID не подходит для независимых баз

В более ранних версиях (например, в 1С:Документооборот 2.1) для обхода ограничений интеграции с РИБ-базами часто использовался метод подмены идентификатора базы-источника (dataBaseID). Мы могли перехватить запрос в веб-сервисе DMService и подменить идентификатор узла интегрированной системы на «основной» узел:


Функция ОбработатьУниверсальноеСообщение(Сообщение) Экспорт
    // Пример подмены dataBaseID в ДО 2.1
    Если Сообщение.Свойства().Получить("dataBaseID") <> Неопределено Тогда
        УзелИнтегрированнойСистемы = ОбработкаЗапросовXDTOКорп.УзелИнтегрированнойСистемыПоСообщению(Сообщение);
        Если ЗначениеЗаполнено(УзелИнтегрированнойСистемы) Тогда
            Если ЗначениеЗаполнено(УзелИнтегрированнойСистемы.преф_УзелДляПодмены) Тогда
                Сообщение.dataBaseID = УзелИнтегрированнойСистемы.преф_УзелДляПодмены.Идентификатор;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
...

Однако для независимых баз ERP этот метод абсолютно бесполезен. Даже если мы подменим идентификатор базы, УИД одного и того же контрагента в базе ERP-1 и базе ERP-2 будут гарантированно различаться. Система все равно не найдет объект по УИД и попытается создать дубль. Наша задача — заставить систему выполнять сопоставление по реальным бизнес-ключам (ИНН и КПП для юрлиц, ИНН для физлиц, Email для пользователей).

Архитектура решения проблемы дублирования НСИ

Для реализации корректного поиска нам необходимо вмешаться в логику работы Библиотеки интеграции с документооборотом (БИД) на стороне 1С:Документооборот 3.0. Основная идея заключается в следующем:

  1. При поступлении запроса из ERP на создание или сопоставление объекта, система ДО должна сначала проверить наличие связи по УИД.
  2. Если связь не найдена, мы должны перехватить управление и выполнить поиск объекта в справочнике Корреспонденты по ИНН и КПП.
  3. Если контрагент с такими реквизитами найден, мы должны принудительно (программно) зарегистрировать связь между УИД контрагента из текущей ERP и найденной ссылкой в ДО в регистре сведений СвязиОбъектовИнтегрированныхСистем.
  4. После этого система вернет вызывающей базе ERP найденного контрагента, и дубль создан не будет.

Реализация поиска по ИНН/КПП на стороне 1С:Документооборот 3.0

Проанализируем структуру интеграции ДО 3. Запросы обрабатываются через веб-сервисы интеграции. Нам необходимо доработать функцию поиска соответствия для внешнего объекта. В качестве точки расширения (через механизм расширений конфигурации) выберем общий модуль, отвечающий за поиск интегрированных объектов.

Рассмотрим пример кода, который выполняет поиск контрагента по ИНН и КПП при получении данных из ERP:


&Вместо("НайтиСоответствиеДляВнешнегоОбъекта")
Функция преф_НайтиСоответствиеДляВнешнегоОбъекта(ДанныеОбъекта, ТипОбъектаДО, УзелИнтеграции)
    
    СсылкаНаОбъект = Неопределено;
    
    // Обрабатываем только контрагентов (в ДО 3 это справочник "Корреспонденты")
    Если ТипОбъектаДО = "Справочник_Корреспонденты" Тогда
        
        ИНН = "";
        КПП = "";
        
        // Извлекаем ИНН и КПП из переданных данных XDTO/Структуры
        Если ДанныеОбъекта.Свойства().Получить("ИНН") <> Неопределено Тогда
            ИНН = СокрЛП(ДанныеОбъекта.ИНН);
        КонецЕсли;
        
        Если ДанныеОбъекта.Свойства().Получить("КПП") <> Неопределено Тогда
            КПП = СокрЛП(ДанныеОбъекта.КПП);
        КонецЕсли;
        
        Если ЗначениеЗаполнено(ИНН) Тогда
            // Выполняем поиск в базе ДО
            Запрос = Новый Запрос;
            Запрос.Текст = 
                "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
                |	Корреспонденты.Ссылка КАК Ссылка
                |ИЗ
                |	Справочник.Корреспонденты КАК Корреспонденты
                |ГДЕ
                |	Корреспонденты.ИНН = &ИНН
                |	И ИЗБЕГАТЬ_ДУБЛЕЙ_УСЛОВИЕ
                |	И НЕ Корреспонденты.ПометкаУдаления";
            
            // Если КПП заполнен, добавляем его в условия поиска
            Если ЗначениеЗаполнено(КПП) Тогда
                Запрос.Текст = СтрЗаменить(Запрос.Текст, "И ИЗБЕГАТЬ_ДУБЛЕЙ_УСЛОВИЕ", "И Корреспонденты.КПП = &КПП");
                Запрос.УстановитьПараметр("КПП", КПП);
            Иначе
                Запрос.Текст = СтрЗаменить(Запрос.Текст, "И ИЗБЕГАТЬ_ДУБЛЕЙ_УСЛОВИЕ", "");
            EndIf;
            
            Запрос.УстановитьПараметр("ИНН", ИНН);
            Результат = Запрос.Выполнить();
            
            Если Не Результат.Пустой() Тогда
                Выборка = Результат.Выбрать();
                Выборка.Следующий();
                СсылкаНаОбъект = Выборка.Ссылка;
                
                // Принудительно регистрируем связь, чтобы при последующих вызовах поиск не повторялся
                ЗарегистрироватьСвязьОбъектов(СсылкаНаОбъект, ДанныеОбъекта.Идентификатор, УзелИнтеграции, ТипОбъектаДО);
            КонецЕсли;
        КонецЕсли;
        
    КонецЕсли;
    
    // Если объект найден по ИНН/КПП, возвращаем его, иначе вызываем стандартный поиск
    Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
        Возврат СсылкаНаОбъект;
    КонецЕсли;
    
    Возврат ПродолжитьВызов(ДанныеОбъекта, ТипОбъектаДО, УзелИнтеграции);
    
КонецФункции

Для программной регистрации связи в регистре СвязиОбъектовИнтегрированныхСистем используем процедуру записи в регистр сведений на стороне ДО:


Процедура ЗарегистрироватьСвязьОбъектов(СсылкаНаОбъект, ИДВнешнегоОбъекта, УзелИнтеграции, ТипОбъектаДО)
    
    НаборЗаписей = РегистрыСведений.СвязиОбъектовИнтегрированныхСистем.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.УзелИнтегрированнойСистемы.Установить(УзелИнтеграции);
    НаборЗаписей.Отбор.ИдентификаторОбъектаИнтегрированнойСистемы.Установить(ИДВнешнегоОбъекта);
    
    НоваяЗапись = НаборЗаписей.Добавить();
    НоваяЗапись.УзелИнтегрированнойСистемы = УзелИнтеграции;
    НоваяЗапись.ИдентификаторОбъектаИнтегрированнойСистемы = ИДВнешнегоОбъекта;
    НоваяЗапись.ТипОбъектаИнтегрированнойСистемы = ТипОбъектаДО;
    НоваяЗапись.ОбъектДокументооборота = СсылкаНаОбъект;
    
    Попытка
        НаборЗаписей.Записать(Истина);
    Исключение
        ЗаписьЖурналаРегистрации("Интеграция.ПоискКонтрагентов", УровеньЖурналаРегистрации.Ошибка,,, 
            ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    КонецПопытки;
    
КонецПроцедуры

Особенности интеграции физических лиц и пользователей

Помимо контрагентов, аналогичные проблемы с дублированием возникают для справочников Физические лица и Пользователи. Применим те же принципы поиска:

Настройка на стороне 1С:ERP

На стороне ERP перед открытием формы интеграции ДО проверяет наличие связи в локальном регистре сведений ОбъектыИнтегрированныеС1СДокументооборотом. Если записи там нет, ERP отправляет веб-запрос к ДО.

Чтобы минимизировать задержки интерфейса и оптимизировать количество веб-запросов, проанализируем функцию БИД на стороне ERP: ИнтеграцияС1СДокументооборот3.ПолучитьДанныеСвязанногоОбъектаДО. При открытии карточки не связанного ранее контрагента ERP обратится к ДО, наш кастомизированный веб-сервис ДО найдет сопоставление по ИНН/КПП, зарегистрирует связь у себя и вернет успешный ответ. ERP, получив ответ, автоматически создаст запись в своем локальном регистре ОбъектыИнтегрированныеС1СДокументооборотом.

Таким образом, сопоставление «закроется» в обеих базах при первом же обращении к контрагенту из ERP.

Практические советы по отладке интеграции

Разберем процесс отладки такого сложного взаимодействия между несколькими информационными базами по шагам:

  1. Подготовка окружения: Разверните локально копии баз ERP-1, ERP-2 и базы ДО 3. Убедитесь, что все базы опубликованы на веб-сервере (IIS или Apache).
  2. Настройка параметров отладки: Запустите несколько конфигураторов одновременно (для ERP и для ДО). В параметрах запуска баз укажите ключ /РежимОтладки. В настройках отладки конфигуратора ДО обязательно включите отладку HTTP и Web-сервисов.
  3. Увеличение таймаута: По умолчанию таймаут ожидания ответа веб-сервиса в ERP составляет около 30 секунд. При остановке на точках останова в конфигураторе ДО, ERP быстро отвалится по ошибке таймаута. Рекомендуется временно увеличить таймаут ожидания в коде интеграции ERP (например, до 600 секунд) на период разработки и тестирования.
  4. Тестирование сценария: Создайте контрагента «Ромашка» с ИНН 7712345678 в ERP-1 и откройте его интеграционную карту — создастся объект в ДО. Затем перейдите в ERP-2, создайте контрагента «Ромашка» с тем же ИНН 7712345678 и откройте интеграционную карту. Убедитесь, что система не предложила создать новый элемент, а сразу отобразила карточку контрагента, созданного ранее из ERP-1.

Используя данный подход, вы полностью решите проблему дублирования нормативно-справочной информации, сохраните чистоту базы данных «1С:Документооборот» и обеспечите сквозную аналитику по всем юридическим лицам холдинга.

← На главную