Сервис DaData.ru предоставляет возможность получать данные по контрагентам, банкам и контекстную подсказку для более быстрого и точного заполнения реквизитов. Сервис является бесплатным (до 10 000 запросов в день). Для работы потребуется API ключ, получить его можно на сайте dadata.ru.
В файле содержится конфигурация с обработкой, код которой приведен ниже.
Обработка имеет несколько экспортных функций, которые:
- Находит компанию или ИП по ИНН или ОГРН;
- Ищет компании и индивидуальных предпринимателей по названию (полному и краткому), по ИНН, ОГРН и КПП;
- Ищет адреса по любой части адреса от региона до квартиры («самара авроры 7 12» → «443017, Самарская обл, г Самара, ул Авроры, д 7, кв 12»). Также ищет по почтовому индексу («105568» → «г Москва, ул Магнитогорская»).
- Находит банк по любому из идентификаторов: БИК, SWIFT, ИНН;
- Ищет кредитные организации по названию и другим идентификаторам;
- Подсказывает ФИО одной строкой или отдельно фамилию, имя, отчество;
- Подсказывает при вводе email локальную часть (до «собачки»), подсказывает доменную часть (после «собачки»), исправляет опечатки (yadex.ru → yandex.ru).
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
// Функция - Сведения о юридическом лице по ИНН
//
// Параметры:
// СтрокаПоиска - Строка - Строка поиска
//
// Структура:
// * ОписаниеОшибки - Строка - содержит текст ошибки, возникшей при получении данных.
// * suggestions - Массив - массив структур хранящих найденные сведения. Описание свойств можно найти на https://dadata.ru/api/find-party/
//
Функция СведенияОЮридическомЛицеПоИНН(СтрокаПоиска) Экспорт
СведенияОЮридическомЛице = Новый Структура("ОписаниеОшибки,suggestions");
Если ПустаяСтрока(КлючAPI()) Тогда
СведенияОЮридическомЛице.ОписаниеОшибки = "Нет действующих настроек для работы с сервисом!";
Возврат СведенияОЮридическомЛице;
КонецЕсли;
Результат = ВыполнитьЗапросДанных(СтрокаПоиска, "/suggestions/api/4_1/rs/findById/party");
ПрочитатьРезультатЗапросаДанных(СведенияОЮридическомЛице, Результат);
УдалитьЮрЛицБезКПП(СведенияОЮридическомЛице);
ПреобразоватьАдресИСтатусы(СведенияОЮридическомЛице);
Возврат СведенияОЮридическомЛице;
КонецФункции
// Функция - Подсказка по организациям
//
// Параметры:
// СтрокаПоиска - Строка - Строка поиска
//
// Структура:
// * ОписаниеОшибки - Строка - содержит текст ошибки, возникшей при получении данных.
// * suggestions - Массив - массив структур хранящих найденные сведения. Описание свойств можно найти на https://dadata.ru/api/suggest/party/
//
Функция ПодсказкаПоОрганизациям(СтрокаПоиска) Экспорт
ПодсказкаПоОрганизациям = Новый Структура("ОписаниеОшибки,suggestions");
Если ПустаяСтрока(КлючAPI()) Тогда
ПодсказкаПоОрганизациям.ОписаниеОшибки = "Нет действующих настроек для работы с сервисом!";
Возврат ПодсказкаПоОрганизациям;
КонецЕсли;
Результат = ВыполнитьЗапросДанных(СтрокаПоиска, "/suggestions/api/4_1/rs/suggest/party");
ПрочитатьРезультатЗапросаДанных(ПодсказкаПоОрганизациям, Результат);
Возврат ПодсказкаПоОрганизациям;
КонецФункции
// Функция - Банк по идентификатору
//
// Параметры:
// СтрокаПоиска - Строка - Строка поиска
//
// Структура:
// * ОписаниеОшибки - Строка - содержит текст ошибки, возникшей при получении данных.
// * suggestions - Массив - массив структур хранящих найденные сведения. Описание свойств можно найти на https://dadata.ru/api/find-bank/
//
Функция БанкПоИдентификатору(СтрокаПоиска) Экспорт
БанкПоИдентификатору = Новый Структура("ОписаниеОшибки,suggestions");
Если ПустаяСтрока(КлючAPI()) Тогда
БанкПоИдентификатору.ОписаниеОшибки = "Нет действующих настроек для работы с сервисом!";
Возврат БанкПоИдентификатору;
КонецЕсли;
Результат = ВыполнитьЗапросДанных(СтрокаПоиска, "/suggestions/api/4_1/rs/findById/bank");
ПрочитатьРезультатЗапросаДанных(БанкПоИдентификатору, Результат);
Возврат БанкПоИдентификатору;
КонецФункции
// Функция - Подсказка по банкам
//
// Параметры:
// СтрокаПоиска - Строка - Строка поиска
//
// Структура:
// * ОписаниеОшибки - Строка - содержит текст ошибки, возникшей при получении данных.
// * suggestions - Массив - массив структур хранящих найденные сведения. Описание свойств можно найти на https://dadata.ru/api/suggest/bank/
//
Функция ПодсказкаПоБанкам(СтрокаПоиска) Экспорт
ПодсказкаПоБанкам = Новый Структура("ОписаниеОшибки,suggestions");
Если ПустаяСтрока(КлючAPI()) Тогда
ПодсказкаПоБанкам.ОписаниеОшибки = "Нет действующих настроек для работы с сервисом!";
Возврат ПодсказкаПоБанкам;
КонецЕсли;
Результат = ВыполнитьЗапросДанных(СтрокаПоиска, "/suggestions/api/4_1/rs/suggest/bank");
ПрочитатьРезультатЗапросаДанных(ПодсказкаПоБанкам, Результат);
Возврат ПодсказкаПоБанкам;
КонецФункции
// Функция - Подсказка по ФИО
//
// Параметры:
// СтрокаПоиска - Строка - Строка поиска
//
// Структура:
// * ОписаниеОшибки - Строка - содержит текст ошибки, возникшей при получении данных.
// * suggestions - Массив - массив структур хранящих найденные сведения. Описание свойств можно найти на https://dadata.ru/api/suggest/name/
//
Функция ПодсказкаПоФИО(СтрокаПоиска) Экспорт
ПодсказкаПоФИО = Новый Структура("ОписаниеОшибки,suggestions");
Если ПустаяСтрока(КлючAPI()) Тогда
ПодсказкаПоФИО.ОписаниеОшибки = "Нет действующих настроек для работы с сервисом!";
Возврат ПодсказкаПоФИО;
КонецЕсли;
Результат = ВыполнитьЗапросДанных(СтрокаПоиска, "/suggestions/api/4_1/rs/suggest/fio");
ПрочитатьРезультатЗапросаДанных(ПодсказкаПоФИО, Результат);
Возврат ПодсказкаПоФИО;
КонецФункции
// Функция - Подсказка по email
//
// Параметры:
// СтрокаПоиска - Строка - Строка поиска
//
// Структура:
// * ОписаниеОшибки - Строка - содержит текст ошибки, возникшей при получении данных.
// * suggestions - Массив - массив структур хранящих найденные сведения. Описание свойств можно найти на https://dadata.ru/api/suggest/email/
//
Функция ПодсказкаПоEmail(СтрокаПоиска) Экспорт
ПодсказкаПоEmail = Новый Структура("ОписаниеОшибки,suggestions");
Если ПустаяСтрока(КлючAPI()) Тогда
ПодсказкаПоEmail.ОписаниеОшибки = "Нет действующих настроек для работы с сервисом!";
Возврат ПодсказкаПоEmail;
КонецЕсли;
Результат = ВыполнитьЗапросДанных(СтрокаПоиска, "/suggestions/api/4_1/rs/suggest/email");
ПрочитатьРезультатЗапросаДанных(ПодсказкаПоEmail, Результат);
Возврат ПодсказкаПоEmail;
КонецФункции
// Функция - Подсказка по адресам
//
// Параметры:
// СтрокаПоиска - Строка - Строка поиска
//
// Структура:
// * ОписаниеОшибки - Строка - содержит текст ошибки, возникшей при получении данных.
// * suggestions - Массив - массив структур хранящих найденные сведения. Описание свойств можно найти на https://dadata.ru/api/suggest/address/
//
Функция ПодсказкаПоАдресам(СтрокаПоиска) Экспорт
ПодсказкаПоАдресам = Новый Структура("ОписаниеОшибки,suggestions");
Если ПустаяСтрока(КлючAPI()) Тогда
ПодсказкаПоАдресам.ОписаниеОшибки = "Нет действующих настроек для работы с сервисом!";
Возврат ПодсказкаПоАдресам;
КонецЕсли;
Результат = ВыполнитьЗапросДанных(СтрокаПоиска, "/suggestions/api/4_1/rs/suggest/address");
ПрочитатьРезультатЗапросаДанных(ПодсказкаПоАдресам, Результат);
Возврат ПодсказкаПоАдресам;
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ВыполнитьЗапросДанных(СтрокаПоиска, Метод)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Новый Структура("query", СтрокаПоиска));
Тело = ЗаписьJSON.Закрыть();
Сервер = "suggestions.dadata.ru";
Порт = 443;
Таймаут = 30;
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
Возврат ВыполнитьPOSTЗапрос(Сервер, Порт, Метод, Таймаут, Тело, ЗащищенноеСоединение);
КонецФункции
Функция ВыполнитьPOSTЗапрос(Сервер, Порт, Адрес, Таймаут, Тело, ЗащищенноеСоединение)
Соединение = Новый HTTPСоединение(Сервер,Порт,,,,Таймаут, ЗащищенноеСоединение);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-type", "application/json");
Заголовки.Вставить("Accept", "application/json");
Заголовки.Вставить("Authorization", "Token " + КлючAPI());
Запрос = Новый HTTPЗапрос(Адрес, Заголовки);
Запрос.УстановитьТелоИзСтроки(Тело);
СтруктураДанных = Новый Структура("КодСостояния,Тело");
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
СтруктураДанных.КодСостояния = Ответ.КодСостояния;
СтруктураДанных.Тело = Ответ.ПолучитьТелоКакСтроку();
Возврат СтруктураДанных;
Исключение
//ToDo: Заменить на другой код, более точный для таких исключений
СтруктураДанных.КодСостояния = 500;
Возврат СтруктураДанных;
КонецПопытки;
КонецФункции
Функция ДесериализоватьСтруктуруОтвета(Тело)
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Тело);
Возврат ПрочитатьJSON(ЧтениеJSON, Ложь).suggestions;
КонецФункции // ДесериализоватьСтруктуруОтвета()
Функция КлючAPI()
КлючОбъекта = "DaData.ru";
КлючНастроек = "DaDataAPI";
ОписаниеНастроек = "API ключ для сервиса DaData.ru";
Пользователь = "Общие";
СтруктураНастроек = Неопределено;
СтруктураНастроек = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, КлючНастроек, ОписаниеНастроек, Пользователь);
Если ЗначениеЗаполнено(СтруктураНастроек) Тогда
Возврат СтруктураНастроек.КлючAPI;
Иначе
Возврат "";
КонецЕсли;
КонецФункции
Процедура ПреобразоватьАдресИСтатусы(СтруктураОтвет)
Для каждого suggestion Из СтруктураОтвет.suggestions Цикл
Сведения = suggestion.data;
Статусы = Новый Соответствие;
Статусы.Вставить("LIQUIDATING", "в стадии ликвидации");
Статусы.Вставить("LIQUIDATED", "ЛИКВИДИРОВАН");
Статусы.Вставить("BANKRUPT", "БАНКРОТ");
Статусы.Вставить("REORGANIZING", "В СТАДИИ РЕОРГАНИЗАЦИИ");
Статусы.Вставить("ACTIVE", "действующий");
Сведения.state.status = Статусы[Сведения.state.status];
Если Сведения.type = "LEGAL" Тогда
Сведения.name.full = ПреобразоватьНаименование(Сведения.name.full);
Сведения.name.short_with_opf = ПреобразоватьНаименование(Сведения.name.short_with_opf);
Сведения.name.full_with_opf = ПреобразоватьНаименование(Сведения.name.full_with_opf);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПреобразоватьНаименование(Наименованиекомпании)
ОПФ = "ПАОЗАООООНКООПАОИП";
СокращенияГородов = СокращенияГородов();
Слова = СтрРазделить(Наименованиекомпании, " ", Ложь);
Результат = Новый Массив;
Для Каждого Слово Из Слова Цикл
Если СтрНайти(ОПФ, Слово) > 0 Тогда
Результат.Добавить(Слово);
Продолжить;
КонецЕсли;
Если СтрСравнить(Слово, "филиал") = 0 ИЛИ СтрСравнить(Слово, "фил") > 0 Тогда
Результат.Добавить(НРег(Слово));
Продолжить;
КонецЕсли;
Если НЕ СокращенияГородов.Найти(ВРег(Слово)) = Неопределено Тогда
Результат.Добавить(ВРег(Слово));
Продолжить;
КонецЕсли;
Результат.Добавить(ТРег(Слово));
КонецЦикла;
Возврат СтрСоединить(Результат, " ");
КонецФункции
Процедура ПрочитатьРезультатЗапросаДанных(СтруктураОтвета, РезультатЗапроса)
Если РезультатЗапроса.КодСостояния = 200 Тогда
СтруктураОтвета.suggestions = ДесериализоватьСтруктуруОтвета(РезультатЗапроса.Тело);
Иначе
СтруктураОтвета.ОписаниеОшибки = СтрШаблон("Не удалось получить ответ от сервиса DaData
|Код состояния: %1
|Ответ сервера: %2", РезультатЗапроса.КодСостояния, РезультатЗапроса.Тело);
КонецЕсли;
КонецПроцедуры // ПрочитатьРезультатЗапросаДанных()
Функция СокращенияГородов()
МассивГородов = Новый Массив;
МассивГородов.Добавить("МАЙ");
МассивГородов.Добавить("ГОА");
МассивГородов.Добавить("УФА");
МассивГородов.Добавить("УДЭ");
МассивГородов.Добавить("МАХ");
МассивГородов.Добавить("НЗР");
МассивГородов.Добавить("НАЛ");
МассивГородов.Добавить("ЭЛИ");
МассивГородов.Добавить("ЧЕР");
МассивГородов.Добавить("ПТЗ");
МассивГородов.Добавить("СЫК");
МассивГородов.Добавить("ЙШК");
МассивГородов.Добавить("СРН");
МассивГородов.Добавить("ЯКУ");
МассивГородов.Добавить("ВЛК");
МассивГородов.Добавить("ТАТ");
МассивГородов.Добавить("КЗЛ");
МассивГородов.Добавить("ИЖВ");
МассивГородов.Добавить("АБН");
МассивГородов.Добавить("ГРЗ");
МассивГородов.Добавить("ЧЕБ");
МассивГородов.Добавить("БАР");
МассивГородов.Добавить("ЧИТ");
МассивГородов.Добавить("ПТР");
МассивГородов.Добавить("КРД");
МассивГородов.Добавить("КРР");
МассивГородов.Добавить("ПЕМ");
МассивГородов.Добавить("ВЛВ");
МассивГородов.Добавить("СТВ");
МассивГородов.Добавить("ХАБ");
МассивГородов.Добавить("БЛГ");
МассивГородов.Добавить("АРХ");
МассивГородов.Добавить("ACT");
МассивГородов.Добавить("БЕЛ");
МассивГородов.Добавить("БРН");
МассивГородов.Добавить("ВЛМ");
МассивГородов.Добавить("ВЛГ");
МассивГородов.Добавить("ВОЛ");
МассивГородов.Добавить("ВРЖ");
МассивГородов.Добавить("ИВА");
МассивГородов.Добавить("ИРК");
МассивГородов.Добавить("КЛГ");
МассивГородов.Добавить("КЛЖ");
МассивГородов.Добавить("КЕМ");
МассивГородов.Добавить("КИР");
МассивГородов.Добавить("КОС");
МассивГородов.Добавить("КУГ");
МассивГородов.Добавить("КРС");
МассивГородов.Добавить("ЛОД");
МассивГородов.Добавить("ЛПЦ");
МассивГородов.Добавить("МАГ");
МассивГородов.Добавить("МСК");
МассивГородов.Добавить("МУР");
МассивГородов.Добавить("НЖГ");
МассивГородов.Добавить("НВГ");
МассивГородов.Добавить("НОВ");
МассивГородов.Добавить("ОМС");
МассивГородов.Добавить("ОРБ");
МассивГородов.Добавить("ОРЛ");
МассивГородов.Добавить("ПНЗ");
МассивГородов.Добавить("ПСК");
МассивГородов.Добавить("РСТ");
МассивГородов.Добавить("РЯЗ");
МассивГородов.Добавить("СМР");
МассивГородов.Добавить("СРТ");
МассивГородов.Добавить("ЮСХ");
МассивГородов.Добавить("CBE");
МассивГородов.Добавить("СМО");
МассивГородов.Добавить("ТМБ");
МассивГородов.Добавить("ТВЕ");
МассивГородов.Добавить("ТОМ");
МассивГородов.Добавить("ТУЛ");
МассивГородов.Добавить("ТЮМ");
МассивГородов.Добавить("УЛН");
МассивГородов.Добавить("ЧЕЛ");
МассивГородов.Добавить("ЯРЛ");
МассивГородов.Добавить("БИР");
МассивГородов.Добавить("ЧИТ");
МассивГородов.Добавить("НРМ");
МассивГородов.Добавить("УОР");
МассивГородов.Добавить("ХМН");
МассивГородов.Добавить("АНД");
МассивГородов.Добавить("СЛХ");
МассивГородов.Добавить("МОС");
МассивГородов.Добавить("СПБ");
МассивГородов.Добавить("ШАЗ");
МассивГородов.Добавить("ШБТ");
МассивГородов.Добавить("ШБМ");
МассивГородов.Добавить("ШБЛ");
МассивГородов.Добавить("ШБР");
МассивГородов.Добавить("ШВС");
МассивГородов.Добавить("ШКМ");
МассивГородов.Добавить("ШКС");
МассивГородов.Добавить("ШМЛ");
МассивГородов.Добавить("ШОМ");
МассивГородов.Добавить("ШПМ");
МассивГородов.Добавить("ШЧМ");
МассивГородов.Добавить("ШЧУ");
МассивГородов.Добавить("ШЯМ");
Возврат МассивГородов;
КонецФункции
Процедура УдалитьЮрЛицБезКПП(СтруктураОтвет)
НовыйМассив = Новый Массив;
Для Каждого suggestion Из СтруктураОтвет.suggestions Цикл
Если suggestion.data.type = "INDIVIDUAL"
ИЛИ (suggestion.data.type = "LEGAL" И НЕ ПустаяСтрока(suggestion.data.kpp)) Тогда
НовыйМассив.Добавить(suggestion);
КонецЕсли;
КонецЦикла;
СтруктураОтвет.suggestions = НовыйМассив;
КонецПроцедуры // УдалитьКонтрагентовБезКПП()
#КонецОбласти
#КонецЕсли
#Область ОбработчикиСобытийЭлементовШапкиФормы
&НаКлиенте
Процедура КлючAPIПриИзменении(Элемент)
ЭтаФорма.Модифицированность = Истина;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
КлючОбъекта = "DaData.ru";
КлючНастроек = "DaDataAPI";
ОписаниеНастроек = "API ключ для сервиса DaData.ru";
Пользователь = "Общие";
СтруктураНастроек = Неопределено;
СтруктураНастроек = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, КлючНастроек, ОписаниеНастроек, Пользователь);
Если ЗначениеЗаполнено(СтруктураНастроек) Тогда
Объект.КлючAPI = СтруктураНастроек.КлючAPI;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
Если Модифицированность Тогда
Отказ = Истина;
Оповещение = Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Данные были изменены, сохранить ключ API?", РежимДиалогаВопрос.ДаНетОтмена);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура ПерейтиНаГлавнуюСтраницуDaData(Команда)
ЗапуститьПриложение("https://dadata.ru/");
КонецПроцедуры
&НаКлиенте
Процедура ПерейтиНаСтраницуAPI(Команда)
ЗапуститьПриложение("https://dadata.ru/api");
КонецПроцедуры
&НаКлиенте
Процедура Сохранить(Команда)
СохранитьКлючAPI();
Модифицированность = Ложь;
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура СохранитьКлючAPI()
УстановитьПривилегированныйРежим(Истина);
КлючОбъекта = "DaData.ru";
КлючНастроек = "DaDataAPI";
ОписаниеНастроек = "API ключ для сервиса DaData.ru";
Пользователь = "Общие";
Настройки = Новый Структура("КлючAPI", Объект.КлючAPI);
ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, Настройки, ОписаниеНастроек, Пользователь);
КонецПроцедуры
&НаКлиенте
Процедура ПослеОтветаНаВопрос(РезультатВопроса, ДополнительныеПараметры) Экспорт
Если РезультатВопроса = КодВозвратаДиалога.Нет Тогда
Модифицированность = Ложь;
Закрыть();
ИначеЕсли РезультатВопроса = КодВозвратаДиалога.Да Тогда
СохранитьКлючAPI();
Модифицированность = Ложь;
Закрыть();
КонецЕсли;
КонецПроцедуры
#КонецОбласти
Тестировалось на платформе 8.3.13, 8.3.20, 8.3.22.
Проверено на следующих конфигурациях и релизах:
- Управление торговлей, редакция 10.3, релизы 10.3.88.3