ЭСЧФ. Беларусь. Практика работы с входящими электронными счетами-фактурами




Принцип обмена данными из 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='\

25 Comments

  1. ge_ni

    Всем, кто скачал, готов отправлять ежедневные обновления примерно к 21:00.

    За время с начала публикации:

    — Агентство Гревцова записывае заголовок файла xml 4 мя строчками. — Исправлено

    — ЗАО «БЕЛСНАБЭНЕРГО пишет «sender = » вначале а затем «http…» — Исправлено

    — При автозагрузке получен под именем хххх.xml файл содержащий описание ошибки сервера портала — Исправлено

    — Не обрабатывается документ с реквизитами «Всего», «НДС» в том числе — Исправлено

    — В «СканерВходящихЭСЧФ» пропущена процедура «ШкалаВСтрокеСостояния(…) — Исправлено (есть в

    ЧитаемИПодписываемВходящиеЭСЧФ)

    — На некоторых компьютерах не запускается Анализатор = СоздатьОбъект(«AddIn.XMLParser») — Исправлено

    Reply
  2. ge_ni

    При загрузке с портала Получен файл со статусом «Данный контрагент «+УНП+» не является плательщиком НДС…» — Исправлено

    Портал возвращает описание статуса в виде «Текст» на русском языке, не меняется статус входящих — Исправлено

    Нет автоматического перемещения между папками «ВходящиеИсходные» в зависимости от статуса — Будет исправлено

    Reply
  3. wer_alex

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

    Мой адрес wer_alex@tut.by

    Reply
  4. ge_ni

    Некоторые из бухгалтеров накопили до 500 неподписанных ЭСЧФ.

    Попытка сканировать их на локальном рабочем месте бухгалтера привела к огромным потерям времени: 45 секунд на 1 запись.

    При том, что на сервере эта работа была выполнена за 2.5 секунды.

    Основное зависание на обработке поиска контрагента по номеру ИНН. Для 20 000 контрагентов это оказалась непосильная задача.

    «Черный запрос» сработал не эффективно.

    Касается это обработки: «Читаем и подписываем…»

    Изменил правила работы с ней:

    1. Читаем файлы ЭСЧФ из папки «…Исходные» и создаем «ЭСЧФВходящие» в 1С на сервере.

    2. Проверяем ЭСЧФ и устанавливаем статус «На согласовании» на сервере.

    3. Читаем в обработку уже из документов 1С «ЭСЧФВходящие». Всю необходимую информацию для заполнения таблицы к подписанию берем из документа. (управляет этим режимом «флажок» в шапке обработки). Это на локальном компьютере бухгалтера. Тратим те же 2.5 секунды.

    4. Запускаем режим подписания … 14 секунд.

    5 Файлы ЭСЧФ из папки «,,,Исходные» переносятся в папку «,,,Подписанные» с изменением статуса и документов 1С

    Reply
  5. titoff

    Огромное спасибо автору за публикацию. Сэкономлена куча времени. И это при том, что постоянно сталкиваешься со все-возможными проблемами на стороне портала. Однозначно плюс. Только остался открытым вопрос с получением обновлений :)))

    Reply
  6. ge_ni

    Обновления буду отправлять на электронный адрес

    Reply
  7. user609375_pupkin2005

    На каких условиях?

    Reply
  8. ge_ni

    Надеюсь понимаете, что часть реквизитов в обработках не совпадает с реквизитами Ваших конфигураций и соответственно: прежде

    чем использовать обработки придется чуть переписать.

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

    Добавьте реквизиты документу «ЭСЧФВходящие» … как описано в публикации.

    1. Получаем с портала на диск. (Обработка — ЗагружаемВходящие…»)

    2. Читаем на сервере… (так быстрее) (Обработка — ЧитаемИПодписываем…)

    3. Создаём документы «ЭСЧФВходящие» в 1С на сервере со статусом «На согласовании» (Обработка — ЧитаемИПодписываем…)

    4. На следующий день на локальном компьютере бухгалтера (Обработка — ЧитаемИПодписываем…) ставим в шапке обработки флажок

    «Читаем из уже созданных ЭСЧФ для подписи на портале (экономим время)» и жмем кнопку «Читаем входящие». Заполнятся только

    распознанные в 1С по приходным документам.

    5. Жмем кнопку «Подписать»… «бла-бла-бла-портал»… в случае успешного ответа портала:

    — в таблице обработки меняется статус;

    — в документе 1С «ЭСЧФВходящий» меняется статус;

    — файл ЭСЧФ меняет название с «Выставлен__ХХХ…xml» на «Выставлен. Подписан получателем__ХХХ…xml» и переносится из папки

    «ВходящиеИсходные» в папку «ВходящиеПодписанные».

    6. Читаем файлы ЭСЧФ из папки «ВходящиеПодписанные», мало ли что пропустили (Обработка — СканерВходящих…) на сервере… (так быстрее)

    7. Создаём недостающие «ЭСЧФВходящие» в 1С (Обработка — СканерВходящих…) на сервере… (так быстрее) .

    8. Если всё распознано по документам поступления, жмем кнопку «Отправить в архив»… (Обработка — СканерВходящих…) на сервере… (так быстрее). Файлы ЭСЧФ переносятся из папки «ВходящиеПодписанные» в папку «ВходящиеАрхив»…

    Из ЭСЧФВходящих в 1С формируем «Книгу покупок» и т.д.

    Reply
  9. ge_ni

    (7) да просто ни на каких… т.е если Вам это нужно…

    Reply
  10. ge_ni

    Беда-то общая!

    Reply
  11. titoff

    (6) Вот и он: titoff_27@mail.ru. Вчера столкнулся с этим тормозами в реальности. Конечно, это не допустимо. Спасибо еще раз.

    Reply
  12. titoff

    Сегодня получил вот это:

    InvList = EVatService.GetList(НужнаяДата);

    {\TERMINALБУХГАЛТЕРИЯ НEXTFORMSЧИТАЕМИПОДПИСЫВАЕМВХОДЯЩИЕЭСЧФ.ERT(890)}: Плохой тип переменной

    InvVatXml = EVatService.GetEDoc(InvVatNumber);

    {\TERMINALБУХГАЛТЕРИЯ НEXTFORMSЗАГРУЖАЕМВХОДЯЩИЕЭСЧФВКАТАЛОГ.ERT(141)}: Плохой тип переменной

    Это опять портал заглючил ?

    Reply
  13. user609375_pupkin2005

    pupkin2005@tut.by — это для обновлений. Спасибо.

    Reply
  14. ge_ni

    12. titoff (файл скачал) 21.09.2016 13:21

    Сегодня получил вот это:

    InvList = EVatService.GetList(НужнаяДата);

    {\TERMINALБУХГАЛТЕРИЯ НEXTFORMSЧИТАЕМИПОДПИСЫВАЕМВХОДЯЩИЕЭСЧФ.ERT(890)}: Плохой тип переменной

    InvVatXml = EVatService.GetEDoc(InvVatNumber);

    {\TERMINALБУХГАЛТЕРИЯ НEXTFORMSЗАГРУЖАЕМВХОДЯЩИЕЭСЧФВКАТАЛОГ.ERT(141)}: Плохой тип переменной

    Ответ портала на попытку повторного подключения к нему… Значит сегодня уже не стоит…

    Остаётся только сожалеть

    Другой команды кроме

    EVatService.GetList(НужнаяДата) нет…

    Это мы пытаемся запросить у портала отбор по входящим ЭСЧФ на НужнуюДату именно по нашему ключу…

    Посмотрите в отладчике, что есть у Вас НужнаяДата?

    Reply
  15. titoff

    (14) Понятно. Попробую завтра. Спасибо.

    Reply
  16. titoff

    При попытке загрузить в каталог получаем вот это:

    Ошибка подключения: Ошибка HTTP

    SSPI InitializeSecurityContext returns error #-2146893816(0x80090008): Unknown error

    Что за зверь ? Не встречался ?

    Reply
  17. bravesk

    Скачал ваши обработки, буду очень благодарен за обновления.

    Мой адрес bravesk@mail.ru

    Reply
  18. ge_ni

    (16) Ровно вчера получил такой же ответ.

    Сегодня всё нормально… не выдаёт такого сообщения…

    Reply
  19. bravesk

    При попытке загрузить в каталог выдает следующее:

    Ошибка подключения: Ошибка HTTP

    Socket Error # 10060

    Connection timed out.

    В чём причина???

    Reply
  20. ge_ni

    (19) Да не в чем… Нужно попробовать через пол часа… Было у меня и такое сообщение.

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

    — Мы сообщили порталу «Кто мы»…

    — Сообщили дату и время с какой и по текущий момент хотим получить входящие ЭСЧФ

    — Нас поставили в очередь, если:

    — все входы заняты;

    — идет некая транзакция и не до НАС

    — не успели обработать распознавание НАС

    — и т.д.

    — Время ожидания в очереди на обработку запроса истекло

    — Нам об этом сказали

    Reply
  21. user589919_digitta

    Добрый день. А как-нибудь управление вычетами у Вас реализовано?

    Reply
  22. ge_ni

    (21) Имеется в виду заполнение книги покупок?

    Reply
  23. user589919_digitta

    (22) не совсем.

    Само заполнение книги покупок не проблема. Главное правильно отразить в ней ЭСЧФ с вычетами. Вот есть у нас на портале ЭСЧФ. Нам нужно принять только часть ндс из неё. Допустим мы её импортировали в 1с (к примеру Вашей обработкой), удалили из документа в 1с позицию,по которой ндс не «принимаем». Отразили в учете (записали в книгу покупок). Далее подписали и отправили на портал. Но на портале этот ЭСЧФ осталась не изменённой. Придется лезть на портал и делать вычеты в данном ЭСЧФ вручную. Но это уже невозможно, т.к. он подписан. Или сначало делать вычеты вручную, а потом импортировать в 1С. В любом случае данные на портале и в 1С должны соответствовать. Вы как-нибудь эту проблему решали?

    Reply
  24. ge_ni

    (23) Для отправителя исходящих ЭСЧФ, в новых условиях, существует ограничение связанное с тем, что его «ЭСЧФ исходящий» может анулировать получатель. В «СтатусахЭСЧФ» есть два состояния, предназначенные для таких манипуляций:

    — «CANCELLED» (Анулирован);

    — «ON_AGREEMENT_CANCEL» (Выставлен. Анулирован поставщиком).

    Для Вас это единственный шанс повлиять на содержание входящих ЭСЧФ. Вам придется их «Анулировать». У поставщика же должен быть механизм регулярного (или перед составлением отчетов) чтения статусов выставленных им ЭСЧФ. На основании данных этого механизма предстоит определить долю счета 68.2.1, которую можно пустить в зачет.

    Есть и другой способ: поставщик сам «Анулирует» собственные ЭСЧФ по Вашему звонку и подстраивает их под то, что Вы хотите.

    Обе ситуации КОНФЛИКТНЫЕ. Вывод для поставщика: зачем ему такой хлопотный покупатель?

    А Вы, судя по всему, работаете «по оплате» и имеете от этого существенные «преимущества»…

    Та же картина, когда ВЫ являетесь поставщиком! Выставлять ЭСЧФ следует только на то, что оплачено покупателем.

    Один из клиентов, работающий «по оплате», согласовал с налоговой для себя вариант, когда он не ориентируется на оплату отгрузочных документов, при выставлении «ЭСЧФ исходящих»…

    Есть еще странное состояние «ON_AGREEMENT» (На осгласовании), но я его использую в обработках только для фиксации у получателя статуса чтения входящего и проверки до подписания…

    Reply
  25. grayglobus

    Скачал, вашу разработку. Будьте добры выслать обновления на адрес GrayGlobus@inbox.ru. Заранее благодарен

    Reply

Leave a Comment

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