Доработка универсального обмена в формате EnterpriseData

В публикации показана доработка универсального обмена в формате EnterpriseData для получения документа поступления товаров из Бухгалтерии 3.0 в Управление Автотранспортом.

Введение

        В типовой конфигурации Управление автотранспортом Проф, редакция 2.2 (УАТ) поддерживается обмен с Бухгалтерией 3.0 (БП) через универсальный формат EnterpriseData. Однако уже после первого обмена, ожидая увидеть документы поступления товаров, оформленные в БП, был неприятно удивлен — их не оказалось. Модель ведения складского учета в УАТ предполагает, что документы поступления товаров и услуг должны быть оформлены в УАТ и обменом попасть в БП. С одной стороны это правильно, где возникают первичные документы, там они и должны быть оформлены, но реалии другие и зачастую первичные документы вводятся в БП, которые уже после должны попасть в УАТ.

Анализ проблемы

        В подсистеме обмена данными стандартных подсистем есть служебный регистр сведений Настройки обмена данными XDTO, в котором для узла обмена сохраняется информация о том, какие метаданные может отправлять и получать корреспондент, заглянув в него в базе БП, увидим, что получение отключено:

      Обмен в формате EnterpriseData в самой 1С построен на общий модулях, центральным из который является МенеджерОбменаЧерезУниверсальныйФормат, опередящий по сути правила обмена (описывает структуры обмена и обработчики). В этом модуле есть экспортная процедура ЗаполнитьПравилаОбработкиДанных, которая и определяет, какие данные отправлять и получать, на основании этой функции и происходит заполнение описанного выше служебного регистра сведений. Общий ее вид такой:

Процедура ЗаполнитьПравилаОбработкиДанных(НаправлениеОбмена, ПравилаОбработкиДанных) Экспорт
Если НаправлениеОбмена = "Отправка" Тогда
ДобавитьПОД_Документ_АвансовыйОтчет_Отправка(ПравилаОбработкиДанных);
ДобавитьПОД_Документ_ВыдачаРасходныхМатериалов_Отправка(ПравилаОбработкиДанных);
//  и т.д.
ИначеЕсли НаправлениеОбмена = "Получение" Тогда
ДобавитьПОД_Документ_АвансовыйОтчет_Получение(ПравилаОбработкиДанных);
ДобавитьПОД_Документ_ЗаказКлиентаВЗаказНаТС_Получение(ПравилаОбработкиДанных);
// и т.д.
КонецЕсли;
КонецПроцедуры

Ожидаемо в ветке "Получение" не было описания правил обработки данных для Поступления товаров и услуг. Это и надо будет решить.

Дописываем правила

               Можно было бы воспользоваться конвертацией данных 3, но конкретно в данной задаче это только займет время, которое можно потратить эффективней. Учитывая, что правила отправки документа Поступления товаров и услуг есть, то по сути нам надо повторить все те же самые процедуры, но на случай получения. Дописывать все будем в расширении, в которое добавим общий модуль МенеджерОбменаЧерезУниверсальныйФормат. Начнем с процедуры ЗаполнитьПравилаОбработкиДанных, добавляем в нее процедуру, которая после работы основной процедуры, добавить наше правило:

&После("ЗаполнитьПравилаОбработкиДанных")
Процедура лок_ЗаполнитьПравилаОбработкиДанных(НаправлениеОбмена, ПравилаОбработкиДанных) Экспорт

Если НаправлениеОбмена = "Получение" Тогда
лок_ДобавитьПОД_Документ_ПоступлениеТоваровУслуг_Получение(ПравилаОбработкиДанных);
КонецЕсли;

КонецПроцедуры

Основа процедуры лок_ДобавитьПОД_Документ_ПоступлениеТоваровУслуг_Получение взята из этого же общего модуля, но для получения другого документа, которая в общем типична:

