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

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

Во время обновления Бухгалтерии 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 надо добавить поле УстановленОсновным равное Истина, вне зависимости от того является договор основным или нет. Этого требует функция ЗагрузкаВыпискиПоБанковскомуСчету.НайтиДоговорПоВидуОперации. См. также функцию ИдентификацияУчастниковБанковскихОпераций.СведенияОбОбъектеИнформационнойБазы на предмет списка полей выборки запроса поиска объектов.

5 Comments

  1. le_

    Помогло допилить поиск под свои нужны. Thanks!

    Reply
  2. sovetnik101

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

    Reply
  3. xrrg

    (2)

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

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

    Reply
  4. djerry

    Автор, а подскажи пожалуйста по поводу признака платежа от физ.лица или юр.лица. Как их различить? Свои мысли?

    На данный момент я использую:

    — TXID — юр.лицо + ИП;

    — PNNM — физ.

    Может быть есть более надежный способ?

    Reply
  5. xrrg

    (4)

    Не могу прокомментировать. К счастью или сожалению, я к этой теме с тех времен не возвращался. Многое могло измениться. Помню, что заполнение полей платежки разнится от банка к банку. В моем случае проблема была в том, что в качестве контрагента в платежке указывался сам банк.

    Reply

Leave a Comment

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