gifts2017

Добавление новой схемы поиска участника банковской операции в Клиенте-банке

Опубликовал Денис (xrrg) в раздел Программирование - Практика программирования

Как подменить поиск контрагента при загрузке выписки из Клиент-банка

Во время обновления Бухгалтерии 3.0 КОРП с 3.0.40.24 до 3.0.43.155 неожиданно выяснилось, что перенести старый функционал поиска контрагента и договора не представляется возможным. Доработка заключалась в поиске в назначении платежа номера счета на оплату или номера договора с последующим заполнением соответствующих реквизитов обработки.

Долго ли, коротко ли, было найдено место в процедуре общего модуля ЗагрузкаВыпискиПоБанковскомуСчету.ЗаполнитьИдентификаторыУчастниковОперацийПоДаннымИзБанка

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

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

Если Сторона = "Плательщик" И УчастникиОпераций.ИспользоватьПоискКлиентаПоНазначениюПлатежа Тогда
				
	Позиция = СтрНайти(Документ.НазначениеПлатежа, "ЪЪ"); // интеллектуальный поиск
				
	Если Позиция > 0 Тогда
	
		НомерСчетаНаОплату = Врег(Сред(Документ.НазначениеПлатежа, Позиция, 9));
		
		Идентификатор = ИдентификацияУчастниковБанковскихОпераций.ИдентификаторПоНомеруСчетаНаОплатуИлиДоговору(УчастникиОпераций, НомерСчетаНаОплату);
		
		Если Идентификатор <> Неопределено Тогда
			ИдентификаторыУчастника.Добавить(Идентификатор);
		КонецЕсли;

	КонецЕсли;

КонецЕсли;

Схема - это упрощенно некий входящий параметр-идентификатор и процедура с запросом, в котором будет осуществлен поиск ссылки по этому идентификатору. Сначала добавляем идентификатор, потом выполняется поиск. Точка входа - функция ЗагрузкаВыпискиПоБанковскомуСчету.РаспознанныеДанныеИзБанка, в ней выполняется добавление идентификатора (вышеприведенная процедура) и поиск объекта ИБ по этому идентифкатору (об этом ниже).

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

Функция ИдентификаторПоНомеруСчетаНаОплатуИлиДоговору(УчастникиОпераций, Номер) Экспорт
	
	Состав = Новый Структура;
	Состав.Вставить("Номер", Номер);
	
	Точный = Истина;
	БазовыйИдентификатор = "";
	
	Возврат УстановитьИдентификатор(УчастникиОпераций, "INSR", Номер, Состав, Точный, БазовыйИдентификатор);
	
КонецФункции

Замечу, что это упрощенный вариант поиска. В рабочем варианте выполняется также поиск договоров, и идентификатор может быть также номером договора. Соответственно, чтобы различать какой это номер - договора или счета на оплату - нужен некий флаг, который надо добавить в Состав.

А теперь то, что надо сделать, чтобы сработал поиск по новому идентификатору в общем модуле ИдентификацияУчастниковБанковскихОпераций

Функция СхемыИдентифицирующиеТип(Тип)
	
	// Схемы упорядочены по убыванию надежности для каждого типа данных.
	// Так, если известны TXID и BBAN, при этом по TXID найден один контрагент, а по BBAN - другой, то следует предпочесть первого.
	
	Схемы = Новый Массив;
	Схемы.Добавить("UUID"); // позволяет идентифицировать любой тип
	Если Тип = Тип("СправочникСсылка.Организации") Тогда
		Схемы.Добавить("TXID");
		Схемы.Добавить("BBAN");
	ИначеЕсли Тип = Тип("СправочникСсылка.Контрагенты") Или Тип = Тип("СправочникСсылка.ДоговорыКонтрагентов") Тогда
		Схемы.Добавить("INSR"); // ВСТАВЛЯЕМ СХЕМУ ПЕРВОЙ, СЧИТАЕМ ЕЕ САМОЙ ЛУЧШЕЙ
		Схемы.Добавить("TXID");
		Схемы.Добавить("TXZN");
		Схемы.Добавить("IBAN");
		Схемы.Добавить("BBAN");// см. СхемаПрименяетсяОграниченно()
		Схемы.Добавить("BKNM");
	ИначеЕсли Тип = Тип("СправочникСсылка.БанковскиеСчета") Тогда
		Схемы.Добавить("BBAN");
		Схемы.Добавить("IBAN");
	ИначеЕсли Тип = Тип("СправочникСсылка.ФизическиеЛица") Тогда
		Схемы.Добавить("TXID");
		Схемы.Добавить("BBAN");// см. СхемаПрименяетсяОграниченно()
		Схемы.Добавить("IBAN");
	КонецЕсли;
	
	Возврат Схемы;
	
