Как мы универсально заштриховали документы




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

63 Comments

  1. yarsort

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

    В целом классно, но код128 слишком длинный для пользователя и вводить вручную для поиска тоже сложно

    Reply
  2. Mi11er

    (1)

    В целом классно, но код128 слишком длинный для пользователя и вводить вручную для поиска тоже сложно

    вот от ручного ввода конечно стоит сразу отказаться =)

    Поэтому сканер и QR это лучшее что есть, наверное по тиху будем переходить на них.

    А регистр сведений, в целом тоже крут, можно всегда получить срез последнего и прибавить 1 к коду.

    Reply
  3. RocKeR_13

    Ну это, я так понимаю, дернули из типовых конфигураций на УФ?) А компонента для формирования картинки со штрихкодом почти в каждой конфе есть в виде общего макета: там и EAN, и Code128, отдельно компонента для QR-кодов есть

    Reply
  4. pvvpvv

    Это изумительная идея. Вместо «Уникальный идентификатор + Дата» применить «Уникальный идентификатор».

    Reply
  5. pvvpvv

    +(4) «Уникальный идентификатор + Дата» называется «Ссылка».

    Reply
  6. Mi11er

    (3) Нет, просто пришло в голову как то …

    Но УФ на толкнули на мысль, я просто знаю, что там можно скопировать ссылку на объект и передать другому, чтоб тот открыл и отсюда уже понеслось.

    Reply
  7. Mi11er

    (5) Здорово.

    А дата зачем ?

    Reply
  8. pvvpvv

    Если дата не нужна — не используй. Зачем новый реквизит — «Уникальный идентификатор» . Он есть.

    Reply
  9. Tria

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

    Reply
  10. palsergeich

    Есть более интересное решение, но оно требует что бы объекты метаданных имели имена на латинице.

    По Code128 можно закодировать до 103 символов данных, это идеально подходит для следующего:

    Хранить в штрих коде не УИД ссылки, а навигационную ссылку:

    e1cib/data/Catalog.CatName?ref=947e0050568b2c2111e416f9b2fde6d6, это избавит от необходимости хранить в базе вообще какие либо дополнительные данные.

    И тогда обработка получения данных со сканера будет иметь всего одну строчку —

    ПерейтиПоНавигационнойСсылке(строка)

    Согласен, что в случае со штрих кодом это практически невыполнимо переименовать справочники и документы, но если речь пойдет о QR коде, то там такого ограничения (можно и кириллицу использовать e1cib/data/Catalog.Номенклатура?ref=947e0050568b2c2111e416f9b2fde6d6) нет

    Reply
  11. Mi11er

    (10)

    Да, это работет прекрасно, но есть одно НО

    по причине:

    Данная функция может быть вызвана только в управляемом режиме

    У меня ут 10.3, простые формы.

    Так что УИД.

    Reply
  12. Mi11er

    (9) с QR можно и попробовать так.

    Хотя и с code128 в целом можно…

    Попробуем =) Спасибо за совет.

    Reply
  13. ZLENKO

    Почему то в конфигураторе все нормально работает в макете, но при выполнении в 1С 8.3.9

    ОбластьШК.Рисунки.Штрихкод.Объект содержит значение Неопределено

    На 8.3 не работает компонент ?

    Reply
  14. Mi11er

    (13) У меня на 8.3.8 все сделано. Вроде работает.

    Reply
  15. zabaluev

    (13) Компонента «1С Штрихкод» не работает с 64 разрядной платформой. Сам пол дня потерял, после того , как поставил новую платформу и вдруг перестала работать элементарная обработка по генерации штрихкодов для бейджиков.

    Reply
  16. genayo

    В Ут11 например в штрихкоде выводится не символьный уид а его десятиричное представление. Ну и прикрутить к нему префикс к примеру для каждого вида документов дело техники.

    Reply
  17. Mi11er

    (16) Нужно будет 11 глянуть, что и как делается. Может чего позаимствовать

    Reply
  18. minimajack

    (17) все очень просто, надо не только в 10-й системе но и что бы количество символов было кратно 2-м. Тогда в кодировке Code 128C — штрихкод получается очень компактным

    Reply
  19. Mi11er

    (9) Сделал так, быстрее раз в 5 конечно =) Открытие моментальное. Спасибо за совет.

    P.s. добавить метод в статью

    Reply
  20. palsergeich

    (11) Из навигационной ссылки УИД получается перестановкой символов, имя и тип объекта метаданных там есть, просто будет не одна а 2-3 строчки кода)

    Reply
  21. DarkAn

    (1) Тоже считаю, что данное решение более простое и использовать можно простой EAN13 вместо Code128. (У нас правда регистр поменьше — 430к)

    Reply
  22. Mi11er

    (21) а на сколько быстро ищется документ ?

    По уид и имени, прям моментально открывает.

    + если испольщзуется обмен с бух к примеру, то и по идее в бух документ будет иметь такой же уид и можно его там найти

    Reply
  23. DarkAn

    (22)

    а на сколько быстро ищется документ

    «Быстро» по Вашему это сколько? Т.к. МарьИвановне из соседнего отдела 1 минута — это тоже быстро она, чай с плюшками допить не успела 🙂

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

    Зато если Ваш Code128 по произвольным причинам вдруг не будет считываться(стерся в одном месте) Вашим ТСД, то я думаю вбить цифры с EAN13 у пользователя займет гораздо меньше времени чем с Code128 🙂

    Reply
  24. nomadon

    (11) ну можно не переходить а получить ссылку и ОткрытьЗначение()

    Reply
  25. nomadon

    (10) можно русские закодировать с помощью метода КодироватьСтроку в урл, а потом обратно раскодировать.

    Reply
  26. palsergeich

    И да вместо этого

    Документы[Имя].ПолучитьСсылку(Новый УникальныйИдентификатор(УИД)).ПолучитьФорму().Открыть();

    Я бы написал так:

    ОткрытьФорму(«Документ» + [Имя]+».Форма», Новый Структура(Ключ, Документы[Имя].ПолучитьСсылку(Новый УникальныйИдентификатор(УИД)))

    Reply
  27. Mi11er

    (25) Попробуем такой метод. Пока что сделали по УИД, уже начали пользоваться, всем нравится.

    Reply
  28. Mi11er

    (26) а в чем принципиальная разница ?

    Reply
  29. dandykry

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

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

    Вообще идея хорошая.

    Reply
  30. palsergeich

    (29) Переименовываются объекты метаданных редко, ибо слишком много что в итоге приходится менять, особенно документы.

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

    Reply
  31. palsergeich

    (28) Рекомендации с ИТС

    1.1. Для открытия форм следует применять метод глобального контекста ОткрытьФорму (при использовании версии платформы 1С:Предприятие 8.2 и более ранних версий — также ОткрытьФормуМодально). Применение альтернативного способа, с получением формы и ее последующим открытием с помощью метода ПолучитьФорму, не рекомендуется. Исключения из этого правила возможны только в особых случаях (см. раздел ниже «Особые случаи использования форм»).

    Reply
  32. dandykry

    (30) Редко, но бывает. Только недавно в ERP было.

    Я тут подумал, если документ переименуется, то и тип документа так же изменится.

    С историей развития базы придется иметь где-то сопоставление Было-Стало для поддержки предыдущих штрихкодов.

    Я не ради спора пишу. Есть много способов реализации этого механизма. Я думаю о путях обхода подводных камней в будущем.

    Reply
  33. Mi11er

    (31) Понял, буду знать и внедрять, спасибо.

    Reply
  34. palsergeich

    (32) Или хардкодом в общем модуле: соответствие старое название -новое название или регистр сведений

    Reply
  35. MerwMebel

    Ребята а нельзя просто обойтись без уникального индефикатора потому что у меня он не читается сканером!

    Reply
  36. MerwMebel

    Решил реализовать всё вышеописанное в документе РеализацияТоваровУслуг

    Сам штрих код выводится в печатную форму и вроде бы все нормально, но у меня РИБ и базы индефицируются между собой номерами у которых есть префиксы в виде 5 букви они на кириллице! помогите пожалуйста не по уникальному а как-то указывать ЕАН13 заменяя его первые цифры на цифры «22» например! или назначать новый штрихкод типа как в номенклатуре что бы начинался на 200 чтоль!

    Reply
  37. acanta

    При ручном наборе цифр штрих кода можно сделать поиск по вхождению.

    Reply
  38. Infector

    На практике доказано, что 28 числовых символов достаточно, чтобы идентифицировать любой объект в системе. Если нужно идентифицировать еще и разновидности печатных форм добавляем еще 4 символа. Итого 32 числовых символа, которые превращаются в 16 символов code128 или любой другой разновидности штрихкода.

    Reply
  39. DMon

    А по-моему это очередной велосипед. Чем не устраивает типовой механизм штрих-кодирования документов, где GUID преобразуется из шестнадцатеричного в десятичный код и обратно (при поиске документа в базе)?

    Тогда не важна раскладка клавиатуры.

    Или это для чего-то экзотичного? 🙂

    Reply
  40. Mi11er

    (39) это в типовой 10.3 ?

    Reply
  41. DMon

    (40) Честно, не помню где подсмотрел, но по-моему в УТ11 (и их подобных)

    Пробежался по топику и уже встречались подсказки в эту сторону.

    Сорри за мой флуд )

    Reply
  42. Antimyslitel

    (41)

    Честно, не помню где подсмотрел, но по-моему в УТ11 (и их подобных)

    Пробежался по топику и уже встречались подсказки в эту сторону.

    Сорри за мой флуд )

    вот именно в 11 Ут есть а для 10.3 нет! Помогите пожалуйста!

    (40)

    .3 ?

    Подскажите если не сложно можно сделать что бы штрихкод был ЕАН13 а не уникальный индефикатор? и назначался по какому то алгоритму определенному?

    Reply
  43. Infector

    (42) EAN13 для кодирования документов базы — это грабли. ибо он слишком короток. Зато code128, QR и PDF417 задачу замечательно решают. Фактически при этом сам код может быть одним и тем же, но выводиться в разный формат при печати.

    Reply
  44. dmt

    (36) Будет работать при соглашении, что пользователи не могу изменить номер документа.

    1. Простое соответствие: префикс — двузначное число

    2. Год документа — двузначное число

    3. Остальные 8 цифр значащие.

    Получаем штрих код:

    10_17_00000001+контрольный символ

    Reply
  45. Mi11er

    (42) алгоритм можете задать сами. у вас для этого аж 13 цифр есть.

    к примеру

    год + номер + тип документа.

    Дальше запросом по подобию номера в пределах года ищете

    Reply
  46. Infector

    (45) Грабли. Рано или поздно окажется, что или под номер знаков мало, или под тип. А еще иногда в номера любят пихать буквы, вот тогда веселье начинается.

    Reply
  47. Mi11er

    (46) Есть такое дело

    у нас так кодировались заказы покупателя

    год + номерной префик компании + номер

    ну потом запросом легко находится. но это конечно не универсально, поэтому и задался вопросом =) и получилось что code128 идеально. Надо будет глянуть как в 11 сделано

    Reply
  48. Infector

    (47) думаю, что скоро свое решение в публикацию оформлю. Азарт, так сказать, зажгли.

    Reply
  49. Mi11er

    (48) =) Будем ждать. Как раз со след недели поеду на склад работать ,смотреть бизнес процессы и думать как ускорять их дальше. И повсеместно вводить ШК ..

    Reply
  50. Antimyslitel

    (45)

    алгоритм можете задать сами. у вас для этого аж 13 цифр есть.

    к примеру

    год + номер + тип документа.

    Дальше запросом по подобию номера в пределах года ищете

    А мне надо что бы первые две цифры были 22 потом пять цифр с права на лево номер документа без префикса и потом 6 цифр дата документа тогда получается что 13 цифр еан13 идеально получается!

    Помогите пожалуйста с кодом где его прописать какой код и как потом его считать если не сложно! очень надо!

    Reply
  51. Арчибальд

    (50) В еан13 есть только 12 цифр.

    Reply
  52. Mi11er

    (51) Вообще 13, 12 кодированные и 1 контрольный. Это если действительно так. А вообще, вот пример, как у нас был ШК для заказов покупателя http://prntscr.com/hx83sq , тут 13 цифр

    Reply
  53. Арчибальд

    (52)

    Это если действительно так

    Именно так. Я это проходил (и описывал)

    Reply
  54. Mi11er

    (50)

    Попробуйте что то вроде, код на быструю руку, поправьте что надо

    Функция ФормированияСТрокаДЛяКодирования(Ссылка)
    
    НомерДокумента = прав(Ссылка.Номер,5);
    
    н = 4;
    СтрокаНомер = «»;
    
    Пока н <> 0 Цикл
    
    СтрокаНомера = СтрокаНомера + НомерДокумента [н];
    н = н — 1;
    
    КонецЦикла;
    
    ДатаДокумента= Формат(Ссылка.Дата,»ДФ=ггММдд»);
    
    Возврат  «22» + СтрокаНомер + ДатаДокумента;
    КонецФункции

    Показать

    Reply
  55. Antimyslitel

    (52) Именно так и хочется! подскажите как это можно осуществить?

    Reply
  56. Antimyslitel

    (54)Спасибо сейчас в течении часа все это сделаю и отпишусь!

    Reply
  57. Antimyslitel

    (54)А куда надо этот код вставить?

    Reply
  58. Antimyslitel

    (54)Что то я пытался его вставить но похожей функции из темы нет!(((

    Reply
  59. ZLENKO
    Reply
  60. igo1

    Это же принцип работы из УТ 11. Ай как не хорошо =)

    Reply
  61. Mi11er

    (60) Когда я делал у себя, я еще не видел как сделано в УТ 11.

    Но у них это не 2ух мерный и не 128, они впихивают спокойно в ean13 , компактно получается.

    Reply
  62. Muxomop

    Небольшое дополнение: т.к. Code128 не может закодировать кириллицу, то вид документа можно закодировать числом.

    Например:

    Имя = Ссылка.Метаданные().Имя;
    ИндексДокумента = Метаданные.Документы.Индекс(Метаданные.Документы[Имя]);
    СтрокаДляКодирования = ИндексДокумента + «/» + Уид;
    
    Reply
  63. Mi11er

    (62)

    Интересное решение.

    Reply

Leave a Comment

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