Стандартные доработки. Запрет изменения документов “ЗаказовПокупателей”, по которым есть движения.




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

16 Comments

  1. milkers

    Стандартные доработки. Запрет изменения документов “ЗаказовПокупателей”, по которым есть движения.

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

    Перейти к публикации

    Reply
  2. Поручик

    Про программное изменение заказа (какой-нибудь обработкой, например) забыли оба. Надо добавить соответствующий код или в модуль объекта или в подписку на событие.

    Reply
  3. milkers

    (1)(2) Отслеживается не проведение этого документа а наличие ссылок на этот документ в проводках других документов.

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

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

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

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

    Reply
  4. milkers

    (8) Ну, несмотря на объяснения, плюс ты все равно зажал. 😀

    Reply
  5. milkers

    (11) По поводу подписки. При групповой обработке заказов покупателей это очень сильно замедлит работу системы. Данный дополнительный контроль актуален именно при ручной попытки изменить документ. Так, что забирай минус обратно 😀 .

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

    Reply
  6. y22-k

    (12) Очень Сильно Это сколько?

    Можно просто настроить автоматическую синхронизацию ЗАКАЗ — РТУ или в обратную сторону. или использовать Схему ЗАКАЗ — Корректировка -РТУ

    Reply
  7. milkers

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

    Reply
  8. milkers

    (13) А на счет автоматической синхронизации, никак не могу понять, что Вы имеете в виду.

    Reply
  9. Sintson

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

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

    Reply
  10. simuljakr

    (16) А как Вы решили подобную проблему, если не секрет ?

    Reply
  11. milkers

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

    Reply
  12. Sintson

    (18) Прошу прощения, я не разобрался в какой момент времени вызывается тотальная проверка на движения документа.

    (17) Запретили изменять проведенный документ пользователям без полных прав.

    Reply
  13. milkers

    (18) Этот вариант хуже, так как на этого пользователя сваливается дополнительная нагрузка.

    Reply
  14. wwizard

    а зачем оно надо?

    Reply
  15. 1c-intelligence

    Способ хорош простотой своей реализации, но есть ряд вопросов/предложений:

    1. ЭтаФорма.ТолькоПросмотр = Истина оставляет доступными некоторые кнопки на командных панелях. Например, кнопки заполнения ТЧ. При этом документ удастся записать, т.к. при закрытии форма спросит «Записать?»;

    2. Если типовое решение используется нормально, то используются также документы «КорректировкаЗаказаПокупателя», «ИзменениеЗаказаПокупателя». С их помощью удастся внести изменения.

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

    Я делал подобное для заказов поставщику, там было так:

    1. Подписка ПриЗаписи для регистра накопления ЗаказыПоставщикам (ПриЗаписи, потому что записываемый набор уже в БД и читается запросом);

    2. В обработчике подписки просто проверяются остатки регистра по этому заказу.

    3. Если остатки отрицательные, ставится Отказ.

    В чем смысл:

    1. Работает от любого документа (сам заказ, корректировка, ПТиУ, и т.д.);

    2. Контролирует как обычное превышение, так и расхождение аналитики (как правило — цена или ставка НДС). В заказе цена стоит 100 р., в ПТиУ указали 101 — все, система фиксирует отрицательный остаток, т.к. контроль идет по всем измерениям;

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

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

    Такое же решение работает для заказа на производство и внутреннего заказа. По заказу покупателя не делал, т.к. потребности не было.

    Reply
  16. Polzavatel

    Подскажите, как запретить в «Реализации товар и услуг» изменение Менеджерами (роль) документа, если в статусе документа кладовщик (роль) установил статус «Отгружен».

    Reply

Leave a Comment

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