Заполнение данных по ИНН контрагента с помощью альтернативного сервиса огрн.онлайн




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

50 Comments

  1. Mi11er

    О, за наводку про сервис 1С спасибо, а остальное можно было получать от DaData.

    Reply
  2. Serega-artem

    Еще не побывал, но за идею однозначно плюс!

    Reply
  3. OlegAr

    однозначный плюс +

    Reply
  4. akim2040

    А что за сервис? Ради интереса пытался найти себя, и ни чего не дал полезного.

    Reply
  5. slava_1c

    Спасибо, друзья.

    На счет сервиса dadata.ru — не соглашусь с тем что он равнозначен этому.

    Например в dadate в ответе по адресу я получаю адрес в формате кладр,

    а сегодняшнее требование к заполнению счетов-фактур вызвало коллективное помешательство

    бухгалтеров и они поголовно хотят видеть адреса в формате ФИАС. Здесь же прилетает именно

    адрес в формате ФИАС, да еще и с ГУИД ссылкой в значении, по которой можно получить и ссылку из Кладра:

    Структ.address.fiasOnlineLink например «фиас онлайн»

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

    Структ.closeInfo.closeReason.name например «ПРЕКРАЩЕНИЕ ДЕЯТЕЛЬНОСТИ ЮРИДИЧЕСКОГО ЛИЦА В СВЯЗИ С ИСКЛЮЧЕНИЕМ ИЗ ЕГРЮЛ НА ОСНОВАНИИ П.2 СТ.21.1 ФЕДЕРАЛЬНОГО ЗАКОНА ОТ 08.08.2001 №129-ФЗ»

    Из значения Структ.description можно получить исчерпывающую информацию по организации и контролить таким образом контров перед заключением договоров

    И все это бесплатно!!! (надолго, надеюсь)))

    А на счет того что себя не смогли найти… И слава богу))) это поиск по организациям, директорам и учредителям

    Reply
  6. user694260_vip.allabirdin

    (4)1С:Контрагент

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

    https://portal.1c.ru/applications/3

    Reply
  7. gosizo

    Большое спасибо! то что нужно и в рабочем состоянии (в отличие от других подобных публикаций)

    Reply
  8. Xel'naga

    Для поиска физлица по ИНН

    HTTPЗапрос = Новый HTTPЗапрос(«интеграция/люди/?инн=»+СокрлП(ИНН))
    Reply
  9. Mi11er

    (5)да, соглашусь, тут больше всего приходит.

    Написал на 100 строк утилиту, буду крутить ее к базе =) Спасибо за ссылку.

    Reply
  10. Mi11er

    Можем кому, будет интересно, как работает ( на ОФ, платформа 3.8)

    Reply
  11. rozer

    (5)

    И все это бесплатно!!! (надолго, надеюсь)))

    вряд ли бесплатно будет в будущем — как только наберут вес сразу монетизируют )

    Reply
  12. Niko_Arte

    ИП не находит(

    Reply
  13. slava_1c

    (12) А это вот как раз то как (8) написал. Это как раз поиск по ИП, учредителям, директорам и сотрудникам.

    Вот подробнее тут

    Reply
  14. rwf96

    Получаем структуру Структ. Такой конструкции — Структ.closeInfo.closeReason.name — в Структ нет. Судя по описанию она есть в Структ.predecessor. predecessor — это массив. При запросе информации, кол-во элементов в массиве predecessor равно 0. Подскажите, как правильно получить состояние Контрагента?

    Reply
  15. slava_1c

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

    не Структ.closeInfo = Неопределено 

    либо через

    Попытка
    Reply
  16. slava_1c

    Если кому интересно как получить тоже самое из сервиса 1С — вот продолжение кода из публикации:

    ОбъектXDTO = Результат.РеквизитыЮрЛица;
    Сообщить(«НаименованиеПолное «+ ОбъектXDTO.СвНаимЮЛ.НаимЮЛПолн);
    Сообщить(«НаименованиеСокращенное «+ОбъектXDTO.СвНаимЮЛ.НаимЮЛСокр);
    Сообщить(«ОГРН «+ ОбъектXDTO.ОГРН);
    Сообщить(«КПП «+ОбъектXDTO.КПП);
    Адрес =ОбъектXDTO.СвАдрес.Адрес.Состав.ДопАдрЭл[0].Значение+», «+ ОбъектXDTO.СвАдрес.Адрес.Состав.СубъектРФ+», «+ОбъектXDTO.СвАдрес.Адрес.Состав.Улица;
    Для каждого СведенияОбАдресе Из ОбъектXDTO.СвАдрес.Адрес.Состав.ДопАдрЭл Цикл
    Если СведенияОбАдресе.Номер  <> Неопределено тогда
    Адрес = Адрес+», «+СведенияОбАдресе.Номер.Значение;
    КонецЕСлИ;
    КонецЦикла;
    Сообщить(«Адрес: «+Адрес);
    Если ОбъектXDTO.СвУправлДеят <> Неопределено И ОбъектXDTO.СвУправлДеят.СведДолжнФЛ <> Неопределено Тогда
    Для каждого СведенияОДолжности Из ОбъектXDTO.СвУправлДеят.СведДолжнФЛ Цикл
    Если Найти(ВРег(СведенияОДолжности.НаимВидДолжн), «РУКОВОДИТЕЛЬ») > 0 И СведенияОДолжности.ФИО <> Неопределено Тогда
    Сообщить(«Руководитель:»+СведенияОДолжности.ФИО.Фамилия+» «+СведенияОДолжности.ФИО.Имя+» «+СведенияОДолжности.ФИО.Отчество+», должность: «+СведенияОДолжности.НаимДолжн+», тел: «+СведенияОДолжности.ИННФл);
    Сообщить(«Телефон:»+СведенияОДолжности.НомТел);
    Прервать;
    КонецЕсли;
    КонецЦикла;
    КонецЕсли;
    

    Показать

    Reply
  17. rwf96

    (16)Спасибо, получилось!

    Reply
  18. akim2040

    (6) Я имел ввиду сервис, который предлагается использовать в публикации. огрн.онлайн

    Он мне не правильную информацию выдал обо мне. Вернее не актуальную

    Reply
  19. rpgshnik

    По вам походу уже обработки пилят https://infostart.ru/public/695635/ )))

    Reply
  20. slava_1c

    (19) Ну, по-хорошему, это и делалось для того чтобы все пилили обработки. )))

    Автор ее к рознице прикрутил. Еще можно ее к бухгалтерии 2.0 прикрутить — там тоже нет такого сервиса, УТ 10.2, 10.3.

    Ну а в 77 вообще поле не паханное, так что… ))))

    В любом случае, спасибо за бдительность!

    Reply
  21. user828732

    (11) Видимо в этот сервис данные подсасываются из того же 1С Контрагент.

    Reply
  22. Zelenhof

    Хороший вариант. Жаль не подходит для пользователей совсем уж старых решений на 8.1. (

    Reply
  23. slava_1c

    (22) Ну конкретно этот код не работает — там просто нет таких методов.

    Для пользователей 8.1 и 7.7, можно порекомендовать использовать COM объект WinHttp.WinHttpRequest.5.1

    Пример для 8.1 будет такой

    WinHttp = Новый COMОбъект(«WinHttp.WinHttpRequest.5.1″);
    WinHttp.Option(2,»utf-8»);
    WinHttp.Open(«POST»,»https://xn--c1aubj.xn--80asehdb/интеграция/компании/?инн=»+СокрлП(ИНН),0);
    WinHttp.SetRequestHeader(«Accept-Language», «ru»);
    WinHttp.SetRequestHeader(«Accept-Charset»,»utf-8″);
    WinHttp.setRequestHeader(«Content-Language», «ru»);
    WinHttp.setRequestHeader(«Content-Charset», «utf-8»);
    WinHttp.setRequestHeader(«Content-type», «application/x-www-form-urlencoded; charset=utf-8»);
    WinHttp.Send(«»);
    Ответ = WinHttp.ResponseText();
    
    

    Показать

    А дальше парсить, парсить… ))) Поищите в сети «парсер JSON». Он точно есть уже готовый.

    Reply
  24. waol

    присоединяюсь к благодарностям. Еще не смотрел, судя по обсуждениям +

    Reply
  25. _Z1

    (23) Это в v7.7 не работает.

    Пробовал по всякому.

    Подскажите куда копать, что посмотреть.

    я с запросами на Вы

    Reply
  26. VGHOST

    Полезная инфа, благодарю.

    Настораживает только то, что база ОГРН.ОНЛАЙН содержит ошибки — меня, например, приписала к чужой ИФНС, на которую в выписке с https://egrul.nalog.ru/ никаких ссылок нет.

    Видимо исправят, со временем…

    Reply
  27. slava_1c

    (25) Не было 77 под рукой (я уже забыл как там писать-то )))). Сейчас проверил — 404 Bad request… Зато без проблем сработал 1с-ный сервис. Пример в этой статье При том, что он тоже https..

    Reply
  28. user861087

    (5)

    Дадата приводит адреса именно к ФИАС. Почему вы думаете, что там адреса в формате КЛАДРа?

    А ещё проставляются индексы, районы города и координаты ツ

    Reply
  29. user861090

    Очень помогло. СПС

    Reply
  30. slava_1c

    (29) Ну вот пример с их официального сайта

    [
    «inn»: «7719402047»,
    «ogrn»: «1157746078984»,
    «okpo»: null,
    «okved»: «72.19»,
    «okveds»: null,
    «authorities»: null,
    «documents»: null,
    «licenses»: null,
    «address»: {
    «value»: «г Москва, г Троицк, Сиреневый б-р, д 1»,
    «unrestricted_value»: «г Москва, г Троицк, Троицкий округ, Сиреневый б-р, д 1»,
    «data»: { … }
    },
    

    Показать

    Это формат ФИАС?

    Reply
  31. user861087

    (31) Это пример исправленного адреса, так как в ЕГРЮЛ полно ошибок. Адрес «как в ЕГРЮЛ» возвращается в поле address.data.source либо address.value, если address.data пустое.

    Сегодняшнее требование к заполнению счетов-фактур вызвало коллективное помешательство

    бухгалтеров и они поголовно хотят видеть адреса в формате ФИАС. Здесь же прилетает именно

    адрес в формате ФИАС, да еще и с ГУИД ссылкой в значении, по которой можно получить и ссылку из Кладра.

    Вот здесь подробности по этому поводу: https://dadata.userecho.com/forums/4-baza-znanij/topics/3369-adres-kompanii-v-tochnosti-kak-v-egryul/

    Reply
  32. slava_1c

    (32) Спасибо за разъяснения. Уверен, что для тех, кто выбирает себе интеграцию, это будет полезная информация!

    Reply
  33. Serega-artem

    Во-первых, еще раз спасибо за публикацию!

    Во-вторых, вопрос: взяв за идею вашу публикацию сделал на тестовой базе реализацию добавления/актуализацию данных в справочнике юр. лиц. Поигрался и на какое-то время отложил. Вчера попробовал снова, получил:

    {
    «error» : «Access is denied»
    }

    Почитал про api, там нужно получать ключ api. Посмотрел заявку на получения ключа — ссылка на сайт с продуктом, описание, скриншоты и т.д. Для тиражных продуктов — ок. Что делать с не тиражными решениями? Там сайта, описания и т.п. нет. Думаю написать разработчикам с этим вопросом, но вдруг кто-то из 1сников уже обращался и имел опыт получения ключа API?

    Reply
  34. slava_1c

    Да, сервис по прежнему бесплатен, но уже не бесконтролен, как это было до начала этого года. Это касается не только данного сервиса, например яндекс с нового года тоже отключил все тестовые ключи, пришлось заново регистрировать личный кабинет для корректной работы некоторых локальных решений 1С для логистики. Там мы предоставили сайт компании, на которой нет никакой карты но получили ключ. По сути , это защита от роботов, а не от реализации 2-х, 10-ти запросов в день.

    Reply
  35. Serega-artem

    (35) Спасибо за ответ! Вот кстати, что пишут разработчики в своей группе в ВК:


    В связи с большим наплывом заявок на API имеет смысл прояснить критерий отбора. Ключи получают те продукты, которые предоставляют сервисы широкому кругу пользователей: боты для месседжеров, плагины для 1С, CRM и прочих. Т.е. способствующие распространению открытых данных.

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

    т.е. для нас с Вами ситуация двоякая. С одной стороны, они говорят, что 1с — это гуд. С другой, все продукты для внутрикорпоративного использования — это плохо. Учитывая специфику 1с, одно противоречит другому. Простой пример: Я сделал некую тестовую конфигурацию с использованием сервиса. Она получилось (предположим) удачной, я получил на нее ключ, конфу начали качать и встраивать в свои конфы (она для этого и создавалась) и получаются, что если один из тех, кто воспользовался конфигурацией, нарушил правила API ключ забанят у всех. Так получается?

    p/s Задал эти вопросы разработчикам. Посмотрим, что скажут.

    Reply
  36. slava_1c

    (36) Совершенно верно. Бесплатный сервис и делается для того чтобы им пользовались все. Однако, встраивая этот и подобный ему сервисы в некую конфигурацию, сам ключ лучше сделать константой, которую пользователь будет вносить в момент начала эксплуатации. И если он вдруг нарушит правила пользования, это коснется только его. По идее разработчики совсем не против использования их сервиса в 1С.

    Reply
  37. Serega-artem

    (37) Вариант с константой — это первое, что пришло на ум. Но тут:

    1. Чтобы получить ключ API на обработку или конфигурацию надо прислать разработчикам ссылку на продукт. Пусть даже на публикацию на инфостарте. Но публиковать по-факту неработающие и не оттестированные разработки тут (да и где угодно) нельзя. А чтобы протестировать и опубликовать нужен ключ API. Замкнутый круг. Ну это ладно, тут я думаю можно как-то договориться.

    2. Сделали подключаемый ключ т.е. каждый вводит для себя. Скачал условный Иван Иванович обработку «Заполнение контрагентов в БП 3.0 с ОГРН.онлайн», она (обработка) просит ввести ключ API. А чтобы получить ключ API нужно прислать ссылку на приложение с его описанием и т.д. Всем одну и туже ссылку на публикацию на ИС присылать?

    Как я понимаю логику разработчиков — одно приложение, один ключ. Но как это будет работать применимо к 1с, не очень понятно. Да и на других платформах тоже. Возможно, компрометироваться в случаи нарушения будет не ключ, а IP или еще что-то.

    Reply
  38. slava_1c

    Вот пример публикации которая, судя по самому сайту, получила одобрение. Т.е. автор, создал СВОЙ сервис, использующий ИХ сервис.

    Reply
  39. Serega-artem
    Reply
  40. madonov

    Скачал несколько обработок, разобрал данный пример везде в качестве ответа получаю ответ «По указанным параметрам не найдено ни одной компании». Так сервис работает без ключа или нет?

    Reply
  41. slava_1c

    (41) Нет, без ключа с нового года API увы не работает. Хотя, какое то странное сообщение получаете. Ответ должен быть в формате JSON

    error: «Access is denied»

    Reply
  42. triviumfan

    (42) На строке

    ОтветСайта.ПолучитьТелоКакСтроку();

    я получаю пустую строку, а далее ошибка чтения/преобразования значения JSON.

    В общем, фейл 🙁

    Reply
  43. mv7890

    Бесплатно не работает: «Access is denied» . Будет честно об этом написать в самом начале.

    Reply
  44. slava_1c

    (44) Да, к сожалению это так. Отредактировал.

    Reply
  45. pentanom
    (20.09.2018) ВНИМАНИЕ!! К великому сожалению с момента написания статьи данный сервис перестал быть бесплатным…

    За вообщем-то небольшие деньги (2 коп за запрос, мин. 10000 запросов = 200 руб) можно получить ключ доступа к API. А куда его нужно вставить в приведенном коде.

    Reply
  46. slava_1c
    Авторизация

    В случае одобрения вашей заявки вам будет предоставлен ключ доступа. Данный ключ доступа необходимо указывать в заголовке X-ACCESS-KEY при каждом запросе к API.

    ssl = Новый ЗащищенноеСоединениеOpenSSL();
    HTTPСоединение = Новый HTTPСоединение(«xn--c1aubj.xn--80asehdb»,443,,,,,ssl);
    ЗаголовокЗапросаHTTP = Новый Соответствие();
    ЗаголовокЗапросаHTTP.Вставить(«X-ACCESS-KEY», «ЗДЕСЬ ВСТАВИТЬ ЗНАЧЕНИЕ КЛЮЧА»);
    HTTPЗапрос = Новый HTTPЗапрос(«интеграция/компании/?инн=»+СокрлП(ИНН), ЗаголовокЗапросаHTTP);
    Попытка
    ОтветСайта =  HTTPСоединение.Получить(HTTPЗапрос);
    ТекстJSON = ОтветСайта.ПолучитьТелоКакСтроку();
    Исключение
    Возврат;
    КонецПопытки;
    

    Показать

    Как то так…

    Reply
  47. pentanom

    (47) Спасибо !

    Но теперь, вероятно, нужно как-то и кодировку установить.

    Это тоже в заголовке делается ?

    Reply
  48. slava_1c

    Все верно, к примеру:

    ЗаголовокЗапросаHTTP.Вставить(«Content-Type», «application/json; charset=utf-8»);
    Reply
  49. ArtemiFD
    Reply
  50. pridecom

    Для 7.7 если будет готовый, дайте знать, пож

    Reply

Leave a Comment

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