Доработка выгрузки поступления на счет по платежным картам при обмене из УНФ в БП

При выгрузке из УНФ в БП поступления на счет с видом операции «Отчет эквайера» в БП не переносится договор и патент.

Анализ XML файла выгрузки

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

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

Выгрузка документа показала, что он выгружается по правилу Документ.ПБДСПоПлатежнымКартам и в этом документе нет договора и патента.

Выгрузка осуществляется по формату ED 1.17:

<msg:Format>http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.17</msg:Format>

Поиск места для передачи дополнительной информации

Посмотрим пакет EnterpriseData_1_17_3 в общих пакетах XDTO:

По расшифровка платежа смотрим тип: Документ.ПБДСПоПлатежнымКартам.РасшифровкаПлатежа.Строка с полями:

Как видим, патента тут нет.

В другом правиле Документ.ПБДСРасчетыСКонтрагентами расшифровка ссылается на тип РасшифровкаПлатежа. Тут патент есть. Но его забыли прописать в наш тип, увы.

Типовая передача договора содержит ошибки

В процедуре ДобавитьПКО_Документ_ПБДСПоПлатежнымКартам_Отправка видно, что договор присутствует в табличной части расшифровки платежа:

Процедура ДобавитьПКО_Документ_ПБДСПоПлатежнымКартам_Отправка(ПравилаКонвертации)
	ПравилоКонвертации = ОбменДаннымиXDTOСервер.ИнициализироватьПравилоКонвертацииОбъекта(ПравилаКонвертации);
	ПравилоКонвертации.ИмяПКО            = "Документ_ПБДСПоПлатежнымКартам_Отправка";
	ПравилоКонвертации.ОбъектДанных      = Метаданные.Документы.ПоступлениеНаСчет;
	ПравилоКонвертации.ОбъектФормата     = "Документ.ПБДСПоПлатежнымКартам";
	ПравилоКонвертации.ПриОтправкеДанных = "ПКО_Документ_ПБДСПоПлатежнымКартам_Отправка_ПриОтправкеДанных";
	СвойстваШапки = ПравилоКонвертации.Свойства;
	ДобавитьПКС(СвойстваШапки, "БанковскийСчет",          "БанковскийСчетОрганизации", , "Справочник_БанковскиеСчета_Отправка");
	ДобавитьПКС(СвойстваШапки, "ВалютаДенежныхСредств",   "Валюта", , "Справочник_Валюты");
	ДобавитьПКС(СвойстваШапки, "Дата",                    "Дата");
	ДобавитьПКС(СвойстваШапки, "Дата",                    "ДатаВыписки");
	ДобавитьПКС(СвойстваШапки, "ДатаВходящегоДокумента",  "ДатаВходящегоДокумента");
	ДобавитьПКС(СвойстваШапки, "Комментарий",             "Комментарий");
	ДобавитьПКС(СвойстваШапки, "Контрагент",              "Контрагент", , "Справочник_Контрагенты_Отправка");
	ДобавитьПКС(СвойстваШапки, "НазначениеПлатежа",       "НазначениеПлатежа", 1);
	ДобавитьПКС(СвойстваШапки, "Номер",                   "Номер");
	ДобавитьПКС(СвойстваШапки, "НомерВходящегоДокумента", "НомерВходящегоДокумента");
	ДобавитьПКС(СвойстваШапки, "Организация",             "Организация", , "Справочник_Организации_Отправка");
	ДобавитьПКС(СвойстваШапки, "СуммаДокумента",          "Сумма");
	ДобавитьПКС(СвойстваШапки, "СуммаКомиссииДокумента",  "СуммаКомиссияБанка");
	ДобавитьПКС(СвойстваШапки, "СуммаКомиссииДокумента",  "СуммаУслуг");
	ДобавитьПКС(СвойстваШапки, "СчетКонтрагента",         "БанковскийСчетКонтрагента", , "Справочник_БанковскиеСчета_Отправка");
	
	СвойстваТЧ = ДобавитьПКТЧ(ПравилоКонвертации, "", "РасшифровкаПлатежа");
	ДобавитьПКС(СвойстваТЧ, "", "ВалютаВзаиморасчетов", 1, "Справочник_Валюты");
	ДобавитьПКС(СвойстваТЧ, "", "Договор", 1);
	ДобавитьПКС(СвойстваТЧ, "", "КратностьВзаиморасчетов", 1);
	ДобавитьПКС(СвойстваТЧ, "", "КурсВзаиморасчетов", 1);
	ДобавитьПКС(СвойстваТЧ, "", "СтавкаНДС", 1);
	ДобавитьПКС(СвойстваТЧ, "", "СтатьяДДС", 1, "Справочник_СтатьиДДС");
	ДобавитьПКС(СвойстваТЧ, "", "Сумма", 1);
	ДобавитьПКС(СвойстваТЧ, "", "СуммаВзаиморасчетов", 1);
	ДобавитьПКС(СвойстваТЧ, "", "СуммаНДС", 1);

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

