Скорость продаж и оборачиваемость за период для УТ 11




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

16 Comments

  1. jobkostya1c8

    Довольно интересная идея для снабженцев. Вопросы сразу:

    1. Что означает блеклость строк отчета?

    2. Алгоритм расчета колонок «1» и «2» пишите

    если позиция на начало дня > 0, но на конец дня = 0 или на начало дня = 0 и на конец дня > 0, то наличие в этот день равно 1/2.

    И что делать если в течение дня происходит периодическое пополнение товара по стратегии «с нуля до максимума, до нуля и опять до максимума»?

    Reply
  2. yc_2011

    1. Блеклость строк — условное оформление. Если товары продавались, то строки зеленые, Если продавались и остаток на конец периода = 0, то строки красные.

    2. Периодичность расчета средних остатков день, т.е. остатки среднедневные. В Вашем случае средний остаток будет 0.5 максимума. При такой интенсивности продаж надо внутри дня детализировать до регистратора. Никто пока такой задачи не ставил..

    Reply
  3. yc_2011

    (1) kostyaomsk, Или, глядя в отчет, увеличить количество энного товара в товарной матрице. Отчет как раз и сделан для корректировки товарной матрицы.

    Reply
  4. empafe

    Ошибка загрузки документа.

    по причине:

    Ошибка преобразования данных XDTO:

    НачалоСвойства: {http://v8.1c.ru/8.1/data-composition-system/settings}useInHierarchicalGroup Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}anyType

    Reply
  5. yc_2011

    Наверное, платформа не понимает тип «ЗначениеПараметраНастроекКомпоновкиДанных». Или обновитесь до 8.3.5, или закомментируйте все в модуле отчета — там «защита от дурака».

    Reply
  6. Spacer

    Как то оно неправильно количество дней на остатке считает…

    У меня период с 1-го по 14-е число.

    С 1-го по 5-е остатки на начало и конец — 2.

    6-го числа на начало 2, на конец — 1.

    с 7-го по 10-е на начало 1, на конец — 1,

    11-го числа на начало 1, на конец — 0.

    По идее количество дней остатка должно быть 10,5.

    А в отчете дает 11,5.

    Reply
  7. yc_2011

    (6) Spacer, Да, получается 10.5. Отлаживал на тестовой базе. Там есть запрос по вычислению периода, в зависимости от выбранного регистра (1 или 2) дает разные цифры.

    Вообще, это надо было сделать на вычисляемых полях… Попробуйте в консоли запросов выполнить

    ВЫБРАТЬ
    ТоварыНаСкладахОстаткиИОбороты1.Склад КАК Склад,
    ТоварыНаСкладахОстаткиИОбороты1.Номенклатура КАК Номенклатура,
    ТоварыНаСкладахОстаткиИОбороты1.ВНаличииНачальныйОстаток КАК КоличествоНачальныйОстаток,
    ТоварыНаСкладахОстаткиИОбороты1.ВНаличииКонечныйОстаток КАК КоличествоКонечныйОстаток,
    НАЧАЛОПЕРИОДА(ТоварыНаСкладахОстаткиИОбороты1.Период, ДЕНЬ) КАК День,
    МАКСИМУМ(НАЧАЛОПЕРИОДА(ТоварыНаСкладахОстаткиИОбороты2.Период, ДЕНЬ)) КАК ПредыдущийДень
    
    ИЗ
    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК ТоварыНаСкладахОстаткиИОбороты1
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК ТоварыНаСкладахОстаткиИОбороты2
    ПО (ТоварыНаСкладахОстаткиИОбороты1.Период > ТоварыНаСкладахОстаткиИОбороты2.Период)
    И (ТоварыНаСкладахОстаткиИОбороты1.Номенклатура = ТоварыНаСкладахОстаткиИОбороты2.Номенклатура)
    И (ТоварыНаСкладахОстаткиИОбороты1.Склад = ТоварыНаСкладахОстаткиИОбороты2.Склад)
    ГДЕ
    ТоварыНаСкладахОстаткиИОбороты1.Склад = &Склад
    И ТоварыНаСкладахОстаткиИОбороты2.Склад = &Склад
    И ТоварыНаСкладахОстаткиИОбороты1.Номенклатура = &Номенклатура
    И ТоварыНаСкладахОстаткиИОбороты2.Номенклатура = &Номенклатура
    
    СГРУППИРОВАТЬ ПО
    ТоварыНаСкладахОстаткиИОбороты1.Склад,
    ТоварыНаСкладахОстаткиИОбороты1.Номенклатура,
    НАЧАЛОПЕРИОДА(ТоварыНаСкладахОстаткиИОбороты1.Период, ДЕНЬ),
    ТоварыНаСкладахОстаткиИОбороты1.ВНаличииНачальныйОстаток,
    ТоварыНаСкладахОстаткиИОбороты1.ВНаличииКонечныйОстаток
    
    УПОРЯДОЧИТЬ ПО
    День

    Показать

    Reply
  8. iren2405

    Данная обработка очень помогла, спасибо большое.

    Reply
  9. yc_2011

    Не нашел комментарий «Здравствуйте, а данная обработка не может вычислять остатки отдельно для конкретной группы номенклатуры?»

    Если отбор по группе номенклатуры, то на втором скане показаны настройки. Если но номенклатурной группе, то надо изменить запрос (у заказчика не было номенклатурных групп).

    Reply
  10. user713548

    Здравствуйте, вот такая ошибка. Конфигурация УТ 3.0 Для Украины (соответствует ут 11.0)

    {(14, 44)}: Поле не найдено «ПродажиОбороты.Склад»

    ПО ОстаткиОбороты.Склад = ПродажиОбороты.<<?>>Склад

    Reply
  11. yc_2017

    (10) Странно, у меня все работает. Может, убрали реквизит «склад» в «ВыручкаИСебестоимостьПродаж»?. Надо посмотреть, куда и что пишет документ продажи.

    Reply
  12. yc_2011

    Процедуру «ПриКомпоновкеРезультата» можно удалить, вместо этого у параметра «ВывестиПозиции» установить «Использование» = «Всегда».

    Reply
  13. yc_2011

    Группировка «Склад» обязательно должна быть, иначе врет.

    Reply
  14. yc_2011

    Адаптировал отчет для производственного предприятия. Деление на склады условное. Чтобы убрать склады, надо в запросе удалить строки со складом (в выборках и соединениях) и группировку «Склад». Склад остается доступным для отбора.

    Reply
  15. yc_2011

    Для производственного предприятия по аналогии сделал отчет «Оборачиваемость материалов». Вместо продаж взял расход со склада на выпуск продукции.

    Reply
  16. germax

    Почему удваивает Дни наличия? Если в месяце 31 день и был целый месяц, выводит 62

    Reply

Leave a Comment

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