КонецФункции

Важно вставить схему первой в списке (на самом деле она будет второй, но схема UUID я не заметил чтобы использовалась). В противном случае сработает, например, TXID и вместо нашего клиента мы получим банк, через который он платил. В свою очередь для клиента-физлица должна использоваться также схема поиска по наименованию (ИНН и адресу) PNNM, которой вообще нет в списке, то есть она или не используется (?), или в моей выписке в наименовании плательщика не было ИНН, что нынешний типовой алгоритм не учитывает.

В функции ОписаниеИдентификатораПоСхеме вставим отметку о своей схеме в конец оператора Если (я даже уже забыл, зачем именно это место надо править, но точно надо).

...
ИначеЕсли Схема = "INSR" Тогда 
	Идентификатор = ИдентификаторПоНомеруСчетаНаОплатуИлиДоговору(УчастникиОпераций, СведенияОбОбъектеИнформационнойБазы.Номер);
Иначе
...

Добавляем свою схему в общий список схем

Функция ОписаниеМетодовПоиска()
	
	МетодыПоиска = Новый Массив;
	МетодыПоиска.Добавить(ОписаниеМетодаПоискаBBAN());
	МетодыПоиска.Добавить(ОписаниеМетодаПоискаIBAN());
	МетодыПоиска.Добавить(ОписаниеМетодаПоискаTXID());
	МетодыПоиска.Добавить(ОписаниеМетодаПоискаBKNM());
	МетодыПоиска.Добавить(ОписаниеМетодаПоискаTXZN());
	МетодыПоиска.Добавить(ОписаниеМетодаПоискаINSR()); // здесь порядок непринципиален
	
	Возврат МетодыПоиска;
	
КонецФункции

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

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

Разницы между полями Ссылка и Владелец я не увидел: совершенно без разницы, куда Вы поместите Контрагента, а куда Договор. А вот реквзиты контрагента важны, т.к. далее к ним есть обращения. Ссылка и Владелец добавляются в список ссылок - каждый для своего типа объектов -  с указанием схемы, по которой был произведен поиск.

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

Если ОписаниеИдентификатора.Схема = "INSR" Тогда
	Продолжить;
КонецЕсли;

Т.к. наша схема первая в списке поиска, предполагается, что договор и контрагента мы нашли, то в Клиент-банке мы увидим именно их. Если же не выполнить последнее действие, то договор будет последним при сортировке "по ссылке". И это необязательно договор из счета на оплату.

За рамками статьи осталась такая вещь, как Мера соответствия идентификатора, но т.к. моя схема точная, я этим не стал озадачиваться.

UPD Обнаружено, что в запросе поиска объектов функции ОписаниеМетодаПоискаINSR надо добавить поле УстановленОсновным равное Истина, вне зависимости от того является договор основным или нет. Этого требует функция ЗагрузкаВыпискиПоБанковскомуСчету.НайтиДоговорПоВидуОперации. См. также функцию ИдентификацияУчастниковБанковскихОпераций.СведенияОбОбъектеИнформационнойБазы на предмет списка полей выборки запроса поиска объектов.

См. также

Подписаться Добавить вознаграждение
В этой теме еще нет сообщений.