Процедура лок_ДобавитьПОД_Документ_ПоступлениеТоваровУслуг_Получение(ПравилаОбработкиДанных)
ПравилоОбработки = ПравилаОбработкиДанных.Добавить();
ПравилоОбработки.Имя = "Документ_ПоступлениеТоваровУслуг_Получение";
ПравилоОбработки.ОбъектВыборкиФормат = "Документ.ПоступлениеТоваровУслуг";
ПравилоОбработки.ПриОбработке = "лок_ПОД_Документ_ПоступлениеТоваровУслуг_Получение_ПриОбработке";
ПравилоОбработки.ИспользуемыеПКО.Добавить("Документ_ПоступлениеТоваровУслуг_Получение");
КонецПроцедуры

Процедура достаточно понятная, в ней определяем имя нашего правила, указываем для какого объекта работают правила в названии метаданных для корреспондента, то есть так как называется документ в БП. Указываем процедуру для обработчика при получении данных, в нашем случае в этой процедуре ничего особенного происходить не будет, опять же копируем подобную процедуру и меняем в ней параметры на наши:

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

    Следующим этапом заполняем правила конвертации, которые заполняются экспортной процедурой ЗаполнитьПравилаКонвертацииОбъектов, она очень похожа на ЗаполнитьПравилаОбработкиДанных и имеет по сути тот же вид, наше ее расширение выглядит так:

&После("ЗаполнитьПравилаКонвертацииОбъектов")
Процедура лок_ЗаполнитьПравилаКонвертацииОбъектов(НаправлениеОбмена, ПравилаКонвертации) Экспорт

Если НаправлениеОбмена = "Получение" Тогда
лок_ДобавитьПКО_Документ_ПоступлениеТоваровУслуг_Получение(ПравилаКонвертации);
КонецЕсли;

КонецПроцедуры

Опять же добавленная процедура лок_ДобавитьПКО_Документ_ПоступлениеТоваровУслуг_Получение особо не отличается от процедуры отправки ДобавитьПКО_Документ_ПоступлениеТоваровУслуг_Отправка присутствующей в модуле, поэтому берем ее за основу и получаем:

 

 Процедура ПКО Поступления товаров и услуг

 

Процедура лок_ДобавитьПКО_Документ_ПоступлениеТоваровУслуг_Получение(ПравилаКонвертации)

ПравилоКонвертации = ОбменДаннымиXDTOСервер.ИнициализироватьПравилоКонвертацииОбъекта(ПравилаКонвертации);
ПравилоКонвертации.ИмяПКО = "Документ_ПоступлениеТоваровУслуг_Получение";
ПравилоКонвертации.ОбъектДанных = Метаданные.Документы.уатПоступлениеТоваровУслуг;
ПравилоКонвертации.ОбъектФормата = "Документ.ПоступлениеТоваровУслуг";
ПравилоКонвертации.ПравилоДляГруппыСправочника = Ложь;
ПравилоКонвертации.ВариантИдентификации = "ПоУникальномуИдентификатору";
ПравилоКонвертации.ПриКонвертацииДанныхXDTO = "лок_ПКО_Документ_ПоступлениеТоваровУслуг_Получение_ПриКонвертацииДанныхXDTO";
ПравилоКонвертации.ПередЗаписьюПолученныхДанных = "лок_ПКО_Документ_ПоступлениеТоваровУслуг_Получение_ПередЗаписьюПолученныхДанных";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "ВалютаДокумента";
НоваяСтрока.СвойствоФормата = "Валюта";
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Валюты";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Дата";
НоваяСтрока.СвойствоФормата = "Дата";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "ДатаВходящегоДокумента";
НоваяСтрока.СвойствоФормата = "ДатаВходящегоДокумента";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Контрагент";
НоваяСтрока.СвойствоФормата = "Контрагент";
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Контрагенты_Получение";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "КратностьВзаиморасчетов";
НоваяСтрока.СвойствоФормата = "КратностьВзаиморасчетов";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "КурсВзаиморасчетов";
НоваяСтрока.СвойствоФормата = "КурсВзаиморасчетов";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Номер";
НоваяСтрока.СвойствоФормата = "Номер";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "НомерВходящегоДокумента";
НоваяСтрока.СвойствоФормата = "НомерВходящегоДокумента";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Организация";
НоваяСтрока.СвойствоФормата = "Организация";
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Организации_Получение";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Ответственный";
НоваяСтрока.СвойствоФормата = "Ответственный";
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Пользователи_Получение";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Подразделение";
НоваяСтрока.СвойствоФормата = "Подразделение";
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Подразделения_Получение";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Склад";
НоваяСтрока.СвойствоФормата = "Склад";
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Склады_Получение";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "СуммаВключаетНДС";
НоваяСтрока.СвойствоФормата = "СуммаВключаетНДС";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "СуммаДокумента";
НоваяСтрока.СвойствоФормата = "Сумма";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "ВалютаДокумента";
НоваяСтрока.СвойствоФормата = "ВалютаВзаиморасчетов";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Валюты";

НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Комментарий";
НоваяСтрока.СвойствоФормата = "Комментарий";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
ПравилоКонвертации.СвойстваТабличныхЧастей.Вставить("ДополнительныеРеквизиты", ОбменДаннымиXDTOСервер.ИнициализироватьТаблицуСвойствДляПравилаКонвертации());
СвойстваТЧ = ПравилоКонвертации.СвойстваТабличныхЧастей.ДополнительныеРеквизиты;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "ЗначениеСвойства";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Свойство";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_ДополнительныеРеквизиты";

ПравилоКонвертации.СвойстваТабличныхЧастей.Вставить("Товары", ОбменДаннымиXDTOСервер.ИнициализироватьТаблицуСвойствДляПравилаКонвертации());
СвойстваТЧ = ПравилоКонвертации.СвойстваТабличныхЧастей.Товары;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "ЕдиницаИзмерения";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_ЕдиницыИзмерения_Получение";

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Количество";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Номенклатура";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Номенклатура_Получение";

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "СтавкаНДС";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
НоваяСтрока.ПравилоКонвертацииСвойства = "СтавкиНДС";

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Сумма";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "СуммаНДС";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Цена";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

ПравилоКонвертации.СвойстваТабличныхЧастей.Вставить("Услуги", ОбменДаннымиXDTOСервер.ИнициализироватьТаблицуСвойствДляПравилаКонвертации());
СвойстваТЧ = ПравилоКонвертации.СвойстваТабличныхЧастей.Услуги;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Количество";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Номенклатура";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Номенклатура_Получение";

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Содержание";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "СтавкаНДС";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;
НоваяСтрока.ПравилоКонвертацииСвойства = "СтавкиНДС";

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Сумма";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "СуммаНДС";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

НоваяСтрока = СвойстваТЧ.Добавить();
НоваяСтрока.СвойствоКонфигурации = "Цена";
НоваяСтрока.ИспользуетсяАлгоритмКонвертации = Истина;

КонецПроцедуры

 

Только внимательное следим, какое свойство формата (типа данных из пакета XDTO EnterpriseData) мы будем использовать и в какой реквизит нашего документа он будет конвертироваться, например:

//...
НоваяСтрока = ПравилоКонвертации.Свойства.Добавить();
НоваяСтрока.СвойствоКонфигурации = "ВалютаДокумента";
НоваяСтрока.СвойствоФормата = "Валюта";
НоваяСтрока.ПравилоКонвертацииСвойства = "Справочник_Валюты";
//...

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

 

 Обработчик ПриКонвертацииДанныхXDTO с конвертацией табличной части Товары

Процедураобработчик перед записью полностью типовая, в данном случае так же ее наличие диктуется обработкой дополнительный свойств и реквизитов, а так же особенностью ведения единиц измерений для товара, когда для номенклатуры необходимо указывать не только базовую единицу, но и единицу хранения остатков, которой нет в БП, поэтому перед записью документа УАТ делает проверку для всех номенклатур из документа на наличие единицы хранения остатков и если ее нет, то генерирует на основе базовой единицы измерения.

 

 Обработчик ПередЗаписьюПолученныхДанных

        Последним этапом необходимо переопределить процедуру ВыполнитьПроцедуруМодуляМенеджера, с помощью данной процедуры происходит вызов всех объявленных обработчиков, в том числе и объявленные нами ПриОбработке, ПриКонвертацииДанныхXDTO, ПередЗаписьюПолученныхДанных:

