Каталог решений - EnterpriseData — пример доработки правил конвертации без использования КД 3.0 в расширении конфигурации

EnterpriseData — пример доработки правил конвертации без использования КД 3.0 в расширении конфигурации

EnterpriseData — пример доработки правил конвертации без использования КД 3.0 в расширении конфигурации

В наличии

В статье подробно описан реальный пример доработки обмена данными через EnterpriseData (универсальный формат обмена) между конфигурациями УТ 11.4 и Бухгалтерия 3.0

Категория:

Описание

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

Вот я, например, привык работать с конвертацией данных 2.0. Мне потребовалось достаточно много времени, чтобы приспособиться к новому подходу, понять его суть. А пока я этого не сделал у меня возникало много сложностей с доработками типовых обменов, даже если доработки незначительны. 

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

 

Постановка задачи

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

Данные переносятся в бухгалтерию 3.0, где необходимо детализировать расчеты с банком на счете 57.3 по договорам (для каждого магазина необходимо использовать отдельный договор). Обмен данными между этими конфигурациями реализован через универсальный формат EnterpriseData.

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

Задача состоит в следующем:

  1. Необходимо, в конфигурации УТ 11.4, указывать по каждому эквайринговому терминалу отдельный договор с банком. Элемент справочника «Эквайринговые терминалы» выбирается в списке оплат платежными картами в документе «Отчет о розничных продажах».
  2. Необходимо корректно переносить указанные договоры в бухгалтерию 3.0.

 

Решение задачи

Для решения первой задачи необходимо создать новый реквизит с типом «Договор с контрагентом» в справочнике «Эквайринговые терминалы». Сделать это можно используя типовой механизм «Дополнительные реквизиты». Откроем список дополнительных реквизитов и добавим новый реквизит «Договор эквайринга» в предопределенную группу «Эквайринговые терминалы» с типом «Договор с контрагентом»:

Создание дополнительного реквизиты

Остальные изменения, касающиеся обмена данными, будем делать в расширениях конфигураций. 

Итак, приступим к решению задачи…

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

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

Версия формата плана обменаВ моем случае, используемая версия – 1.5.

 

Анализ формата данных XDTO

Перед выполнением доработки нам необходимо определить, какие объекты формата мы будем использовать для переноса необходимых нам данных. Открываем XDTO пакет формата требуемой версии в любой из конфигураций. Названия пакетов имеют следующий вид: EnterpriseData_[версия]_[релиз]. В моем случае: EnterpriseData_1_5_2.

Разворачиваем ветку «ТипыОбъектов» и ищем необходимый нам тип объекта «Документ.ОтчетОРозничныхПродажах». Нас будет интересовать реквизит объекта «ОплатаПлатежнымиКартами», который отвечает за перенос безналичных оплат:

Оплата платежными картами

Открываем его и смотрим его тип «ОплатаПлатежнымиКартами»:

Свойства оплаты ПК

Находим этот тип выше по списку и открываем его. Он содержит всего один реквизит «Строка», открываем его. Обращаем внимание на параметр «Максимальное количество», который равен -1. Это говорит о том, что реквизит является списком:

Свойства строки оплаты ПК

Смотрим его тип «ОплатаПлатежнымиКартами.Строка», и также ищем и открываем его в списке типов объектов:

Реквизиты оплаты ПК

Смотрим на доступные реквизиты типа, и видим, что среди них нет договора, есть только Эквайрер с типом «КлючевыеСвойстваКонтрагент» и «ЭквайринговыйТерминал». Ищем состав доступных реквизитов эквайрингового терминала (переходим к типу данного реквизита «КлючевыеСвойстваЭквайринговыеТерминалы» и находим его в списке типов):

Эквайринговый терминал, реквизиты

Видим, что среди доступных реквизитов также нет договора. Получается, что текущий формат EnterpriseData не имеет реквизитов для переноса договоров по эквайринговым операциям. Как же можно поступить в таком случае?

Один из вариантов решения — можно воспользоваться специальным реквизитом, который присутствует практически во всех типах объектов «Дополнительные реквизиты».

Возвращаемся обратно к описанию реквизитов документа  «Документ.ОтчетОРозничныхПродажах» и смотрим тип элемента «Дополнительные реквизиты». Тип одноименный, находим его в списке типов и открываем.

