Редактирование комментариев в закрытом периоде




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-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. Re:аниматор

    Нужно руководствоваться правилами (период закрыт, всё, ни каких изменений), а не хотениями тормозных пользователей. ИМХО.

    P.S. пусть себе в блокнот пишут комментарии 🙂

    Reply
  2. ekaruk

    Бредовое решение.

    При каждом открытии сбрасывать комментарий.

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

    Reply
  3. bds22

    (2) ekaruk,

    Вы просто не поняли, как работает этот код)))

    Затирается перед открытием не комментарий, а источник данных для поля ввода, благодаря чему поле комментария становится доступным для редактирования.

    Перед закрытием программа проверяет, изменился ли комментарий.

    Никакого сообщения о том, что редактирование запрещено, не будет.

    если что-то непонятно, спрашивайте

    Reply
  4. ekaruk

    (3) В Вашем решении комментарий сохранится независимо от того, хочет ли этого пользователь.

    Даже если он нажал «закрыть».

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

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

    Даже в режиме обмена данными. Хотя бы потому, что не все механизмы, вызываемые при сохранении, могут этот режим обрабатывать.

    В общем решение плохое.

    Reply
  5. AlX0id

    Короче, прилепите свойство — и не парьтесь. Его хоть уредактироваться можно..

    Reply
  6. bds22

    (4) ekaruk,

    В Вашем решении комментарий сохранится независимо от того, хочет ли этого пользователь.

    Даже если он нажал «закрыть».

    именно так, только кнопка «закрыть» доступна. если для ваших пользователей важно, чтобы не только кнопка Закрыть была доступна, но и ОК, это не проблема сделать

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

    ошибаетесь — откроется для чтения. да и как код не сработает, если он работает в программе?)))

    В общем решение плохое.

    в нашем случае это единственный выход, пользователи довольны

    Reply
  7. bds22

    (5) AlX0id, со свойствами хорошая идея, но в любом случае свойство придется выводить в журнал документов, в ПриПолученииДанных.

    кроме комментариев данное решение у нас используется также в документе «Акт сверки»для установки пометки «Сверка согласована». т.е. в документе сверка будет не согласована, в свойствах — согласована, что вызовет путаницу

    Reply
  8. Fox-trot

    (7) правильнее было б создать отдельный регистр сведений для ваших комментариев и хоть баллады пишите.

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

    Reply
  9. bds22

    (8) Fox-trot, в данном случае это плохое предложение, даже свойства лучше — это может сделать любой пользователь без программиста. давайте не будем бросаться словами на ветер, сказали А, говорите Б (это я про грабли)

    Reply
  10. vandalsvq

    (9) не бывает «единственно верного решения», как и нет «серебрянной пули» (да простит меня Алексей). Данный вариант мне лично тоже не очень нравится, ни как он сделан, ни зачем он сделан. Конкретно не нравится перезапись документа при изменении одного лишь реквизита. Хотя другого выбора нет, но надо бы гарантировать что в модуле объекта и во всех подписках ОбменДанными.Загрузка контролируется и не произойдет изменений.

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

    Прости, но «минус». Это даже хуже перенумераторов.

    Reply
  11. bds22

    (10) vandalsvq,

    не бывает «единственно верного решения»

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

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

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

    Хотя другого выбора нет, но надо бы гарантировать что в модуле объекта и во всех подписках ОбменДанными.Загрузка контролируется и не произойдет изменений.

    в стандартной конфигурации эти проверки везде есть

    По нажатию открываешь поле ввода строки, а там уже записываешь или что надо то и делаешь.

    это лишнее действие, чем оно лучше? из журнала редактировать тоже комментарий в документе не совсем удобно

    Прости, но «минус». Это даже хуже перенумераторов.

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

    Reply
  12. bds22

    ну и последнее, что я хочу сказать по теме и почему я это разместил

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

    это решение (с возможностью редактирования реквизита документа) может быть использовано для других целей аккуратного вмешательства в конфигурацию

    спасибо за внимание

    Reply
  13. PiccaHut001

    (10) vandalsvq,

    Конкретно не нравится перезапись документа при изменении одного лишь реквизита.

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

    Reply
  14. vandalsvq

    (11) первый вариант был покруче, согласен, знатно я там «ляпнул». Стыдно, конечно. С другой стороны вспомнил я быстрее, чем мне пустили пулю в лоб 🙂

    Давай по-порядку:

    Про единственный вариант вот — сообщение (6)

    в нашем случае это единственный выход

    Если ты что другое имел в виду, скажи.

    в стандартной конфигурации эти проверки везде есть

    Пусть будет по-твоему. Со стандартными работаю, но утверждать бы не стал. Каждому свое.

    это лишнее действие, чем оно лучше? из журнала редактировать тоже комментарий в документе не совсем удобно

    Давай считать.

    Твой вариант:

    Открыли журнал документов и нашли документ -> Открыли документ -> Активизировали поле комментарий -> Изменили значение поля -> Нажали «ОК»

    Мой вариант:

    Открыли журнал документов и нашли документ -> Открыли документ -> Нажали «Редактировать комментарий» -> Изменили значение поля -> Нажали «Записать»

    При этом действие №2 не нужно если кнопка доступна и в списке документов. Не прав?

    (13) PiccaHut001, я же написал «хотя другого выбора нет». Но здесь я маленько слукавил. Другой выход есть, но надо пересматривать методику работы с реквизитом. Например выносить его за пределы документа, а пользователю отображать в документе считывая из другого места. Варианты всегда есть.

    Кстати немного хорошего в сторону автора — на самом деле прикольное решение с обнулением источника данных в элементе формы с целью открытия для изменений. Это действительно забавно придумано.

    Reply
  15. vandalsvq

    (0) кстати, если бы статья была о том как в обычной форме с установленным признаком «ТолькоПросмотр» = Истина сделать доступным реквизит без обхода по элементам, то тут безоговорочный плюс. Но, была выбрана другая подача материала. Может стоит изменить статью? Получается что вместо того чтобы увидеть смекалку автора в одном моменте, все обращают внимание на проблематику и предложенный код (оформление которого вообще за гранью добра и зла) и отсюда негодование.

    Что думаешь автор? Может на самом деле сосредоточить мнение сообщества на другом, а «обвязку» либо убрать в тень, либо вообще убрать.

    Кстати свой минус я отзову. Пояснение автора в сообщении (12), предложило другую трактовку статьи.

    Reply
  16. bds22

    (15) vandalsvq, на самом деле если бы я просто написал, что таким образом можно сделать поле доступным для редактирования, пользы от этого 0. справедливо бы на это последовал вопрос, «ну, редактируется, а зачем?)))»

    про единственный выход я написал не в тексте статьи, а в комментарии в ответ на такую фразу «При этом пользователю выдастся сообщение, что редактирование запрещено, но документ перезапишется». единственный способ записать — это установить ОбменДанными.Загрузка в Истину и после этого записать

    Reply
  17. AlX0id

    (12) аккуратным вмешательство было бы, если бы вы прикрутили дополнительную внешнюю печатную форму «Изменить комментарий», которая бы содержала ваш код. Точнее сказать, это вообще не было бы вмешательством в конфигурацию.

    Reply
  18. ARL

    Плюс за «ЭлементыФормы.Комментарий.Данные=»»;». Как то не задумывался об этом, теперь возьму на вооружение.

    P.S. Статьи всегда рассматриваю с точки зрения новых идей, а не буквальных реализаций.

    Reply
  19. Трактор

    Автор напомнил, что я тоже эту задачу когда-то решал.

    Порылся у себя в закромах и написал статью на тему этой публикации http://infostart.ru/public/313753/

    Reply
  20. kosmo0

    Об.ОбменДанными.Загрузка=Истина;

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

    Reply
  21. bds22

    (19) Трактор, у Вас совсем другое, в закрытом периоде поменять комментарий реквизит в вашем примере нельзя. Система нагружается меньше, это плюс. Обычно пользователь нажимает ОК, редко «Записать». Если же нажимает ОК, надо как-то определить, что же надо в данном случае — записать или провести, и при этом пользователь не должен быть введен в заблуждение. Уверен, что Вы это как-то учитываете, это интересный момент, напишите, как Вы это сделали

    Reply
  22. Трактор
    Обычно пользователь нажимает ОК

    (21) именно поэтому я решил, что я умнее пользователя и принял решение перепроводить только в случае, если изменены реквизиты влияющие на перепроведение или не изменены вообще. А если пользователь поменял что-то незначительное, то пусть так записывается. Эта логика описывается в процедуре ПередЗаписью. Я не настаиваю на абсолютной верности своего решения. Но пока неприятностей не было.

    Наши с тобой решения похожи. Только ты решаешь на клиенте, а я на сервере и для списка реквизитов.

    в закрытом периоде поменять комментарий реквизит в вашем примере нельзя

    Отчего ж нельзя? Можно также как у тебя написать ПередЗаписью ОбменДанными.Загрузка = Истина;

    Если СписокИзменённыхРеквизитовВызывающихПерепроведение = «» И Проведен И СписокИзменённыхРеквизитов.Количество() > 0 Тогда

    РежимЗаписи = РежимЗаписиДокумента.Запись;

    ОбменДанными.Загрузка = Истина;

    ИначеЕсли НЕ РедактированиеЗаднимЧислом и Дата < НачалоДня(ТекущаяДата()) И Не РольДоступна(«ПравоАдминистрирования») Тогда

    Сообщить(«Недостаточно прав для проведения реализации » + Номер + » » + Строка(Дата) +

    » задним числом. Изменены реквизиты: » + СписокИзменённыхРеквизитовВызывающихПерепроведение);

    Отказ = Истина;

    КонецЕсли;
    Reply
  23. mtv:)

    Хочу обратить Ваше внимание, что на Инфостарте есть еще одна публикация о редактировании реквизитов в закрытом периоде — «Есть ли жизнь в закрытом периоде? Или способ заставить работать «Обработку заполнения табличных частей» в закрытом периоде«.

    В этой публикации рассматриваются два способа:

    1. С минимальными изменениями кофигурации (добавляется всего ОДНА строка!);

    2. Без внесения изменений в конфигурацию.

    Reply
  24. dyak84

    Конечно комментарий дело нужное, но вызывают вопросы два момента первый, а после внесения комментария нужно перепроводить всю цепочку документов. Второй вопрос а будет ли работать эта схема в типовой УТ 10,3. Зарание спасибо за ответ.

    Reply
  25. dyak84

    http://infostart.ru/public/123441/ у меня не работает

    Reply
  26. DimaP

    (20) kosmo0, как это не уходят? Уходят, да ещё и изменённые в другой базе будут.

    Reply
  27. bds22

    (24) dyak84, если вопрос ко мне — будет работать в типовой. документ записывается но не перепроводится, цепочка не должна измениться

    Reply
  28. ketr

    Супер! Хитро и красиво!

    Reply
  29. Азверин

    Используя приём автора видоизменил под себя: в документе «Счет на оплату» нужно нажимать кнопку, которая меняет реквизит (на форме выведен как текст). Получилось! Респект.

    Reply

Leave a Comment

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