&После("ВыполнитьПроцедуруМодуляМенеджера")
Процедура лок_ВыполнитьПроцедуруМодуляМенеджера(ИмяПроцедуры, Параметры) Экспорт

Если ИмяПроцедуры = "лок_ПОД_Документ_ПоступлениеТоваровУслуг_Получение_ПриОбработке" Тогда
лок_ПОД_Документ_ПоступлениеТоваровУслуг_Получение_ПриОбработке(
Параметры.ОбъектОбработки, Параметры.ИспользованиеПКО, Параметры.КомпонентыОбмена);

ИначеЕсли ИмяПроцедуры = "лок_ПКО_Документ_ПоступлениеТоваровУслуг_Получение_ПриКонвертацииДанныхXDTO" Тогда
лок_ПКО_Документ_ПоступлениеТоваровУслуг_Получение_ПриКонвертацииДанныхXDTO(
Параметры.ДанныеXDTO, Параметры.ПолученныеДанные, Параметры.КомпонентыОбмена);

ИначеЕсли ИмяПроцедуры = "лок_ПКО_Документ_ПоступлениеТоваровУслуг_Получение_ПередЗаписьюПолученныхДанных" Тогда
лок_ПКО_Документ_ПоступлениеТоваровУслуг_Получение_ПередЗаписьюПолученныхДанных(
Параметры.ПолученныеДанные, Параметры.ДанныеИБ, Параметры.КонвертацияСвойств, Параметры.КомпонентыОбмена);
КонецЕсли;

КонецПроцедуры

      Последний штрих, особенность УАТ, из метаданных плана обмена СинхронизацияДанныхЧерезУниверсальныйФормат, в расширение надо добавить макет ПравилаОтправкиПолученияДанных, который описывает фильтры для управлением отправки/получения данных над механизмом обмена данными. В этот макет необходимо добавить запись, что мы теперь умеем получить документ Поступление товаров и услуг.

На этом все. Запускаем расширение и проверяем перенос документ Поступление товаров и услуг. Документ перенесется, но не проведется из-за незаполненного договора контрагента, который в УАТ обязателен для заполнения, но при этом в формате обмена его нет. Решение опять же либо дописать обмен, но уже с двух сторон, если нужен реальный договор, либо отключить необходимость договора, переопределив ОбработкуПроверкиЗаполнения, либо генерировать произвольный общий договор. В моем случае важен только приход товара, поэтому в процедуре-обработчике ПередЗаписьюПолученныхДанных генерируется договор с предопределенным названием если такой не найден для контрагента и этот договор подставляется в документ.

Итог

        Доработка правил не составила особого труда, понадобилось только определить точки входа в модуле МенеджерОбменаЧерезУниверсальныйФормат, их три:

  1. ЗаполнитьПравилаОбработкиДанных
  • Добавили процедуру обработки данных при получении документа,
  • Определили процедуру-обработчик события ПриОбработке
  1. ЗаполнитьПравилаКонвертацииОбъектов
  • Добавили процедуру правила конвертации объекта
  • Определили процедуру-обработчик события ПриКонвертацииДанныхXDTO
  • Определили процедуру-обработчик события ПередЗаписьюПолученныхДанных
  1. ВыполнитьПроцедуруМодуляМенеджера

и по аналогии с имеющимися процедурами для получения данных в модуле, дописать необходимые и дозаполнить макет ПравилаОтправкиПолученияДанных, добавив туда строку, опять же, по аналогии с имеющимися. К публикации приложено расширение, которое в точности повторяет описанное с учетом создания обобщенного договора для контрагента.
        Тестирование проводилось на платформе версии 8.3.13.1809, 1С: Бухгалтерия предприятия 3.0.70.30 и Управление автотранспортом ПРОФ 2.2.5.1.

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *