АЦРК: Автоматический запрет редактирования для пользователей УТ 10.3




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

28 Comments

  1. reynagroup

    С точки зрения бухгалтерского учёта — не совсем правильно изменять документы в прошлом периоде.

    необходимо сторнировать.

    Reply
  2. Поручик

    http://infostart.ru/public/71590/

    Там же есть и список аналогичных работ.

    Reply
  3. acrk

    (2) Прямой аналог только один — Мотива… Но он гораздо круче, поэтому платный.

    Зато здесь минимальные изменения, вносимые в код разработчика: 1 строка, меньше не бывает.

    Reply
  4. metakot

    В рознице работает без проблем, как раз искал подобное

    Reply
  5. trunix

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

    Reply
  6. acrk

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

    Reply
  7. esa35
    eAkademik пишет:

    В рознице работает без проблем, как раз искал подобное

    у меня в Рознице 8.2 не работает((( подскажите как быть. у меня почему то кассиры (с ролью РМК) спокойно проводят предыдущий день, а старые документы(предыдущего месяца) не могут. бьюсь и не пойму в чем проблема. дата запртеа ставится, но они все равно могут изменить(((

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

    Если л_УстановитьЗапрет Тогда

    КолДней = Число(Константы.КоличествоДнейЗапрета.Получить());

    л_Запись = РегистрыСведений.ГраницыЗапретаИзмененияДанных.СоздатьМенеджерЗаписи();

    л_Запись.Пользователь = л_ТекущийПользователь;

    //л_Запись.ГраницаЗапретаИзменений = НачалоДня(НачалоДня(ТекущаяДата())-60);

    л_Запись.ГраницаЗапретаИзменений = НачалоДня(НачалоДня(ТекущаяДата())-(60+86400*КолДней));

    Сообщить(КолДней);

    л_Запись.Записать();

    КонецЕсли;

    ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных();

    кто подскажет что может быть не так?

    Reply
  8. dynamite

    Я что то не то делаю скорее всего и у меня выходит ошибка при запуске

    {МодульОбычногоПриложения(206,3)}: Переменная не определена (АЦРК_Привилегированный)

    <<?>>АЦРК_Привилегированный.ЗакрытиеПредыдущегоДня(); //АЦРК

    Reply
  9. acrk

    (8) dynamite,

    АЦРК_Привилегированный — это общий модуль. Проверьте его свойства, внимательно по инструкции.

    Reply
  10. dynamite

    вроде все сделал по инструкции. Создал общий модель «АЦРК_Привилегированный» в свойствах установил галочки в «Привилегированный» и «Сервер», в новосозданном модуле с копировал это

    Процедура ЗакрытиеПредыдущегоДня() Экспорт

    // НЕ зхакрывает предыдущий день если установлено право пользователя «Автоматически НЕ закрывать предыдущий день»

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

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

    // «Автоматически НЕ закрывать предыдущий день» не установлена.

    л_Право = ПланыВидовХарактеристик.ПраваПользователей.НайтиПоНаименованию(«Автоматически НЕ закрывать предыдущий день»);

    //л_Право = ПланыВидовХарактеристик.ПраваПользователей.НайтиПоНаименованию(«Автоматически закрывать предыдущий день»);

    Если л_Право.Пустая() Тогда

    // если такой настройки в принципе в базе нет, то ничего и не делаем

    Возврат;

    КонецЕсли;

    л_ТекущийПользователь = УправлениеПользователями.ОпределитьТекущегоПользователя();

    Запрос = Новый Запрос;

    Запрос.Текст = «ВЫБРАТЬ

    | ЗначенияДополнительныхПравПользователя.Значение

    |ИЗ

    | РегистрСведений.ЗначенияДополнительныхПравПользователя КАК ЗначенияДополнительныхПравПользователя

    |ГДЕ

    | ЗначенияДополнительныхПравПользователя.Пользователь = &Пользователь

    | И ЗначенияДополнительныхПравПользователя.Право = &Право»;

    Запрос.УстановитьПараметр(«Пользователь», л_ТекущийПользователь);

    Запрос.УстановитьПараметр(«Право», л_Право);

    Результат = Запрос.Выполнить();

    Если Результат.Пустой() Тогда

    л_УстановитьЗапрет = Истина;

    Иначе

    Выборка = Результат.Выбрать();

    Выборка.Следующий();

    л_УстановитьЗапрет = НЕ Выборка.Значение;

    КонецЕсли;

    Если л_УстановитьЗапрет Тогда

    л_Запись = РегистрыСведений.ГраницыЗапретаИзмененияДанных.СоздатьМенеджерЗаписи();

    л_Запись.Пользователь = л_ТекущийПользователь;

    л_Запись.ГраницаЗапретаИзменений = НачалоДня(НачалоДня(ТекущаяДата())-60);

    л_Запись.Записать();

    КонецЕсли;

    ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных();

    КонецПроцедуры

    вроде и все. А так же в модуле обычного приложении перед окончанием процедуры «ПриНачалеРаботыСистемы» вставил это

    АЦРК_Привилегированный.ЗакрытиеПредыдущегоДня(); //АЦРК

    может я что то не да понял или еще что надо дописать

    Reply
  11. dynamite

    все нашел ошибку, просто надо было в общем модуле свойствах поставит галочку не в привилегированный а в Клиент (обычное приложении)

    всем спасибо!

    Reply
  12. Bud78

    Установил на последней версии УТ (10.3.19.3).

    дата запрета не устанавливается 🙁

    Reply
  13. acrk

    (12) Bud78,

    Специально проверил на релизе 10.3.19.3 — все работает.

    Причина скорее всего в том, что у пользователя, которого вы проверяете, установлены полные права. На таких запрет не действует. На мой взгляд это неправильно, но это уже вопрос к 1С.

    Но ведь логично же не давать полные права тем пользователям, которых вы хотите ограничить.

    Reply
  14. Bud78

    Проверяю на пользователях. у которых нету полных прав.

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

    Reply
  15. acrk

    (14) Bud78,

    у модуля галка «Привилегированный» установлена ?

    Reply
  16. azeraus

    Помогите пожалуйста, сделал все по инструкции, но выдает ошибку

    {ОбщийМодуль.АЦРК_Привилегированный.Модуль(13)}: Метод объекта не обнаружен (ОпределитьТекущегоПользователя)

    л_ТекущийПользователь = УправлениеПользователями.ОпределитьТекущегоПользователя();

    Reply
  17. acrk

    (16) azeraus,

    У вас точно УТ 10.3 ?

    А то может вы это в УТ 11 проделали ?

    Reply
  18. azeraus

    (17) У меня стоит Управление торговлей для Казахстана локализация САПА версия 2.2.12.7, платформа 8.2.14.537

    Это может как то повлиять?

    Reply
  19. acrk

    (18) azeraus,

    Не знаю. Наверное может. Может они там все процедуры экспортные переименовали.

    Надо смотреть.

    Вы сами можете посмотреть, есть ли в конфигурации общий модуль «УправлениеПользователями» (судя по сообщению — есть) и есть ли в нем процедура «ОпределитьТекущегоПользователя» (судя по сообщению — нет).

    Reply
  20. azeraus

    (19) Все точно так как вы написали, есть общий модуль «УправлениеПользователями», но нет процедура «ОпределитьТекущегоПользователя», посоветуйте как быть, сам я не программист, но нееемного разбираюсь в 1С 🙂

    Reply
  21. acrk

    (20) azeraus,

    вышлите модуль на info@acrk.ru

    Reply
  22. LexBG

    Спасибо огромное! Как раз стояла такая задача, сэкономил массу времени!

    Reply
  23. xoxmaister

    Отлично написано! очень подробно! Спасибо большое!

    Reply
  24. masik85

    Спасибо огромное за разработку!! Во- первых очень интересный метод , с помощью ПлановВидовХарактеристик. Мне Ваш способ понравился больше всего.Мало изменений и практически одноразово в конфе, все остальное можно добавлять через меню. Просто молодец! Переделаю под УПП. Единственно , наверное еще переделаю чтобы «галки» ставить тем у кого обрубать период, их меньше. Остальные по общей дате практически умещаются. В любом случае Спасибо огромное! за труд, за идею, за воплощение.

    Reply
  25. acrk

    (24) masik85,

    В первом варианте так и было — галочки ставились тем, кому надо обрубать период.

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

    Тем более, если у Вас УПП, значит пользователей много, текучка есть. Один кладовщик уволился, другой пришел. Нового пользователя создали, а галочки установить забыли — период не закрылся.

    А так он зароется автоматически по вчерашний день.

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

    Reply
  26. makskov

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

    Reply
  27. acrk

    (26) Смысл в публикации в том, чтобы с минимальным вмешательством решить поставленную задачу.

    А в поставленной задаче не было пункта, чтобы «кроме одного».

    Вашу задачу тоже можно решить, но это надо уже глубже в конфигурацию лезть.

    Reply
  28. makskov

    (27) я понял, спасибо

    Reply

Leave a Comment

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