Объединение документов




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

33 Comments

  1. CheBurator

    а пересчет, например, суммы взаиморасчетов…? фурычит? 😉

    Reply
  2. CheBurator

    у меня есть похожая мелочевочка, попроще возможностями…

    http://infostart.ru/projects/267/?ref=174

    есть возможность, например, настроил один раз схему объединения «реализаций» — и автоматом можно применить следующий раз…?

    Reply
  3. Shaman100M

    Сумму взаиморасчетов фурычит.

    Сохранение настроек — автоматом. Потом только документы подбирай.

    ссылку посмотрим

    Reply
  4. CheBurator

    О, если так — посмотрим!

    1. В объединенных доках ТЧ «сворачивается»?

    2. При «свертке» — партии сворачиваются корректно?

    3. Поддерживает пометку на удаление объединенных-ненужных?

    4. Поддерживает замену партий (ссылок)? например, если объединяется нескольо поступлений ТМЦ — в доках движения, где партии указаны явно — произвести подмену ссылок на партии поступления при необходимотси?

    Reply
  5. CheBurator

    Нифига навскидку не понял, для чего эмулируем f9…?

    Reply
  6. CheBurator

    Проводится ли пересчет данных при объединении доков с разными значениями шапок (ндс внутри, сверху, например?)

    Reply
  7. Shaman100M

    Да там все написано.

    F9 — это просто способ открыть новый документ с заполненной ТЧ (лучше открывать сохраненный, т.к. в ВводНового() возможно присвоение значений по умолчанию)

    ТЧ может сворачиваться, если указаны поля группировки или поля суммирования. В противном случае — просто объединение ТЧ объединяемых документов.

    Чтобы партии при свертке корректно сворачивались, необходимо задать две группировки : «Номенклатура» и «Партия»

    Пометки на удаление объединяемых документов нет, но это можно сделать. Просто факт необходимости удаления неявен. Раньше была галочка.

    Замена партий (ссылок) происходит неявно. Для этого группировку указать только «Номенклатура». После свертки ТЧ заполнение партий будет происходить по принципу: перебор всех значений «Партия» для данной «Номенклатуры» и заполнение первого из них не пустого.

    «Пересчет данных при объединении доков с разными значениями шапок (ндс внутри, сверху, например?)» это уже пахнет шаманством, однако, и это решаемо. «Вычисляемые поля», — задавай пересчет такой, какой нужен. Недостаток в моем решении — обрабатывается предварительная «ТЗ». по идее, здесь можно обрабатывать уже сформированный документ с корректным вызовом функций глобального модуля. Это подумаю. И будет полноценный пересчет.

    Reply
  8. CheBurator

    > F9 — это просто способ открыть новый документ с заполненной ТЧ (лучше открывать сохраненный, т.к. в ВводНового() возможно присвоение значений по умолчанию)

    ..ниче не понимаю…

    ну вот есть у тебя новый документ сформированный, записанный.. открыть его по ОткрытьФорму() — нельзя…?

    Reply
  9. Shaman100M

    можно, просто кому как нравится.

    Reply
  10. CheBurator

    ну ты великий шаман, однако…

    Reply
  11. cs25

    Shamanу спасибо !!! Бывает надобность в таких Шаманстких ert-шках !!! Плюсуем !!!

    Reply
  12. Gendalf

    Хы, за идею точно +1… действительно что-то шаманское в это есть 🙂

    Reply
  13. Shaman100M

    🙂 спасибо за оценку

    Reply
  14. Shaman100M

    исправил косячок,

    добавил реальную возможность — предварительное приведение табличной части объединяемых документов, например, для колонки «Количество», — перед ее сверткой по всем документам проконтролировать и умножить на Коэффициент (естественно, без сохранения).

    Reply
  15. YARA

    Ни дать, ни взять — ШАМАН !!!

    Reply
  16. tosha

    а нет такого же но под восьмерочку?

    Reply
  17. Khaliff

    при запуске выдает:

    Док.ДатаДок = Док3.ДатаДок;

    {F:PROG_USER1CDEMO_081EXTFORMSDOCUNION.ERT(799)}: Значение не представляет агрегатный объект (ДатаДок)

    комплексная 7.7

    Reply
  18. Shaman100M

    Спасибо. Это логическая ошибка определения документа для копирования шапки, — исправил. В случае (17): либо поля группировки по свертке ТЧ не заданы, либо реквизиты ТЧ для суммирования, — табличная часть просто объединяется, без свертки.

    Reply
  19. neobagz

    при объединении 3 доков выдает

    Если Таб1.ПолучитьЗначение(М3,»Поиск_Поле121″) <> ПоиПо Тогда

    {D:ОСТАТКИВИТ_ОБРАБОТКИDOCUNION.ERT(762)}: Номер за пределами значения!

    можешь подсказать в чем причина?

    Reply
  20. Shaman100M

    Данная строка в текущей версии обработки — 774. Обнови ее. Возможно, в текущей версии проблема решена.

    Reply
  21. pixelhead

    при объединении 3 доков выдает

    Если Таб1.ПолучитьЗначение(М3,»Поиск_Поле121″) <> ПоиПо Тогда

    {D:ОСТАТКИВИТ_ОБРАБОТКИDOCUNION.ERT(774)}: Номер за пределами значения!

    Тоже самое что и в 19 комменте только номер строки 774. Что делать?

    Reply
  22. Shaman100M

    (21) если не трудно, прикрепи скриншот обработки с параметрами

    Reply
  23. pixelhead

    Скриншот во вложении. Уже со всеми параметрами пробовал. Все рано ошибка выходит.

    Reply
  24. Shaman100M

    (23) хм… либо сворачивать по реквизиту «Цена», либо суммировать его (однако, смысла суммировать цену нет вообще — снять галку). С «Ценой» можно поступить: а) как указано на скринах, — добавить в Вычисляемое поле строку (оно доступно только для пользователя с галкой «Отключить контроль прав») Док.Цена = Док.Сумма / Док.Количество; б) не сворачивать по цене, — в этом случае в строку документа встанет первое значение цены, встретившееся для совокупности сворачиваемых реквизитов, проще говоря, цена товара из первого документа.

    Включить видимость текста вычисляемых полей — заремарить 978 строку.

    Reply
  25. Y.Tz

    Класс! Подскажите: Как организовать в ТЧ результирующего документа добавление графы с информацией из шапок объединяемых документов (например, дата документа). Пример: у нас всего одно наименование номенклатуры — Трансп.услуги. Дата услуг в ТЧ берется из шапки документа. При объединении доков все даты записываются из помеченного документа с шапкой. Вложение: Скриншот результата объединения 5 документов.

    Reply
  26. Shaman100M

    (26) Привести объединяемые документы к виду, в котором их обработка объединит, т.е. если я правильно понял — в объединяемых документах есть та же колонка, — заполнить ее датой родного документа, а при объединении указать эту колонку в полях группировки.

    Reply
  27. Y.Tz

    Так точно и делал, да указать колонку не могу, т.к. ее нет при выборе. Кстати как обнулить поля группировки? Я не просёк. Требуется простое объединение, когда все строки в ТЧ объединяемых доков просто переносятся в результирующий со всеми своими клетками. Все переносится как надо, а клетка Дата (та которая из шапки родного дока) не хочет, потому, что заполняется по образцу документа — прообраза шапки. Чего делать? Спасибо.

    Reply
  28. Shaman100M

    «нет при выборе» — значит, ее нет в табличной части документа. Возможно ли ее в таком случае заполнить?

    Reply
  29. Shaman100M

    + (29) «Требуется простое объединение» , — для этого все три поля свертки д.б. пустыми.

    Reply
  30. karbofos

    Мой бух пользует эту обработку до сих пор. Для нее это актуально. Автору большое спасибо. Самому просто лень было заморачиваться.

    Reply
  31. SAshock

    большое спасибо за труды, очень пригодилась в работе

    Reply
  32. erthia

    При попытке объединения 4 документов пишет «Не удалось записать итоговый документ». Связано ли это с тем, что автонумерация нарушена?

    Reply
  33. Shaman100M

    (33) да, это может быть. Установите рабочую дату (сервис — параметры) в периоде нумерации, в котором находился первый документ объединения, затем попробуйте создать новый документ этого вида и сохранить его.

    Reply

Leave a Comment

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