Дополнительные реквизиты также являются списком, о чем говорит единственный реквизит «Строка» с типом «ДополнительныеРеквизиты.Строка», и с максимальным количеством равным -1. Открываем тип «ДополнительныеРеквизиты.Строка»:

Дополнительные реквизиты

Для данного типа доступно два элемента:

  • Свойство — имеет тип «КлючевыеСвойстваДополнительныеРеквизиты». Находим тип «КлючевыеСвойстваДополнительныеРеквизиты». Он является ссылочным объектом с типом ссылки «СправочникСсылка.ДополнительныеРеквизиты». Данный объект формата обычно используется для переноса значений плана видов характеристик «ДополнительныеРеквизитыИСведения», для реализации переноса дополнительных реквизитов объектов, он нам подойдет:

Свойство дополнительныз реквизитов

  • ЗначениеСвойства — имеет определяемый тип, развернув который можно увидеть, из каких составляющих он состоит. Среди доступных типов видим договор, что нам и нужно:

Типы значения свойства дополнительных реквизитов

На данном этапе мы решили какими объектами формата будем пользоваться и проверили возможность их использования.

Дальше необходимо доработать алгоритмы выгрузки и загрузки данных используя выше описанные объекты.

 

Доработка алгоритма выгрузки данных через универсальный формат

Правила конвертации для обмена через универсальный формат находятся не в макете, как это было в конвертации 2.0, а в общем модуле «МенеджерОбменаЧерезУниверсальныйФормат». Для не значительных изменений можно не пользоваться Конвертацией данных 3.0, а внести все изменения непосредственно в данном модуле, что мы и будем делать.

