Групповая загрузка налоговых накладных в формате XML с возможностью проверки в едином реестре в 1С 8.2 УТП (Украина)




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2026-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='\

39 Comments

  1. Иной

    Приветствую.

    А, собственно, откуда эти XML-файлы берутся?

    Reply
  2. S.V.Y

    XML файлы налоговых накладных принимают и сохраняют с помощью специализированного ПО (Медок, Соната) вот эти файлы и обрабатываются

    Reply
  3. dyak84

    Автор хотел уточнить такой маленький вопрос, а обратная загрузка из(медка, санаты………) есть имеется ввиду реквизит накладная зарегистрирована будет отмечатся в 1С или нет. Зарание спасибо за ответ

    Reply
  4. S.V.Y

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

    Reply
  5. DAnry

    Спасибо за обработку. Вот только вопрос: с какими формами налоговых документов работает Ваша обработка, конкретнее — поддерживает ли она налоговые 2015 года?

    Reply
  6. S.V.Y

    Конечно поддерживает — в обработке реализован стандартный функционал 1С — форма документа определяется по его дате

    Reply
  7. yuriyscr

    Неплохо бы доработать: так как есть контрагенты, которые не работают с МЕДОК, присылают хмл-файлы с названием типа «2015-01-22-10-59-35_хххххххх_J1201007».

    У вас идет разбор файла, из названия которого вытаскивается ЕДРПОУ, а также вид и тип документа. А в данном файле — только дата-время и ЕДРПОУ.

    Reply
  8. yuriyscr

    И непонятная структура поиска:

    СтруктураПоиска = Новый Структура(«ЕДРПОУОрганизации, ВидДокумента», ЕДРПОУКонтрагента, «12»); // налоговая накладная и корректировка

    Выделенным шрифтом — если отбор по организации, то почему значению поля структуры поиска присваивается ЕДРПОУКонтрагента ?

    Reply
  9. S.V.Y

    Над Медком я как раз сейчас работаю, только в пятницу лицензию купили, не было возможности раньше это сделать. По структуре отбора — я там на скорую руку сделал (надо просто поменять заголовок колонки в ТЗ), будет больше времени подправлю.

    Reply
  10. yuriyscr

    (7) Извините, этот вопрос снимается — клиент неправильно экспортнул документ из МЕДОК.

    А вопрос (8) — остается.

    Reply
  11. yuriyscr

    (9) И у МЕДОК из названия файла экспорта мало что вытащишь, они выгружаются следующего вида:

    «9F8F76E6D834421FA3FD834FC744F808.xml» — Это экспорт входящей налоговой.

    Reply
  12. S.V.Y

    (11)Не совсем так — в файл вида 2015-01-22-10-59-35_хххххххх_J1201007 выгружается тоже вся информация — и даже более — там есть дата регистрации налоговой в едином реестре + там есть в конце ссылка на файл именно налоговой накладной — т.е., если выгрузить оба документа то можно получить вообще полную картину, хотя, в принципе, можно обойтись и одним файликом.

    Reply
  13. S.V.Y

    (7)Вид и тип документа тут тоже есть — J1201007

    Reply
  14. yuriyscr

    Спасибо за обработку, подправил себе немного, загружается.

    Добавил при заполнении СпискаДокументов — поиск ДокументаОснование.

    Reply
  15. S.V.Y

    (14)Пользуйтесь на здоровье 😉 По поводу поиска документа-основания — Вы искали конкретный вид документа? Поступление товаров, например, или поиск по всем документам, которые могут быть основаниями?

    Reply
  16. yuriyscr

    (15) В обработке — изначально ищет только среди : «Документ.РегистрацияВходящегоНалоговогоДокумента».

    Я добавил поиск среди документов из составного типа данных реквизита «СсылкаОснование» из ТЧ.

    Так как зачастую Внесены только платежки или заказы и ещё нет накладой, а в МЕДОК уже появляется Налоговая Накладная от Контрагента.

    Reply
  17. S.V.Y

    (16)Понял — только это не совсем документ-основание. В обработке это поле используется для вызова метода Заполнить() входящего документа, чтобы все реквизиты заполнялись стандартными средствами платформы.

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

    Reply
  18. zhurba

    Два вопроса. Но больше не по обработке, а по Медку:

    Подскажите, каким образом выгрузить из Медка «файл вида 93A045DED3074415B86D5C7E62EF9CAD.XML — непосредственно сам документ» ?

    И как выгрузить пакет документов «файл типа 2015-01-28-10-54-38_ХХХХХХХХ.XML» ?

    Лицензия есть.

    Заранее спасибо!

    Reply
  19. S.V.Y

    Файл — Экспорт в меню Медка

    Reply
  20. Alchin

    А работает эта обработка с документами выгруженными из аналога медка АртЗвита?

    файлы вида 08330039290190J1201007100000000210420150833.XML

    Reply
  21. S.V.Y

    Нет, не думаю — формат заголовка отличается от медка.

    Reply
  22. IgorArhangel

    Скачал обработку.

    Сделал экспорт из медка

    В настройках выбрал обновить список MeDOC XML

    И оно мне выдало

    Отсутствует файл XML \LUDAobmenВыгрузка налоговых6B798BA1DDFD44A0AD0E3A109B95E2DD.XML

    Файл создался с таким названием

    2015-07-03-12-39-43_ХХХХХХХХ_J1201007.XML

    В чем может быть проблема?

    Reply
  23. S.V.Y

    Попробуйте для начала сделать загрузку с локального а не с сетевого каталога. Дальше посмотрим.

    Reply
  24. IgorArhangel

    То я тупанул в папке были еще куча файлов поэтому и не загружалось.

    Попробовал загрузить и удивился, не затягивается документ основание и договор.

    Может в обработке что-то не доделано?

    Мне надо чтоб затягивался документ основание и договор автоматически.

    Может что-то не так делаю?

    Reply
  25. S.V.Y

    Контрагента пробовали выбирать?

    Reply
  26. IgorArhangel

    нет не пробовал.

    Я загружаю пакет налоговых от разных контрагентов.

    И как мне выбрать одного контрагента?

    Reply
  27. IgorArhangel

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

    А должен быть один главный файл и для каждого документа свой еще файл, правильно?

    У меня просто медок выгружает тупо один файл

    Reply
  28. IgorArhangel

    я понял в чем проблема..

    У меня из медка выгружается только пакет документов вот такой 2015-07-08-15-25-03_ХХХХХХХХ.XML

    А файлы документов вида — F0F6AAA0733941C19E837FFBA895AE2E.XML

    Не выгружается из-за этого и не тянет документ основание и пишет что файл F0F6AAA0733941C19E837FFBA895AE2E.XML Отсутствует файл.

    А без файлов документов работать не будет.

    Может что-то подскажите

    Reply
  29. IgorArhangel

    Только что звонил в медок и там сказали, что файлы можно выгружать или пакетом или отдельно по одному, а формировать пакет и файлы сразу медок не может…

    Вот так-то..

    и что делать не знаю.

    Reply
  30. S.V.Y

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

    Reply
  31. S.V.Y

    (27) IgorArhangel, неправильно — выгруженный пакет содержит в себе все необходимые документы.

    Reply
  32. IgorArhangel

    (31) Но обработка Ваша пишет что файл F0F6AAA0733941C19E837FFBA895AE2E.XML отсутствует

    из медка выгружается 1 файл.

    Но обработка еще ищет файлы по каждой накладной.

    Может в ней надо дописать чтоб оно не искало дальше файлы?

    Reply
  33. S.V.Y

    Я, честно говоря, уже не помню о чем вы говорите 🙂 Мне кажется что этот файл записывается в реквизит «ТекстХМЛ» в 1С, тогда его действительно надо выгружать отдельно. В любом случае, на работоспособность обработки это никак не влияет.

    По документу основанию — попробуйте в строке 528 после

    Строка.Контрагент = Выборка.Ссылка;
    

    добавить

    НайтиДокОснование(Строка);
    
    Reply
  34. IgorArhangel

    Да вроде бы получилось.

    Но на платформе 8.3 не пашет.

    И ещё. Когда сохраняю настройки и в следующий раз захожу оно не прохавывает путь к файлам. Пишет не верный путь. Перевыбрал путь все нормально. Это на платформе 8.2

    Reply
  35. S.V.Y

    Что именно не пашет на 8.3? С путями — есть такая проблема, решения пока не нашел.

    Reply
  36. IgorArhangel

    (35) на 8.3 не пашет именно путь. И сетевой путь указывал и локальный. Тупо не видит файл. Пишет проверьте правильность пути.

    все перепробовал…

    Reply
  37. S.V.Y

    Строка 242 пробуйте поменять Файл.Имя на Файл.ПолноеИмя и в строке 597 также

    Reply
  38. IgorArhangel

    на 8.2 прокатило..

    на 8.3 пока нет возможности проверить

    Reply
  39. IgorArhangel

    На 8.3 работает отлично..

    не много доработал обработку..

    Пашет пока отлично!!!!

    Reply

Leave a Comment

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