Формирование потребностей и заполнение заказа поставщику. УТ, КА, ERP




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

28 Comments

  1. MGMGA
    Количество проданных товаров делится на длительность анализируемого периода

    Дни в которые были нулевые остатки не выкидываются из анализируемого периода?

    Жаль нет отбора по складам.

    Reply
  2. roman77

    Нет не выкидываются. Так же не учитываются текущие резервы, т.к. не понятно купят ли их или нет. Еще не учитываются минимальные лоты. Это всё, включая отбор по складам достаточно просто доработать под пожелания конкретного пользователя. У разных пользователей разные пожелания, поэтому я выложил некую универсальную болванку, с которой можно делать что угодно.

    Reply
  3. webandroid

    1. заполняются ли для анализа товары которые не продавались?

    2. учитываются ли продажи по отчетам розничных продаж?

    Reply
  4. roman77

    (3)

    1. Да, но только те товары, которые есть в наличии. Но так продаж за указанный период не было, то скорость продажи = 0 и программа не будет рекомендовать эти товары закупать: в поле «требуется заказать» будет стоять 0.

    2. Да. В основе обработки лежит запрос к регистру накопления ВыручкаИСебестоимостьПродаж куда попадают движения и отчетов по розничным продажам, и реализаций контрагенту «Розничный покупатель».

    Reply
  5. user1029876

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

    2. Можно ли включить минимальный лот для собственного производства?

    3. Учитывает ли обработка Минимальный остаток при расчете потребности?

    3. Можно ли на основании плана производства сформировать потребность в сырье за минусом текущего остатка сырья?

    Reply
  6. roman77

    1. Если отбор по производителю. Для собственных товаров заведите производителя «собственное производство» и отбирайте.

    2,3. Лоты и минимумы не предусмотрены, но несложно доработать.

    4. Нет. Требуется чуть более сложная доработка.

    Reply
  7. Костя333Костя

    1. В отборе номенклатуры ПРОИЗВОДИТЕЛЬ это поставщик?

    2. Есть ли в обработке возможность указать ПОСТАВЩИКА и обработка выведет потребность в товарах именно только от этого поставщика (товарах когда либо приходивших от этого поставщика). Или потребность выводится от всех вместе взятых поставщиков?

    Reply
  8. roman77

    (7) 1. ПРОИЗВОДИТЕЛЬ — это не поставщик, а реквизит номенклатуры. Это именно тот, кто произвел данный товар (например, Samsung).

    2. Нет.

    Reply
  9. Костя333Костя

    1. В Отборе Номенклатуры можно ли выбрать всю номенклатуру разом, и составленную потребность перевести в ексель формат для отправки заказа поставщику?

    2. Можно ли реализовать данную идею с ПОСТАВЩИКОМ?

    Reply
  10. roman77

    1. Можно. Для этого заполняете обработкой документ «заказ поставщику», а потом из него сохраняете полученную таблицу. Можно через Ещё > вывести список, или через печатную форму заказа.

    2. Можно, но в данный момент у меня нет времени.

    Reply
  11. Костя333Костя

    1. В Отборе Номенклатуры можно ли выбрать всю номенклатуру разом? Это тоже можно?

    Reply
  12. roman77

    (11) не заполняйте поля отбора номенклатуры и будет отобрана вся номенклатура.

    Reply
  13. Костя333Костя

    В Заказе поставщику я не нахожу кнопку ЗАПОЛНЕНИЕ. Она появится когда я зарегистрирую обработку в своей ут?

    Reply
  14. roman77

    (13) Да, см. раздел «ПОДКЛЮЧЕНИЕ» в описании обработки.

    Reply
  15. Костя333Костя

    Можно ваш номер телефона, есть некоторые вопросы.

    Reply
  16. roman77

    (15) нет.

    Reply
  17. Костя333Костя

    У меня есть обработка которая формирует позиции для заказа поставщику. Т.е заказ поставщику у меня сформирован. Мне нужна ваша обработка для проставки рекомендуемого количества для заказа. Вопрос. Можно ли воспользоваться обработкой строго для уже сформированного заказа поставщику?

    Reply
  18. roman77

    (17) Нет, обработка очистит ваш заказ и добавит туда свои товары. Я постараюсь в ближайшее время доделать обработку, чтобы был отбор по тем товарам, которые ранее приобретались у конкретного партнера.

    Reply
  19. Костя333Костя

    Можете сказать когда это будет?

    Reply
  20. roman77

    (19) постараюсь до след. ПН сделать

    Reply
  21. Костя333Костя

    ок, подожду.

    Reply
  22. roman77

    (21) готово. В версии 1.1 добавил отбор по поставщику.

    Reply
  23. Костя333Костя

    Спасибо.

    Reply
  24. Костя333Костя

    Открываю заказ поставщику, заполнить и сформировать потребности. Выводит сообщение «(Форма.Форма.Форма(5.3): Процедура или функция с указанным именем не определена (Показать значение)» и кнопка «ок» Посоветуйте что делать. Управление торговлей, редакция 11.1 (11.1.2.28)

    Reply
  25. roman77

    (24) вечером погляжу.

    Reply
  26. Костя333Костя

    Хорошо

    Reply
  27. roman77

    (24) Видимо у вас какая-то совсем древняя конфигурация, которая работает с платформой, не понимающей «ПоказатьЗначение».

    В режиме конфигуратора откройте модуль формы обработки.

    В самом верху

    &НаКлиенте
    Процедура ТоварыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    Если НЕ Элемент.ТекущийЭлемент.Имя = «ТоварыКоличество» тогда
    ПоказатьЗначение(,Элемент.ТекущиеДанные.Номенклатура);
    КонецЕсли;
    КонецПроцедуры
    

    Закомментируйте строку ПоказатьЗначение(,Элемент.ТекущиеДанные.Номенклатура);

    Можете вписать туда свой код для открывания формы номенклатуры. Или вообще удалите процедуру.

    Reply
  28. Alex_will

    Данная обработка видит заказ материалов в производство?

    Reply

Leave a Comment

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