Журнал учета объема розничной продажи алкогольной и спиртосодержащей продукции для 1С Розница 1.0 (платформы 8.1, 8.2 и 8.3)




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

12 Comments

  1. ENet

    Судя по отчету, у вас в журнале строки по приходу и расходу независимы друг от друга, хотя если посмотреть на первый параметр (№ п/п) и разъяснения фсрар по порядку заполнения (каждая хоз.операция в отдельной строке Вопросы-ответы ФСРАР), то наверное это не совсем корректно. Не подскажете, почему выбрали такой способ заполнения, а не с каждой хоз.операцией в отдельной строке?

    Reply
  2. TESL

    (2) ENet, Да действительно они не зависимы. Как упоминалось в самой статье отчет был сделан на основе http://infostart.ru/public/312092/ в котором я не нашел ничего что бы противоречило http://www.consultant.ru/document/cons_doc_LAW_165152/ или чего бы не хватало. Но теперь почитав http://fsrar.ru/voprosy-i-otvety/raznoe вижу что кое чего не хватает. К примеру перемещений… а на счет хоз операций, я так толком не понял… каждая в отдельности операция это имеется в виду сам чек ? (в этом отчете действительно идет в целом за день по кассе) или же речь идет о том что каждую строку надо делать по порядку, т.е. отдельной строкой поступление, отдельной расход ? или и то и другое ?

    Reply
  3. ENet

    (3) Согласно все тому же приказу ФСРАР п. 4 приложения 2.: «Журнал заполняется по мере совершения хозяйственных операций. Для каждой хозяйственной операции создается новая запись.» а в п.5 приложения 2 приказа: «При заполнении журнала указывается: 1) в графе 1 — порядковый номер;» (http://www.consultant.ru/document/cons_doc_LAW_165152/). Я думаю порядковый номер — есть порядковый номер записи. Т. е. приход и расход должны быть, по-моему, связаны между собой датой, временем проведения операции или, как Вы выразились, отдельной строкой поступление, отдельной строкой расход. и я в файле привел пример как, наверное, должно выглядеть.

    А отчет о розничных продажах» или чекККМ используется в содержании операции тут совершенно не важно. Главное запись сделана — но в расходе их не стоит группировать по виду, коду алкогольной продукции, а в приходе, если в накладной от одного поставщика несколько разных видов водки- то сгруппировать можно. Хотя есть еще момент с фиксацией в течении дня до закрытия смены — тогда надо конечно же в отчет брать и ЧекККМ (но сомневаюсь,что это необходимо, ведь смену при необходимости можно закрыть в любой момент времени для фиксации в отчете при проверке).

    Вот у меня ваш отчет вызвал сомнения только по поводу независимости двух журналов, которые должны быть, наверное, все-таки зависимы (не зря же их в одну форму воткнули).

    Reply
  4. TESL

    (4) ENet, ну зависимость у них должна быть исключительно временная, я правильно понял ? чтоб они шли в порядке их формирования… (думаю что именно так) и это тоже не противоречит , а более того еще и подходит под объяснения. Это конечно подрывает логику основного запроса к данным текущей обработки, но если надо, то будем делать…

    Reply
  5. ENet

    (5) Наверное, все-таки временн’ая — это не совсем к этому контексту подходит. Скорее просто из №п/п вытекает временн’ая зависимость между хозяйственными операциями. Т.е. чем больше №п/п, тем позже была зафиксирована хозяйственная операция.

    Поэтому и заполнение журнала по вашему отчету (по первому скриншоту) скорее всего, является некорректным.

    ИМХО. Каждая строка журнала=отдельная хоз.операция.

    Reply
  6. TESL
    Reply
  7. Uncore

    (7) вот это запрос. Некорректно его строить по документам, правильнее по регистру накопления, чтобы не привязываться к названиям документов. Соединение со свойствами можно сделать к итоговой таблице один раз, а не к каждому документу.

    В нашем журнале запрос занимает втрое меньший объем и использует всего одно обращение к таблицам с данными базы.

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

    Reply
  8. TESL

    (8) Uncore, полностью с вами согласен насчет регистров. Но если почитать всю статью с самого начала, то можно обнаружить что данная обработка была сделана на основе другой, ссылка на которую приведена выше. Нашей задачей было адаптировать, а не делать заново 😉 с функциями своими журнал справляется, хоть и не так быстро как у вас. А если на выходе не видно разницы, зачем же платить больше ? 😉 А если кому нибудь будет необходимо чтоб мы сделали так как будет нужно ему, то мы с радостью это сделаем и при чем за деньги меньшие чем стоит ваша тиражная обработка.

    Reply
  9. sanches

    Спасибо, пригодится.

    Нашел небольшую ошибку.

    Если выбирать период на форме в самом поле, то значение переменных мДатаНачалаПериодаОтчета и мДатаКонцаПериодаОтчета остается неизменным.

    Reply
  10. ivt_2009

    Решал аналогичную задачу. Вопрос , как перенести значения свойств объектов из УТ в розницу по средствам РИБ

    Reply
  11. TESL

    (11) ivt_2009, Доброго времени суток! О каких редакциях УТ и Розницы идет речь ? Т.к. для УТ 10.3 <-> РТ 1.0 через обмен прекрасно передаются все свойства, если у вас не стоят какие либо ограничения в плане обмена.

    Reply
  12. pallid

    Капец, скачиваю обработки, а они на почту не приходят. Сегодня пытался скачать 4 раза, монетки ушли а писем нет

    Написал в ТП, жду ответа….

    Автор, прошу помочь, пришлите на почту 1005220_mail_ru

    Reply

Leave a Comment

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