Однако выгрузка договора очень странная в процедуре ПКО_Документ_ПБДСПоПлатежнымКартам_Отправка_ПриОтправкеДанных.

Сначала мы получаем договор запросе из поля договора эквайрингового терминала:

Но затем полученный договор игнорируется и зачем-то берется основной договор эквайринга:

А ведь основной договор может быть только один. А у нас выгрузка по разным договорам, в зависимости от терминала. Да, договор может быть один, но банки позволяют иметь и разные договора по разным терминалам.

Увы, отладка показала, что какой-то основной договор эквайринга все же находится, но почему-то не выгружается. Значит и наш договор не выгрузится. Почему?

В процедуре ВыгрузитьСвойство отлаживаем код с условной точкой останова с кодом:

ПКС.СвойствоФормата = "Договор"

Тут: ПравилоКонвертацииСвойства = «Справочник_ДоговорыКонтрагентов_Отправка«.

ЗначениеСвойства заполняется. Тут все отрабатывает хорошо.

Далее смотрим точку останова в процедуре ОбъектXDTOИзДанныхXDTO с условием останова:
Строка(ТипXDTO) = «{http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.17}Документ.ПБДСПоПлатежнымКартам» :

И далее в цикле по свойствам точку останова с условием: Строка(ТипXDTO) = «{http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.17}Документ.ПБДСПоПлатежнымКартам» и Свойство.Имя = «ДоговорКонтрагента»

Находим что нам нужна точка останова:

Строка(ТипXDTO) = «{http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.17}Документ.ПБДСПоПлатежнымКартам.РасшифровкаПлатежа.Строка»

И тут становится понятна причина ошибки. В XDTO договор контрагента предполагается в шапке, а 1с его выгружает в табличную часть.

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

Причина было в том, что я не добавил правило конвертации поля ДоговорКонтрагента в шапке.

После этого все заработало, я увидел уже в файле обмена договор и в загрузке в БП:

UPD: Ошибка в передаче договора

Я так обрадовался, что договор стал попадать в файл выгрузки, что просто забыл проверить, а проставлятеся он в БП или нет. Думал, подхватится. Но нет, БП то ожидает договор в таблице, а не в шапке.

Пришлось дорабатывать БП:

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

	
	ПродолжитьВызов(ДанныеXDTO, ПолученныеДанные, КомпонентыОбмена);   

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

Тут вставить надо именно вначале, перед вызовом процедуры, т.к. код анализирует, есть ли в расшифровке договор.

Неправильный поиск способа передачи патента

Я попытался добавлять патент отдельно в ОбщиеСвойстваОбъектовФормата:

В поле ОбщиеДанные типа ОбщиеСвойстваПБДС добавить ничего своего не получится:

Тут не нашел в формате ED нет возможности передавать по документам свою произвольную информацию. Но потом в отладчике увидел в объектах поле AdditionalInfo, погулил и нашел способ передачи через это поле.

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

Правильный способ передача патента через AdditionalInfo

Передавать патент буду в AdditionalInfo, как описано в статье. Я уже сам ранее использовал такой метод в одной из доработок обмена с мобильной кассой.

Данные можно передавать в виде структуры.

Простой код добавляет структуру:

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

	ДанныеXDTO.Вставить("AdditionalInfo", Новый Структура("тест", ""));

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

В файле обмена она выглядит так:

Непосредственно передача патента

Теперь осталось реализовать это в рабочей схеме для передачи патента.

