Как простой расчет среднего расхода материалов помог маленькому бизнесу




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

12 Comments

  1. izofen

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

    Reply
  2. miavolas

    (1) izofen, Действительно данные в отчет выработка исполнителей попадают из табличной части товары, документа заказ-наряд, где в общем случае фигурируют цены продажи, а не закупа… но в описываемом случае методика работы такова, что расходные материалы не продаются как таковые, и на них цены продажи устанавливаются равными закупочными в момент поступления. Организация зарабатывает выполняя работы и не устанавливая от закупочных цены процент наценки. В случае необходимости, в отчете могли бы фигурировать и данные партионного учета

    Reply
  3. AndrewK990

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

    Reply
  4. chernyshova_darya

    Глядя на макеты с текстами запросов делаю вывод, что речь идет про Альфа-Авто 4ой версии, а если мне не изменяет память сейчас разработчик прелагает 5ую версию, где подобный отчет сделан на СКД. Могут ли описанные вопросы быть отражены в последней версии конфигурации?

    Reply
  5. miavolas

    (3) AndrewK990, К сожалению файл конфигурации отраслевого решения нельзя разместить в качестве прилагаемого к публикации вложения для скачивания, потому моих строчек кода там очень немного(как видно из статьи), правообладателем на остальные является разработчик

    Reply
  6. miavolas

    (4) chernyshova_darya, отчет на СКД формируется на основе запроса к тому же регистру накопления, суть отчета та же

    Reply
  7. maxim1c

    Как ваш заказчик планировал сравнивать расход материалов на покраску различных по площади кузовных элементов? цифры объективно будут разными

    Reply
  8. miavolas

    (7) maxim1c, Действительно существуют различные приблизительные оценки расхода готовой эмали на один кузовной элемент

    Например:

    дверь – 300 мл;

    крыло переднее – 200 мл;

    крыло заднее – 300 мл;

    крышка багажника – 300-400 мл;

    задняя панель – 250 мл;

    радиаторная решетка – 100 мл;

    крыша кузова – 400 мл;

    бампер передний и задний – 250-300 мл;

    поверхность капота – 400-500 мл;

    порог – 150 мл.

    В связи с этим работы группируются по виду деталей, и уже внутри этих групп справочника авторабот производится сравнение

    Формируя отчет с группировкой строк «Работа»


    Reply
  9. osivv

    Данная задача решается более просто и себестоимость вычисляется точно:

    Есть такой документ «Комплектация», туда забиваются расходники на комплект ЛКМ, после проведения, комплект списывается в производство.

    В заказ-наряд помещается через кнопку заполнить-деталями из производства, остается проставить цену продажи или прописать продажную цену товара и она встанет автоматом.

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

    Данное решение уже давно и успешно работает, все довольны, нареканий нет.

    Как-то так.

    Reply
  10. miavolas

    (9) osivv, Спасибо за предложенное решение, мне на самом деле интересно обсуждать решения отраслевых проблем….

    На описываемом предприятии активно используется функционал документов комплектации и разукомплектации, …

    Правда не до конца понял как можно было бы использовать предложенную вами методику для того чтобы увязать стоимость материалов с работами исполнителей? чтобы подсчитать сумму приходящуюся на одну деталь (для некоторых работ из табличной части Работ) стоимость действительно более точно можно определять используя данные партионного учета (как об этом сказано в моем первом ответе на статью)

    Сравнить стоимость материалов расходуемых разными исполнителей(малярами) увязав работы с товарами — вот вопрос.

    Думая над вашим предложением возможно получилось бы посмотреть на более интересные результаты если переработав все документы предыдущего периода для формирования отчетов(или изначально выстроив так систему) для каждой работы указать документ комплектации.

    Наверное каждый полученный комплект необходимо в таком случае называть «Комплект ЛКМ для окраски переднего левого крыла автомобиля VIN ххххх»?

    и еще одно описываемом решении для получения данных для анализа не пришлось изменять документов предыдущего периода

    Reply
  11. partstrader

    А как запчасти группировали в справочнике номенклатура?

    Reply
  12. Designer1C

    Прекрасный пример прямой пользы от информационной системы на производстве !

    Думаю, что тот руководитель увидел пользу от программы 1С с новой стороны.

    Что особенно радует — в результате были исключены подозрения на сотрудников.

    А значит — сохранены отношения между руководителем и подчинёнными.

    Reply

Leave a Comment

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