Как передать договор контрагента в документе поступления по платежным картам при обмене через формат EnterpriseData в КД 3.0?

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

При разработке и настройке правил обмена в конфигурации «Конвертация данных 3.0» (КД 3.0) через универсальный формат EnterpriseData разработчики часто сталкиваются с ситуацией, когда в документе ПоступлениеНаРасчетныйСчет с видом операции «Поступления от продаж по платежным картам и банковским кредитам» в базе-источнике заполнен реквизит ДоговорКонтрагента (в шапке или в табличной части РасшифровкаПлатежа), однако в схеме XDTO формата EnterpriseData соответствующее свойство для данного документа отсутствует.

Разберем детально, почему возникает эта проблема, какие особенности структуры XDTO мешают использовать стандартный механизм дополнительных реквизитов и какими способами можно корректно передать или восстановить договор контрагента в базе-приемнике.

Причина ограничения схемы EnterpriseData

Проанализируем структуру пакета XDTO. В типовых версиях формата EnterpriseData объект Документ.ПБДСПоПлатежнымКартам (Поступление безналичных денежных средств по платежным картам) не имеет базового типа Object из пространства имен ExchangeMessage. Вследствие этого у данного типа XDTO отсутствует стандартное свойство AdditionalInfo (Дополнительная информация), которое обычно применяется для передачи произвольных структур данных.

Попытка выполнить принудительную вставку в обработчике выгрузки:


ДанныеXDTO.Вставить("AdditionalInfo", Строка(ДанныеИБ.ДоговорКонтрагента.УникальныйИдентификатор()));

без изменения схемы XDTO приводит к тому, что свойство либо игнорируется сериализатором, либо вызывает ошибку валидации сообщения обмена. Рассмотрим основные пути решения этой задачи без нарушения типовой логики и структуры метаданных.

Способ 1. Автоматический подбор договора по умолчанию в базе-приемнике

В типовых правилах конфигураций на базе БСП (например, «1С:Бухгалтерия предприятия») логика заполнения договора эквайринга вынесена в обработчик ПередЗаписьюПолученныхДанных. Если в документе участвует один основной договор эквайринга с банком, его можно найти или создать автоматически при загрузке.

Посмотрим на пример типового алгоритма заполнения табличной части:


ДоговорЭквайринга = ДоговорЭквайринга(ПолученныеДанные.Организация, ПолученныеДанные.Контрагент);
Для Каждого Расшифровка Из ПолученныеДанные.РасшифровкаПлатежа Цикл
    Если НЕ ЗначениеЗаполнено(Расшифровка.ДоговорКонтрагента) Тогда
        Расшифровка.ДоговорКонтрагента = ДоговорЭквайринга;
    КонецЕсли;
КонецЦикла;

Функция поиска и создания договора эквайринга на стороне приемника строится по следующей схеме:


Функция ДоговорЭквайринга(Организация, Контрагент)
    Если НЕ ЗначениеЗаполнено(Организация) ИЛИ НЕ ЗначениеЗаполнено(Контрагент) Тогда
        Возврат Справочники.ДоговорыКонтрагентов.ПустаяСсылка();
    КонецЕсли;
    
    НаименованиеЭлементаДляОбменаПоУмолчанию = НСтр("ru='Договор эквайринга'");
    ВидДоговора = Перечисления.ВидыДоговоровКонтрагентов.Прочее;
    
    ПараметрыДоговора = Новый Структура;
    ПараметрыДоговора.Вставить("Наименование",         НаименованиеЭлементаДляОбменаПоУмолчанию);
    ПараметрыДоговора.Вставить("Организация",          Организация);
    ПараметрыДоговора.Вставить("Владелец",             Контрагент);
    ПараметрыДоговора.Вставить("ВалютаВзаиморасчетов", ОбщегоНазначенияБПВызовСервераПовтИсп.ПолучитьВалютуРегламентированногоУчета());
    ПараметрыДоговора.Вставить("ВидДоговора",          ВидДоговора);
    
    Договор = ДоговорСПараметрамиПоУмолчанию(ПараметрыДоговора);
    
    Возврат Договор.Ссылка;