Нас интересует обработчик «ПриОтправкиДанных» документа «Отчет о розничных продажах». Именно в этом обработчике можно добавить к выгружаемым данным «ДанныеXDTO» дополнительные элементы. Ищем данный обработчик в модуле менеджера по имени (структура написание имен имеет стандартный формат: «ПКО_Документ_ОтчетОРозничныхПродажах_Отправка_ПриОтправкеДанных».   

Как мы решили изначально, будем делать доработки в расширениях, так что добавляем новое расширение со следующими настройками:

Новое расширение конфигурации

Добавляем в расширение найденный обработчик с аннотацией: После (это означает, что написанный нами код будет выполняться после выполнения кода в основной конфигурации).

Дальнейшие действия разберем подробно, по шагам:

Проверяем, что табличная часть документа «Оплата платежными картами» имеет хотя бы одну строку (через параметр обработчика «ДанныеИБ» можно получить доступ к реквизитам выгружаемого документа):

Если ДанныеИБ.ОплатаПлатежнымиКартами.Количество() > 0 Тогда

…..

КонецЕсли

 

Создаем новую таблицу значений с колонками, аналогичными реквизитам типа XDTO: ДополнительныеРеквизиты, и создаем новую строку таблицы:

ДопРеквизиты = Новый ТаблицаЗначений;

ДопРеквизиты.Колонки.Добавить("Свойство");

ДопРеквизиты.Колонки.Добавить("ЗначениеСвойства");

СтрокаДопРеквизитов = ДопРеквизиты.Добавить();

 

Создаем новую структуру для описания элемента формата «Свойство», которое в формате имеет тип «КлючевыеСвойстваДополнительныеРеквизиты». Еще раз находим данный тип в описании формата и открываем свойства его реквизитов:

Свойство дополнительныз реквизитов

 

Значение параметра «Минимальное количество» равное 1 говорит о том, что это свойство является обязательным:

Наименование свойства доп. реквизитов

 

Проанализировав все три реквизита, делаем вывод, что обязательным является только один реквизит «Наименование», собственно, для решения нашей задачи он один нам и нужен. Однако, остальные два реквизита используются в алгоритмах выгрузки данных, и без них будут выдаваться ошибки при выполнении алгоритмов выгрузки данных. По этой причине нам придется добавить описание всех 3 реквизитов. Добавляем их с указанием пустых значений:

ДопСвойство = Новый Структура("Наименование, Ссылка, ЭтоДополнительноеСведение", "ДоговорЭквайринга", "", Ложь);

 

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

ДопСвойство_Инструция = Новый Структура("ИмяПКО, Значение", "Справочник_ДополнительныеРеквизиты", ДопСвойство);

 

Присваиваем созданную инструкцию элементу строки таблицы значений «Свойство»

СтрокаДопРеквизитов.Свойство = ДопСвойство_Инструция;

 

Получаем ссылку на терминал, обращаясь к документу, к его первой строке табличной части «Оплата платежными картами». Дальше перебираем дополнительные реквизиты терминала и получаем договор эквайринга. Если необходимого нам реквизита нет, прерываем выполнение процедуры:

Терминал = ДанныеИБ.ОплатаПлатежнымиКартами[0].ЭквайринговыйТерминал;

 

Договор = Неопределено;

Для каждого ДопРеквизит Из Терминал.ДополнительныеРеквизиты Цикл

                Если ДопРеквизит.Свойство.Заголовок = "Договор эквайринга" Тогда

                                 Договор = ДопРеквизит.Значение;

                КонецЕсли;

КонецЦикла;

Если НЕ ЗначениеЗаполнено(Договор) Тогда

               Возврат;

КонецЕсли;

Примечание: здесь сделано допущение, что оплаты в одном магазине могут приниматься только по одному терминалу, если терминалов используется больше, необходимо это учесть.

 

Создаем инструкцию для выгрузки договора. Используем правило «Справочник_ДоговорыКонтрагентов»:

ЗначениеСвойства_Инструкция = Новый Структура("Значение, ИмяПКО", Договор, "Справочник_ДоговорыКонтрагентов");

 

Присваиваем созданную инструкцию элементу строки таблицы значений «ЗначениеСвойства»:

СтрокаДопРеквизитов.ЗначениеСвойства = ЗначениеСвойства_Инструкция;

 

Вставляем таблицу значений с дополнительными реквизитами в структуру «ДанныеXDTO»

ДанныеXDTO.Вставить("ДополнительныеРеквизиты", ДопРеквизиты);

Ниже приведен код процедуры полностью:

&После("ПКО_Документ_ОтчетОРозничныхПродажах_Отправка_ПриОтправкеДанных")
Процедура ОД_ПКО_Документ_ОтчетОРозничныхПродажах_Отправка_ПриОтправкеДанных(ДанныеИБ, ДанныеXDTO, КомпонентыОбмена, СтекВыгрузки)

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

		Терминал = ДанныеИБ.ОплатаПлатежнымиКартами[0].ЭквайринговыйТерминал;
		Договор = Неопределено;
		
		Для каждого ДопРеквизит Из Терминал.ДополнительныеРеквизиты Цикл
			 Если ДопРеквизит.Свойство.Заголовок = "Договор эквайринга" Тогда
			 	  Договор = ДопРеквизит.Значение;
			 КонецЕсли;
		КонецЦикла;
		
		Если НЕ ЗначениеЗаполнено(Договор) Тогда
			Возврат;
		КонецЕсли;

		ЗначениеСвойства_Инструкция = Новый Структура("Значение, ИмяПКО", Договор, "Справочник_ДоговорыКонтрагентов");
		СтрокаДопРеквизитов.ЗначениеСвойства = ЗначениеСвойства_Инструкция;

		ДанныеXDTO.Вставить("ДополнительныеРеквизиты", ДопРеквизиты);

	КонецЕсли;
	
КонецПроцедуры

Делаем тестовую выгрузку одного документа и проверяем, как выглядит в файле выгрузки наш новый элемент. Открываем файл, он должен содержать следующие данные:

Выгрузка данных

 

Доработка алгоритма загрузки данных через универсальный формат

Открываем Бухгалтерию 3.0 и определяем, каким образом нам необходимо указывать договор для отображения корректных проводок по счету 57.3.

Договор, который заполняется в проводке, является реквизитом справочника «Виды оплат организаций». Вид оплаты, в свою очередь, является реквизитом табличной части «Вид оплаты», документа «Отчет о розничных продажах». Собственно, наша задача заключается в том, чтобы при загрузки данных выбрать (или создать новый) вид оплаты, с нужным нам договором.

Вид оплаты в документе заполняется уже после загрузки и обработки данных XDTO, так как он не имеет аналогов ни в конфигурации УТ 11.4, ни в описании формата. В файле с выгрузкой по нему нет никаких данных . Для подобных целей обычно используется обработчик объекта «ПередЗаписьюПолученныхДанных», его мы и будем смотреть. Но для начала нам нужно определиться с общем модулем, который содержит необходимые нам правила. 

Ищем модуль менеджера плана обмена через универсальный формат в списке общих модулей. Видим, что в конфигурации их два. Выбираем тот, который имеет приписку «13», так как используемый у нас формат обмена 1.5 больше, чем 1.3:

Менеджеры обмена через универсальный формат

Примечание: На самом деле, чтобы точно удостовериться, какой именно модуль необходимо использовать, нужно посмотреть процедуру «ПриПолученииНастроек», модуля менеджера плана обмена: Синхронизация данных через универсальный формат.

Добавляем новое расширение конфигурации.

Открываем нужный модуль менеджера и ищем по поиску необходимый нам обработчик «ПКО_Документ_ОтчетОРозничныхПродажах_ПередЗаписьюПолученныхДанных». В данном обработчике происходит до заполнение реквизитов полученных данных непосредственно перед записью этих данных в объект информационной базы. Обработчик имеет следующие ключевые параметры:

  • ПолученныеДанные – структура данных, которые будет записаны в новый или перезаписаны в существующий объект метаданных. Данные можно дополнить необходимой информацией.
  • ДанныеИБ – найденный объект информационной базы, в случае переноса нового объекта содержит «Неопределено».  

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

Нам необходимо с конвертировать значение договора самостоятельно. Для этого необходимо доработать обработчик «ПриКонвертацииДанныхXDTO», именно в нем можно получить доступ к принятым данным XDTO и до заполнить полученные данные, к которым также есть доступ в данном обработчике. Ищем обработчик в модуле менеджера через универсальный формат по имени «ПКО_Документ_ОтчетОРозничныхПродажах_ПриКонвертацииДанныхXDTO»

Добавляем обработчик в расширение с аннотацией «После».

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

Проверяем, что полученные данные XDTO содержат свойство «ДополнительныеРеквизиты», и содержат хотя бы один элемент: 

Если ДанныеXDTO.Свойство("ДополнительныеРеквизиты") И ДанныеXDTO.ДополнительныеРеквизиты.Количество()>0 Тогда

….

КонецЕсли;

Перебираем в цикле таблицу дополнительных реквизитов:

Для Каждого Строка Из ДанныеXDTO.ДополнительныеРеквизиты Цикл   

….

КонецЦикла;

Проверяем, что значение свойства дополнительного реквизита равно переданному нами значению «ДоговорЭквайринга»

Если Строка.Свойство.Наименование = "ДоговорЭквайринга" Тогда

….

КонецЕсли;

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

Создаем объект ПКО (Правило конвертации данных) по имени правила, используя стандартную процедуру модуля обмена данными XDTO:

ИмяПКО = "Справочник_ДоговорыКонтрагентов";

ПКОДоговор = ОбменДаннымиXDTOСервер.ПКОПоИмени(КомпонентыОбмена, ИмяПКО);

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

ДоговорЭквайринга = ОбменДаннымиXDTOСервер.СтруктураОбъектаXDTOВДанныеИБ(КомпонентыОбмена, Строка.ЗначениеСвойства, ПКОДоговор, "ПолучитьСсылку");

Добавляем сконвертированный договор в специальную структуру «ДополнительныеСвойства», которая является свойством параметра «Полученные данные»:

ПолученныеДанные.ДополнительныеСвойства.Вставить("ДоговорЭквайринга", ДоговорЭквайринга.Ссылка);

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

Ниже приведен код процедуры полностью:

&После("ПКО_Документ_ОтчетОРозничныхПродажах_ПриКонвертацииДанныхXDTO")
Процедура ОД_ПКО_Документ_ОтчетОРозничныхПродажах_ПриКонвертацииДанныхXDTO(ДанныеXDTO, ПолученныеДанные, КомпонентыОбмена)
	
	Если ДанныеXDTO.Свойство("ДополнительныеРеквизиты")
		И ДанныеXDTO.ДополнительныеРеквизиты.Количество()>0 Тогда
		
    	Для Каждого Строка Из ДанныеXDTO.ДополнительныеРеквизиты Цикл
			
			Если Строка.Свойство.Наименование = "ДоговорЭквайринга" Тогда
			
				ИмяПКО = "Справочник_ДоговорыКонтрагентов";
				ПКОДоговор = ОбменДаннымиXDTOСервер.ПКОПоИмени(КомпонентыОбмена, ИмяПКО);
				ДоговорЭквайринга = ОбменДаннымиXDTOСервер.СтруктураОбъектаXDTOВДанныеИБ(КомпонентыОбмена, Строка.ЗначениеСвойства,
				ПКОДоговор, "ПолучитьСсылку");
         		ПолученныеДанные.ДополнительныеСвойства.Вставить("ДоговорЭквайринга", ДоговорЭквайринга.Ссылка);
				Прервать;
				
			КонецЕсли;
		
		КонецЦикла;
		
	КонецЕсли;
	
КонецПроцедуры

Теперь возвращаемся к процедуре «ПКО_Документ_ОтчетОРозничныхПродажах_ПередЗаписьюПолученныхДанных», добавленной в расширение ранее, и вставляем в нее программный код. Необходимо обратиться к добавленному нами выше реквизиту дополнительных свойств «ДоговорЭквайринга» и присвоить его значение переменной «Договор». Доступ к дополнительным свойствам получаем через тот же параметр обработчика «ПолученныеДанные»:

Если ИмяТабличнойЧасти = "Оплата" И  ПолученныеДанные.ДополнительныеСвойства.Свойство("ДоговорЭквайринга") Тогда

       Договор = ПолученныеДанные.ДополнительныеСвойства.ДоговорЭквайринга;

КонецЕсли;

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

&Вместо("УстановитьВидОплатыВТабличнойЧасти")
Процедура ОД_УстановитьВидОплатыВТабличнойЧасти(КомпонентыОбмена, ПолученныеДанные, ИмяТабличнойЧасти)
	
	Если ЗначениеЗаполнено(ПолученныеДанные.Организация) И ПолученныеДанные[ИмяТабличнойЧасти].Количество() > 0 Тогда
		
		Для Каждого СтрокаТЧ ИЗ ПолученныеДанные[ИмяТабличнойЧасти] Цикл
		
			СтрокаТабличнойЧасти = ПолученныеДанные.ДополнительныеСвойства[ИмяТабличнойЧасти];
			СтрокаДопСвойств = СтрокаТабличнойЧасти[СтрокаТЧ.НомерСтроки - 1];
			
			ТипОплаты  = СтрокаДопСвойств.ТипОплаты;
			Контрагент = Справочники.Контрагенты.ПустаяСсылка();
		    Договор = Справочники.ДоговорыКонтрагентов.ПустаяСсылка();
			
			Если СтрокаДопСвойств.Свойство("Контрагент") Тогда
				Контрагент = СтрокаДопСвойств.Контрагент;
			КонецЕсли;
			
			Если СтрокаДопСвойств.Свойство("ДоговорКонтрагента") Тогда
				Договор = СтрокаДопСвойств.ДоговорКонтрагента;
			КонецЕсли;
			
			Если ИмяТабличнойЧасти = "Оплата" 
				И ПолученныеДанные.ДополнительныеСвойства.Свойство("ДоговорЭквайринга") Тогда
				
				Договор = ПолученныеДанные.ДополнительныеСвойства.ДоговорЭквайринга;
				
			КонецЕсли;				
			
			СтрокаТЧ.ВидОплаты = ВидОплатыОрганизации(
				КомпонентыОбмена,
				ПолученныеДанные.Организация,
				ТипОплаты,
				Контрагент,
				Договор);
		КонецЦикла;
		
	КонецЕсли;

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

На этом все, можно загружать данные, и проверять работу выполненных изменений.

Надеюсь, рассмотренный мной пример поможет в решении подобных задач по доработке механизмов переноса данных через универсальный формат.

Если статья Вам понравилась и оказалось полезной, ставьте звездочку J

 

Другие мои статьи из серии «Новый подход к обмену данными»

  1. Теоретическая, вводная статья по EnterpriseData
  2. EnterpriseData — часть 2. Процесс выгрузки данных, обработчики выгрузки.

 

has been added to your cart:
Оформление заказа