Автоматическое переименование ЕГАИС номенклатуры




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

29 Comments

  1. Denya.S

    Очень было бы удобно засунуть сюда и запрос номенклатуры ЕГАИС по алкокоду, чтобы не грузить всю номенклатуру поставщика.

    Reply
  2. automatizator

    (1) Туда-же и сканирование марок… Иначе запрос по каким данным?

    Для этого и нужна обозначенная обработка Инвентаризация ЕГАИС.

    Reply
  3. Denya.S

    а можно ли с помощью данной обработки исправить уже заведенную и сопоставленную номенклатуру?

    Reply
  4. coolseo

    (3) Да

    Дмитрий, огромное спасибо

    Добавьте чекбокс снятия всех галочек и добавления всех.

    Баг:

    Неважно сколько выбрал галочек все время обрабатывает полностью ТЧ
    &НаКлиенте
    Процедура Переформатировать(Команда)
    Для Каждого Строка Из Объект.Товары цикл
    Строка.Наименование = ПереформатироватьНаСервере(Строка.НоменклатураЕГАИС);
    КонецЦикла;
    КонецПроцедуры
    Reply
  5. automatizator

    (3) Она именно для уже заведеной номенклатуры

    Reply
  6. automatizator

    (4) Галочки отрабатывают только на запись

    Reply
  7. coolseo

    (6) ок

    Вот что еще предлагаю добавить

    Наименование = СтрЗаменить(Наименование,»Пастеризованное»,»»);

    Наименование = СтрЗаменить(Наименование,»Пастеризованный»,»»);

    Наименование = СтрЗаменить(Наименование,»Алюминевый»,»Алюм.»);

    Наименование = СтрЗаменить(Наименование,»ароматом»,»аром.»);

    Наименование = СтрЗаменить(Наименование,»напиток»,»нап.»);

    Наименование = СтрЗаменить(Наименование,»Пивной»,»Пив.»);

    Reply
  8. user635667

    Я уже видел похожую обработку и кидал кое какие совты тому авору, но он что-то так и не соизволил ее доделать. Напишу и вам, мне кажется будет востребованно — Дать возможность выбирать дописывать-ли «л.» и «%», а также дописывать-ли вообще крепость и производителя. Бывает нужно просто цифру литража вставить и все.

    Reply
  9. user635667

    и по галочкам — не нашел кнопки убирающей все и ставящей обратно все галочки. а если мне надо только пару из всего списка переименовать?

    ну и я так понимаю можно писать сюда что можно допиливать в логике замены?

    то что я нашел и хотелось бы что бы вы поправили в своей обработке:

    Стеклянная бутылка вместимостью — ст.б.

    Металлическая банка — ж.б.

    ПЭТФ-бутылка вместимостью — переименовать в просто бут. либо вообще удалять

    Бутылка стеклянная — ст.б.

    Бутылка полимерная ПЭТ — переименовать в просто бут. либо вообще удалять

    СТЕКЛЯННАЯ БУТЫЛКА — ст.б.

    Пастеризованное. — вообще удалять, считаю лишним.

    Reply
  10. user635667

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

    Reply
  11. automatizator

    (7) Пив. нап. — по моему это перебор )))

    Reply
  12. automatizator

    (9) не понимаю откуда брать инфу по таре. В наименовании — почти не встречается

    Reply
  13. user635667

    Надо наверное добавить сортировку по столбикам. и добавить возможность открывать номенклатуру прямо из окна обработки, скажем правой кнопкой на номенклатуре — изменить

    Reply
  14. automatizator

    (13) Хорошо. Обработка бесплатная, так что за оперативность не ручаюсь. Пока делитесь предложениями в стиле СтрЗаменить() — т.е. что, на что менять в названии.

    Reply
  15. user635667

    Я сделал кучу всяких исправлений. Теперь мне надо сделать отдельную обработку которая бы чистила лишние пробелы в номенклатуре уже имеющейся. Я не программист 1С. Подскажите пожалуйста что поправить в этом коде, что бы просто убирались лишние пробелы в уже переписанном справочнике номенклатура(накалякал вариант как я его вижу, но не знаю как поменять что бы он брал названия уже не из справочника егаис, а из простого справочника номенклатуры):

    Скрытый текст
    Reply
  16. automatizator

    (15) Егор надо поискать другую обработку.

    Reply
  17. maxL

    Дмитрий, а возможно сделать такую обработку для УТ 10.3 ?

    Reply
  18. automatizator

    (17) Готовы оплатить работу?

    Reply
  19. maxL

    Готовы, цена вопроса ?

    Reply
  20. automatizator

    (19)Написал в личку

    Reply
  21. user635667

    Не пойму что не так — я добавил строку:

    Наименование = СтрЗаменить(Наименование,»Вино контролируемого наименования по происхождению»,»Вино»);

    Но это условие не работает. Связано это как-то с длинной наименования? Из всех позиций номенклатуры с таким начало самые длинные и у них у всех не срабатывает мое условие.

    п.с.

    наименование таких позиций выглядит так — Вино контролируемого наименовани по происхождению белое полусладкое «Молоко любимой женщины. Мадонна. Наэ. Ланселот»

    ну и плюс мы еще пытаемся добавить емкость, крепость и завод.

    Reply
  22. automatizator

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

    Reply
  23. user635667

    Другой вопрос. Я сделал так что бы цыфры в начале удалялись. А потом выеснилось что у некоторых позиций в названиях тоже есть цыфры. И в итоге у меня напиток «Портвей 777» преврящается просто в напиток «Портвейн». Вопрос — как сделать так что бы условие не проверяло наименования которые в скобках. например удалять 7, но не удалять ее там где » 7 «. ????

    Reply
  24. automatizator

    (23) Такого обработка не умеет

    Reply
  25. Ryukenden

    (15)

    // Удаление задвоенных пробелов

    Пока СтрНайти(ИсходнаяСтрока, » «) <> 0 Цикл

    ИсходнаяСтрока= СтрЗаменить(ИсходнаяСтрока, » «, » «);

    КонецЦикла;

    Результат = СокрЛП(ИсходнаяСтрока);

    Reply
  26. user635667

    (25) в какую строку это можно вставить?

    Reply
  27. Ryukenden

    (26)

    в какую строку это можно вставить?

    Это для вашей задачи очистки всей номенклатуры от лишних пробелов. Я для Розницы 2.2 такой код использую:

    &НаКлиенте
    Процедура ОбработатьНоменклатуру(Команда)
    ОбработатьНоменклатуруНаСервере();
    КонецПроцедуры
    
    &НаСервере
    Процедура ОбработатьНоменклатуруНаСервере()
    
    Запрос = Новый Запрос;
    Запрос.Текст =
    «ВЫБРАТЬ
    | Номенклатура.Ссылка КАК Номенклатура,
    | Номенклатура.Наименование,
    | Номенклатура.НаименованиеПолное
    |ИЗ
    | Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    | НЕ Номенклатура.ЭтоГруппа»;
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
    
    НоменклатураОбъект = Выборка.Номенклатура;
    
    НоменклатураОбъект.Наименокание = УдалитьЛишниеСимволы(Выборка.Наименование);
    НоменклатураОбъект.НаименованиеПолное = УдалитьЛишниеСимволы(Выборка.НаименованиеПолное);
    
    НоменклатураОбъект.Записать();
    
    КонецЦикла;
    
    КонецПроцедуры
    
    &НаСервереБезКонтекста
    Функция УдалитьЛишниеСимволы(Текст)
    
    Если Текст = «» Тогда
    Возврат «»;
    КонецЕсли;
    
    Результат = Текст;
    
    // Удаление задвоенных символов
    УдаляемыеСимволы = «»».,;/_»;
    
    Для Поз = 1 По СтрДлина(УдаляемыеСимволы) Цикл
    Симв = Лев(УдаляемыеСимволы, Поз);
    
    Пара = Симв + Симв;
    
    Пока СтрНайти(Результат, Пара) <> 0 Цикл
    Результат = СтрЗаменить(Результат, Пара, » «);
    КонецЦикла;
    
    КонецЦикла;
    
    // Удаление недопустимых символов в начале и конце строки:
    // Чистим слева
    УдаляемыеСимволы = «.:,;/_»;
    Работаем = Истина;
    Пока Работаем Цикл
    Симв = Лев(Результат, 1);
    Если СтрНайти(УдаляемыеСимволы, Симв) <> 0 Тогда
    Результат = Прав(Результат, СтрДлина(Результат) — 1);
    Иначе
    Работаем = Ложь;
    КонецЕсли;
    КонецЦикла;
    
    //Чистим справа
    УдаляемыеСимволы = «:,;/_»;
    Работаем = Истина;
    Пока Работаем Цикл
    Симв = Прав(Результат, 1);
    Если СтрНайти(УдаляемыеСимволы, Симв) <> 0 Тогда
    Результат = Лев(Результат, СтрДлина(Результат) — 1);
    Иначе
    Работаем = Ложь;
    КонецЕсли;
    КонецЦикла;
    
    // Удаление задвоенных пробелов
    Пока СтрНайти(Результат, »  «) <> 0 Цикл
    Результат = СтрЗаменить(Результат, »  «, » «);
    КонецЦикла;
    
    Результат = СокрЛП(Результат);
    
    Возврат Результат;
    
    КонецФункции
    

    Показать

    Reply
  28. user635667

    (24) Приветствую. В последнее время в мои торговые точки часто привозят новый ассортимент. Возникает необходимость в переименовании этих позиций. Пользуюсь данной обработкой т.к. она великолепна. НО мучает рутина постоянно нажимать Поиск, потом вставлять название которое надо переделать и так по многим позициям. Можете сделать отбор по номенклатурным группам? Например можно было бы кидать всю новую номенклатуру в корень справочника Номенклатура, а потом просто в данной обработке все разом их обработать!?!?

    Reply
  29. user635667

    ?

    Reply

Leave a Comment

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