Дорабатываем код выгрузки:


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

	Если СтекВыгрузки.Количество() > 1 Тогда
		Возврат;
	КонецЕсли;	

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

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

Процедура доуф_ДобавитьДополнительныеДанные(
	ДанныеXDTO, Имя, ДопЗначение) Экспорт
	//https://almaz-sharipov.ru/article/1c-develop/conversionAdditionalInfo	
	
	
	Если ДанныеXDTO.Свойство("AdditionalInfo") 
		И ТипЗнч(ДанныеXDTO.AdditionalInfo)=Тип("Структура") Тогда
		ДопДанные = ДанныеXDTO.AdditionalInfo;
	Иначе
		ДопДанные = Новый Структура;
	КонецЕсли;
	
	ДопДанные.Вставить(Имя, ДопЗначение);
	ДанныеXDTO.Вставить("AdditionalInfo", ДопДанные);	
КонецПроцедуры

В файле обмена дополнительные свойства выглядят так:

<Документ.ПБДСПоПлатежнымКартам>
			<msg:AdditionalInfo xmlns:d4p1="http://v8.1c.ru/8.1/data/core" xsi:type="d4p1:Structure">
				<d4p1:Property name="ПатентНомер">
					<d4p1:Value xsi:type="xs:string">NNNNNNNNNN</d4p1:Value>
				</d4p1:Property>
				<d4p1:Property name="ПатентДатаНачала">
					<d4p1:Value xsi:type="xs:dateTime">2024-03-04T00:00:00</d4p1:Value>
				</d4p1:Property>
			</msg:AdditionalInfo>
			<КлючевыеСвойства>
			...
			</КлючевыеСвойства>
</Документ.ПБДСПоПлатежнымКартам>			

При загрузке нужно учитывать, что патент очищается в этой процедуре:

Поэтому код загрузки надо доработать в нескольких местах. Модуль МенеджерОбменаЧерезУниверсальныйФормат13:


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

	//Загружаем патенты
    Если ДанныеXDTO.Свойство("AdditionalInfo") И ТипЗнч(ДанныеXDTO.AdditionalInfo)=Тип("Структура") Тогда
        
        ДопДанные = ДанныеXDTO.AdditionalInfo;
        
        Если ДопДанные.Свойство("ПатентНомер") И ДопДанные.Свойство("ПатентДатаНачала")  Тогда
            
            ПатентНомер = ДопДанные.ПатентНомер; 
            ПатентДатаНачала = ДопДанные.ПатентДатаНачала; 
			
			//Ищем и заполняем патент                                                       
			ИскПатент = доуф_НайтиПатент(ПатентНомер, ПатентДатаНачала);      
            ПолученныеДанные.Патент = ИскПатент;
			ПолученныеДанные.ОтражениеВУСН = Перечисления.ОтражениеВУСН.НеПринимаются;  
			//Этот код не работает, расшифровки платежа еще нет
			//Для Каждого Строка ИЗ ПолученныеДанные.РасшифровкаПлатежа Цикл
			//	Строка.ПорядокОтраженияАванса = ИскПатент; 
			//КонецЦикла;
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры


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

&Вместо("ОтложеннаяОбработка_ПоступлениеДенежныхСредств")
Процедура доуф_ОтложеннаяОбработка_ПоступлениеДенежныхСредств(Объект)

	ПредПатент = Объект.Патент; 

	ПродолжитьВызов(Объект);

	//Восстанавливаем патент, сброшенный отложенной обработкой
	Если ЗначениеЗаполнено(ПредПатент) Тогда      
		Объект.Патент = ПредПатент;
		Для Каждого Строка ИЗ Объект.РасшифровкаПлатежа Цикл
			Строка.ПорядокОтраженияАванса = ПредПатент; 
		КонецЦикла;
	КонецЕсли;
	
КонецПроцедуры

Модуль ОбменДаннымиXDTOСервер:

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

Проверяем — патент передается успешно! Нюанс — патент не создается при обмене, это надо иметь ввиду.

Среда: УНФ 3.0.9.163, БП 3.0.161.22 Объем: 5 час.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

1 комментарий

  1. 07.11.2024

    […] уже писал ранее про обмен из УНФ 3.0 в БП3 по поступлениям из банка по […]

Добавить комментарий

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