"Разрушающий" контроль (анализ актуальности движений документа)




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

32 Comments

  1. CheBurator

    плохое, лобовое решение

    Reply
  2. Evg-Lylyk

    Хорошая идея.

    Reply
  3. Ish_2

    (1) Ты бы предложил нелобовой подход. Интересно.

    Reply
  4. simol

    Зато можно узнать с какого документа начинается.

    Reply
  5. axae

    (6) Да, действительно, видимо на вопрос «с какого документа требуется перепроведение?» эта обработка сможет ответить в определенных случаях.

    (4) Но я думаю, эта обработка не для практического применения (она же ничего не изменяет в базе). Она скорее для теоретического интереса: «а где, когда и как у нас здесь начинаются косяки?»

    (5) Да конечно, никогда не отследит. Никто не отследит, не зная конкретных последовательностей документов конкретных конфигураций.

    В нашей бухгалтерии страх боятся перепроводить документы: «А вдруг изменятся оборотки? У нас уже всё сведено!». Я предложил эту идею такого контроля актуальности движений нашим админам базы данных и своему начальнику — они поддержали…

    А при такой «накатывающей» волне требуется просто перепроводить документы по партии. Для этого я админам делал другую, простую обработку перепроведения по конкретной партии, причем с выбором всего одной партии и только по бухгалтерии 8.1 — но и этого им было достаточно. А обработка «разрушающего контроля» поможет найти начало нарушения последовательности по партии (6).

    (1) А какой нелобовой подход может быть для решения задачи «какие документы при перепроведении изменят свои движения»?

    Reply
  6. Ish_2

    (5) Эээ… Ты — сразу минус…

    Лучше дождаться от автора убедительного примера в каких случаях применение обработки эффективно.

    Reply
  7. ediks

    Лично я воспринимаю данный портал как сборник идей, некую копилку (выкладывание обработок с ИТС и т.д. для накручивания рейтинга не считаем). В данном случае идея мне понравилась, хотя я пока не вижу практического применения для себя. Ну а если кому-то обработка не подошла сразу без доработки напильником, то это не повод размахивать шашкой. IMHO

    Reply
  8. CheBurator

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

    Reply
  9. rhtr

    При разработки конфы полезная приблуда))Немного под себя тисануть и у сё.))ИДЕЯ +

    Reply
  10. 8c1.ru

    Переделанная УТ 10.2.8.2, при нажатии «отобрать документы»:

    {Форма.Форма(167)}: Ошибка при вызове метода контекста (Выполнить): {(7, 2)}: Неоднозначное поле «ЧекККМ.Проведен»

    <<?>>ЧекККМ.Проведен = ИСТИНА

    Выборка = Запрос.Выполнить().Выбрать();

    по причине:

    {(7, 2)}: Неоднозначное поле «ЧекККМ.Проведен»

    <<?>>ЧекККМ.Проведен = ИСТИНА

    Reply
  11. axae

    (14) Спасибо, не люблю, когда что-то не работает 🙁 Найду УТ 10.2.8.2, посмотрю

    (13) А как при разработке конфы может пригодится?

    (11) Скорее ради идеи и писалась обработка, практическое применение обработке видимо каждый придумывает самостоятельно 😀

    Reply
  12. logarifm

    А вот теперь такое.

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

    «В данной транзакции уже были ошибки» и опля, мы имеем в итоге распроведенный документв нормальном заднем периоде, при устранении ошибки проведения мы еще имеем и не те движения так как документ может уже не те данные взять!!!

    Reply
  13. axae

    (16) Это не хорошо. Вот это не хорошо.

    Какой вариант решения может быть для обработки?

    А в таком случае придется видимо восстанавливать выгрузкой/загрузкой из копии базы документ с движениями…

    Reply
  14. logarifm

    Да нет решения. На копии разве только делать и все.

    Reply
  15. logarifm

    собственно после описанной ошибки в (16) обработка приобретает свою суть указанную в теме поста. То есть «Разрушающий»

    Reply
  16. Ish_2

    (16) Правильно ли я понял ? Проверить нет возможности.

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

    И тогда выдается сообщение «В данной транзакции уже были ошибки» ? Так ?

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

    Reply
  17. logarifm

    (21) нет не правильно поняли. Все это происходит во время работы обработки. А поскольку была отмена проведения и при следуещем проведении возникла ошибка система попытается откатать транзакцию, а вложенных транзакций 1С не поддерживает и таким образом будем иметь не проведенный документ.

    Тоесть, откат происходит сам 1С, а вот в обработке указывается ОтменаТранзакции поскольку возникли ошибки и здесь будет болт мягко говоря. 1С скажет, что уже были ошибки в данной транзакции, таким образом повторюсь, обработка сначала распровела документа в транзакции потом попыталась его провести для сравнения движений и тут во время проведения возникла ошибка, 1С откатывает автоматом данную транзакцию, а обработка видит Ошибка надо откатать транзакцию обратно и вернуть проведение в первичное состояние документа, но не судьба этому уже не быть…

    Reply
  18. logarifm

    Вот такая вот ошибка не хорошая и опасная! Уже проходил это!

    Reply
  19. Ish_2

    (22) Ок.Спасибо.

    Reply
  20. axae

    (22) Мы ведь запомнили первоначальные движения документа… Можно ли отследить эту ошибку и при ее возникновении вернуть движения документа на место прямыми записями в регистры?

    Reply
  21. simol

    (9)Более чем осведомлен и мне знакомо, что граница последовательности и то, что я написал в (6) это разные вещи(документы, даты). Это Вы скорее больше теоретик, чем практик (не примите это в обиду).

    Reply
  22. nafa

    По поводу (16) — не понимаю в чем здесь проблема? Ну распровелся документ — и что страшного. Старые движения то у нас сохранились. Записываем их назад и все.

    (Для новеньких: В 1С 8 проводками (движениями) можно управлять независимо от записи (проведения) самого документа.)

    А обработка реально очень полезная.

    Reply
  23. logarifm

    (27) А страшное в том, что документ останеться не проведенным!

    Reply
  24. nafa

    (28) Документу просто устанавливаем признак что он проведен. (Без вызова процедуры проведения).

    Reply
  25. Yashazz

    Мдя. Вообще делать проведение, которое само по себе системная транзакция, внутри объявленной транзакции — моветон. Ish_2 очень правильно всё сказал. Это будет недиагностируемое выпадание посреди процесса.

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

    Кроме того, сама обработка неряшливо сделана. Хелп почти никакой, рекомендации 1С не соблюдены, да ещё малопонятный макет про Альфа-авто болтается.

    Не ахти, в общем.

    Reply
  26. axae

    (30) Макет да, лишний здесь. А где можно ознакомиться с рекомендациями 1С?

    Reply
  27. axae

    (30) Можно и читать старые движения…

    Я думаю здесь еще есть вопрос на какой базе делается это: либо на рабочей, либо на копии. Если на рабочей, то и там и там опасность:

    В моем случае (с откатами транзакций) есть вероятность ее слетания при сбое проведения.

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

    Reply
  28. Yashazz

    (31) На дисках ИТС.

    Да и мелочей полно. Почему, например, юзверю можно всяко править дерево результатов? Жмякнет на del, потом сам через пять минут впадёт в ступор.

    (32) Будем говорить про самый экстрим (про который, например, я пишу свою обработку, чем-то похожую на вашу), считаем, что рабочая база. Некогда туда-сюда архивы делать, экспериментировать. Насчёт «увидеть новые до перезаписи старых» — да, такое возможно. Однако стоит помозговать, может, удастся и это обойти…

    Reply
  29. molot

    (30) >рекомендации 1С не соблюдены

    Да за соблюдение их стандартов вообще расстреливать надо, ес чессно… Вот это ты задвинул…

    Reply
  30. Yashazz

    (34) За советы писать директивы клиента и сервера в модуле надо расстреливать? Впрочем, сие оффтоп.

    Reply
  31. molot

    (35) Если это имелось ввиду в посте №30, то это уже не «рекомендации 1С не соблюдены», а «безграмотно закодировано».

    ЗЫ. Я никого не хотел обидеть, бо код и не смотрел даже…

    Reply
  32. Nadezhda09

    Спасибо!

    Запускаю на копии БД.

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

    Очень полезная обработка!

    Reply

Leave a Comment

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