Расчет дней компенсации за неиспользованный отпуск в приказе об увольнении (ЗиК)




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

31 Comments

  1. Boroda

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

    Reply
  2. Antia

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

    А пока можно на демо-базе проверить.

    Например, Антонов принят на работу 01.01.06. Делаем приказ об увольнении 01.02.08. Получаем 58.33, что правильно, т.к. он не был в отпуске 2 года и 1 месяц.

    Reply
  3. irisha

    Не могу скачать обработку!!!!

    Reply
  4. Antia

    Проверил. Скачивается.

    Reply
  5. irisha

    Может у меня не все настроено?! Жму на обработу — появляется слово Скачать. и все. Дальше никуда не идет…

    Reply
  6. Antia

    Давайте e-mail — отправлю.

    Reply
  7. medik1976

    я что то не понял а где обработка ?????

    medik1976@mail.ru

    Reply
  8. buh

    А рассчитывает все же не верно. Вот пример: Сотрудник увольняется 08.05.08. Начислить компенсацию нужно за период с 06.06.07 по 08.05.08, т.е. 28 дней. Ваша обработка считает почему-то 56, т.е. в два раза больше.

    Reply
  9. Antia

    Открыл демо-базу ЗиК. Сделал приказ о приеме на работу Лукина Ю.Н. с 06.06.07. Делаю приказ об увольнении с 08.05.08. Обработка выдает 28 дней, т.е. правильно.

    Reply
  10. buh

    Сейчас скачал свежую обработку. Опять считает неверно, т.е. 56 дней!!!

    Послушайте, я же не придумываю это. Говорю что есть. Значит в некоторых ситуациях обработка отрабатывает некорректно.

    И еще. Вы бы попробовали ситуацию другую. Т.е. приказ о приеме, не 06.06.07, а раньше, потом отпуск, а вот потом уже увольнение. Может здесь что-то некорректно отрабатывает?

    Reply
  11. buh

    Вот более подробно:

    Сотрудник принят на работу 06.06.05.

    Отпуск за период 06.06.05 — 05.06.06 отгулял с 01.08.06 по 28.08.06

    Отпуск за период 06.06.06 — 05.06.07 отгулял с 24.12.07 по 26.01.08

    08.05.08 — увольняется.

    Вот здесь обработка и считает 56 дней вместо 28.

    Reply
  12. buh

    Посмотрел по коду и отладчику. Количество отработанных месяцев начинает считаться с даты приема, что неверно, т.к. человек гулял свои отпуска.

    Поэтому когда Вы делаете приказ о приеме 06.06.07 у Вас все корректно отрабатывает. А вот шаг в сторону и …. ошибка. Желательно исправить. Полезная вещь

    Reply
  13. Antia

    Опять взял демо-базу. Принял Лукина на работу 06.06.05. Сделал НачислениеОтпуска с 01.08.06 по 28.08.06. Сделал НачислениеОтпуска с 24.12.07 по 26.01.08. Увольняю 08.05.08 — получаю 28 дней компенсации.

    Да, подсчет начинается с даты приема. Но ранее использованные отпуска потом учитываются в строках:

    // Вычитаем использованные ранее дни отпуска

    ДнейКомпенсацииОтпуска = Месяцев*28/12 — ДнейОтпуска7 — ДнейОтпуска6*28/24;

    Reply
  14. buh

    Ну вот что в отладчике дает эта формула, для того случая, который я описал Выше:

    ДнейКомпенсацииОтпуска = 36*28/12 — 28 — 0 = 56.

    Давайте все же разберемся, в чем может быть дело…

    Reply
  15. buh

    А может быть дело в том, что на самый первый отпуск документа Начисление отпуска нет, т.к. база новая и есть только приказ на отпуск? Поэтому и не учитывается этот отпуск как отгулянный? Если так, то, на мой взгляд, целесообразно добавить выборку и по приказам на отпуск, а не только по начислению отпуска

    Reply
  16. Antia

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

    Reply
  17. Antia

    Итак, проблема не в моем алгоритме.

    Проблема в том, что в Вашей базе учет ведется не за весь период. И надо как-то сообщить ЗиК об отпусках до начала ведения учета в программе.

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

    Благодарю Вас за плодотворное обсуждение.

    Reply
  18. buh

    На самом деле проблема все же в алгоритме, т.к. даже у 1С в их документах универсальность все же некая прослеживается. По крайней мере 1С делает выборку по всем возможным документам, а не по какому-то одному конкретному. Да и если Вы добавите выборку по всем возможным документам отпуска, то ценность и универсальность Вашего алгоритма только повысится. Конечно, на всех не угодишь, но подавляющее большинство организаций все же когда нибудь начинают новую базу, оставляя приказы. Приказы заводить все равно нужно, т.к. иначе не будет правильно формироваться Т2. Ну да дело ваше, просто, повторюсь, добавив и эту выборку ваш алгоритм только выиграл бы…

    Reply
  19. GSokolov

    Идея отличная! Замечания на будущее:

    1) Не учитывается, что при наличии инвалидности продолжительность отпуска 30 дней, а не 28.

    2) Отбор записей по ЖР проблематичен из-за того, что ЖР зачастую не отражает весь период работы сотрудника и, бывает, его «чистят» для уменьшения размера базы. Перспективней использовать для поиска отпусков документы, по аналогии с алгоритмом формы Т-2 ЗиК, тогда для корректной работы за периоды, когда расчет в ЗиК не велся, достаточно ввести задним числом приказы на отпуск, отражающие условия сотрудников, принятых до начала работы в ЗиК.

    3) после расчета не мешает перерисовать видимость измененных реквизитов в форме.

    Reply
  20. isn

    еще одна проблема- если отпуск начислялся документом ВводЛюбогоРасчета — вываливается с ошибкой на «поле агрегатного объекта не обнаружено» т.к. видрасчета в этом документе нет.

    Reply
  21. Antia

    2 isn

    Документа ВводЛюбогоРасчета в типовой ЗиК нет. Если вы ЗиК переделываете, то и обработку исправляйте.

    Reply
  22. Antia

    2 Gsokolov

    1) Спасибо за подсказку. Отпуск 30 дней не только у инвалидов, но и у пожилых людей. Отпуск 31 день у работников до 18 лет. Пока не совсем понимаю, как учесть наступление инвалидности в периоде подсчета стажа. Подумаю.

    2) В первой версии обработки подсчет шел по документам. Во второй я от документов отказался из-за трудоемкости учета исправлений. Подумаю еще, поглядывая в сторону Т-2. Но быстро не получится — пока нет ни времени, ни клиента, которому это нужно…

    3) Зачем?

    Reply
  23. Antia

    Учтены изменения по отпускам за свой счет, внесенные в ТК 22.07.08.

    Reply
  24. Solo1

    Установила обработку. При попытке создать приказ об увольнении вылетает ошибка — не найден модуль обработки Считать дни компенсации (606). Что не так сделала, если у всех работает?

    Reply
  25. Svetlana_E

    Плюс поставила, но! так и не учтено, что длина отпуска м.б. не 28 дней. 🙁

    Reply
  26. Antia

    (24) Наверное, пункт 1 инструкции не выполнили — текст процедуры СчитатьДниКомпенсации() в модуль формы документа не вставили. Процедура должна быть где-нибудь в начале модуля, раньше, чем она вызывается.

    Reply
  27. lushka712

    Не могу установить обработку выдает ошибку

    СчитатьДниКомпенсации<<?>>();

    {Документ.ПриказОбУвольнении.Форма.Модуль(618)}: Процедура не обнаружена (СчитатьДниКомпенсации)

    Подскажите,как ее устранить

    Reply
  28. pencil

    Большое спасибо, очень пригодилось.

    Reply
  29. hate86
    Svetlana_E пишет:

    так и не учтено, что длина отпуска м.б. не 28 дней.

    В принципе, на сколько я понимаю, можно добавить на форму поле, в которое «ручками» вводится кол-во дней отпуска, если оно отличное от 28, передается в переменную N, и в формуле

    Antia пишет:

    ДнейКомпенсацииОтпуска = Месяцев*28/12 — ДнейОтпуска7 — ДнейОтпуска6*28/24;

    «28» заменяется на эту переменную.

    Если не права, подправьте;-) На досуге попробую провернуть сей финт)

    Reply
  30. safia-med

    Спасибо

    Reply
  31. Anzhey

    Спасибо

    Reply

Leave a Comment

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