КонецФункции

Этот вариант является наиболее простым и надежным, если взаиморасчеты с банком-эквайрером ведутся в рамках единого договора «Прочее».

Способ 2. Определение договора по терминалу или расчетному счету

Если в базе-источнике заведено несколько договоров эквайринга с одним банком, мы можем идентифицировать договор через сопутствующие реквизиты, передаваемые в формате: банковский счет и эквайринговый терминал.

  1. В схеме Документ.ПБДСПоПлатежнымКартам передаются реквизиты счета и терминала эквайринга.
  2. В базе-приемнике в справочнике ЭквайринговыеТерминалы или ДоговорыЭквайринга каждый терминал жестко привязан к конкретному договору взаиморасчетов.
  3. В обработчике ПередЗаписьюПолученныхДанных производим поиск договора по связке Контрагент + Организация + Терминал/Счет, что исключает ошибки при наличии нескольких договоров.

Способ 3. Передача идентификатора договора через транзитные строковые поля

Если требуется передать строго конкретный договор из базы-источника без изменения пакета XDTO, применим технику инкапсуляции данных в свободные текстовые поля формата (например, НазначениеПлатежа или Комментарий).

  1. В модуле менеджера обмена источника (событие ПриОтправкеДанных):

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

    
    Если ЗначениеЗаполнено(ДанныеИБ.ДоговорКонтрагента) Тогда
        GUIDДоговора = Строка(ДанныеИБ.ДоговорКонтрагента.УникальныйИдентификатор());
        ДанныеXDTO.НазначениеПлатежа = "[ContractGUID:" + GUIDДоговора + "]" + ДанныеXDTO.НазначениеПлатежа;
    КонецЕсли;
    
  2. В модуле менеджера обмена приемника (событие ПриКонвертацииДанныхXDTO):

    Считываем маркер из строки, извлекаем идентификатор и очищаем технический префикс:

    
    Маркер = "[ContractGUID:";
    ПозицияМаркера = СтрНайти(ДанныеXDTO.НазначениеПлатежа, Маркер);
    Если ПозицияМаркера > 0 Тогда
        КонецМаркера = СтрНайти(ДанныеXDTO.НазначениеПлатежа, "]", , ПозицияМаркера);
        ДлинаМаркера = СтрДлина(Маркер);
        ИдентификаторДоговора = Сред(ДанныеXDTO.НазначениеПлатежа, ПозицияМаркера + ДлинаМаркера, КонецМаркера - ПозицияМаркера - ДлинаМаркера);
        
        // Сохраняем во временную структуру для записи
        ПолученныеДанные.ДополнительныеСвойства.Вставить("ИдентификаторДоговора", ИдентификаторДоговора);
        
        // Очищаем реквизит до исходного вида
        ДанныеXDTO.НазначениеПлатежа = Сред(ДанныеXDTO.НазначениеПлатежа, КонецМаркера + 1);
    КонецЕсли;
    
  3. В событии ПередЗаписьюПолученныхДанных:

    По сохраненному УникальныйИдентификатор находим ссылку в справочнике ДоговорыКонтрагентов (или через регистр СоответствияОбъектовИнформационныхБаз) и присваиваем ее строкам табличной части РасшифровкаПлатежа.

Способ 4. Расширение пакета XDTO через расширение конфигурации

Если архитектура проекта требует передачи данных через строгие типы, вносить изменения напрямую в типовой пакет EnterpriseData не рекомендуется, так как это усложняет обновление конфигурации. В современных версиях БСП для добавления реквизитов рекомендуется подключать собственное расширение формата обмена с отдельным пространством имен (URI), расширяющим базовые типы схемы без снятия типовой конфигурации с поддержки.

← На главную