<?php // Полная загрузка сервисных книжек, создан 2025-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='\
Обработка очень понравилась, но… к сожалению, неправильно расчитывает дни компенсации, если у сотрудников большая задолженность по отпускам ( не ходили в отпуск более года — 2,3). У меня на одном предприятии такая картина сложилась, и когда применил эту обработку, то количество дней не совпало с реальным, рассчитанным вручную (показала меньше дгней, чем надо).
Хотелось бы конкретный пример, чтобы ошибку можно было найти и обезвредить: дата приема сотрудника, какие отклонения были.
А пока можно на демо-базе проверить.
Например, Антонов принят на работу 01.01.06. Делаем приказ об увольнении 01.02.08. Получаем 58.33, что правильно, т.к. он не был в отпуске 2 года и 1 месяц.
Не могу скачать обработку!!!!
Проверил. Скачивается.
Может у меня не все настроено?! Жму на обработу — появляется слово Скачать. и все. Дальше никуда не идет…
Давайте e-mail — отправлю.
я что то не понял а где обработка ?????
medik1976@mail.ru
А рассчитывает все же не верно. Вот пример: Сотрудник увольняется 08.05.08. Начислить компенсацию нужно за период с 06.06.07 по 08.05.08, т.е. 28 дней. Ваша обработка считает почему-то 56, т.е. в два раза больше.
Открыл демо-базу ЗиК. Сделал приказ о приеме на работу Лукина Ю.Н. с 06.06.07. Делаю приказ об увольнении с 08.05.08. Обработка выдает 28 дней, т.е. правильно.
Сейчас скачал свежую обработку. Опять считает неверно, т.е. 56 дней!!!
Послушайте, я же не придумываю это. Говорю что есть. Значит в некоторых ситуациях обработка отрабатывает некорректно.
И еще. Вы бы попробовали ситуацию другую. Т.е. приказ о приеме, не 06.06.07, а раньше, потом отпуск, а вот потом уже увольнение. Может здесь что-то некорректно отрабатывает?
Вот более подробно:
Сотрудник принят на работу 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.
Посмотрел по коду и отладчику. Количество отработанных месяцев начинает считаться с даты приема, что неверно, т.к. человек гулял свои отпуска.
Поэтому когда Вы делаете приказ о приеме 06.06.07 у Вас все корректно отрабатывает. А вот шаг в сторону и …. ошибка. Желательно исправить. Полезная вещь
Опять взял демо-базу. Принял Лукина на работу 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;
Ну вот что в отладчике дает эта формула, для того случая, который я описал Выше:
ДнейКомпенсацииОтпуска = 36*28/12 — 28 — 0 = 56.
Давайте все же разберемся, в чем может быть дело…
А может быть дело в том, что на самый первый отпуск документа Начисление отпуска нет, т.к. база новая и есть только приказ на отпуск? Поэтому и не учитывается этот отпуск как отгулянный? Если так, то, на мой взгляд, целесообразно добавить выборку и по приказам на отпуск, а не только по начислению отпуска
Да, ПриказПоОтпуску никак не учитывается. Потому что он в начислениях не участвует и в некоторых организациях им совсем не пользуются.
Итак, проблема не в моем алгоритме.
Проблема в том, что в Вашей базе учет ведется не за весь период. И надо как-то сообщить ЗиК об отпусках до начала ведения учета в программе.
Вы для этого решили ввести приказы на отпуск. Другим такие приказы вводить будет лень и они, например, введут в справочнике сотрудников число дней отпуска до начала учета в программе. Или что-то еще. Сомнительно, что можно сделать универсальную обработку для всех этих случаев. Проще взять мою обработку за основу и настроить на нюансы конкретного предприятия.
Благодарю Вас за плодотворное обсуждение.
На самом деле проблема все же в алгоритме, т.к. даже у 1С в их документах универсальность все же некая прослеживается. По крайней мере 1С делает выборку по всем возможным документам, а не по какому-то одному конкретному. Да и если Вы добавите выборку по всем возможным документам отпуска, то ценность и универсальность Вашего алгоритма только повысится. Конечно, на всех не угодишь, но подавляющее большинство организаций все же когда нибудь начинают новую базу, оставляя приказы. Приказы заводить все равно нужно, т.к. иначе не будет правильно формироваться Т2. Ну да дело ваше, просто, повторюсь, добавив и эту выборку ваш алгоритм только выиграл бы…
Идея отличная! Замечания на будущее:
1) Не учитывается, что при наличии инвалидности продолжительность отпуска 30 дней, а не 28.
2) Отбор записей по ЖР проблематичен из-за того, что ЖР зачастую не отражает весь период работы сотрудника и, бывает, его «чистят» для уменьшения размера базы. Перспективней использовать для поиска отпусков документы, по аналогии с алгоритмом формы Т-2 ЗиК, тогда для корректной работы за периоды, когда расчет в ЗиК не велся, достаточно ввести задним числом приказы на отпуск, отражающие условия сотрудников, принятых до начала работы в ЗиК.
3) после расчета не мешает перерисовать видимость измененных реквизитов в форме.
еще одна проблема- если отпуск начислялся документом ВводЛюбогоРасчета — вываливается с ошибкой на «поле агрегатного объекта не обнаружено» т.к. видрасчета в этом документе нет.
2 isn
Документа ВводЛюбогоРасчета в типовой ЗиК нет. Если вы ЗиК переделываете, то и обработку исправляйте.
2 Gsokolov
1) Спасибо за подсказку. Отпуск 30 дней не только у инвалидов, но и у пожилых людей. Отпуск 31 день у работников до 18 лет. Пока не совсем понимаю, как учесть наступление инвалидности в периоде подсчета стажа. Подумаю.
2) В первой версии обработки подсчет шел по документам. Во второй я от документов отказался из-за трудоемкости учета исправлений. Подумаю еще, поглядывая в сторону Т-2. Но быстро не получится — пока нет ни времени, ни клиента, которому это нужно…
3) Зачем?
Учтены изменения по отпускам за свой счет, внесенные в ТК 22.07.08.
Установила обработку. При попытке создать приказ об увольнении вылетает ошибка — не найден модуль обработки Считать дни компенсации (606). Что не так сделала, если у всех работает?
Плюс поставила, но! так и не учтено, что длина отпуска м.б. не 28 дней. 🙁
(24) Наверное, пункт 1 инструкции не выполнили — текст процедуры СчитатьДниКомпенсации() в модуль формы документа не вставили. Процедура должна быть где-нибудь в начале модуля, раньше, чем она вызывается.
Не могу установить обработку выдает ошибку
СчитатьДниКомпенсации<<?>>();
{Документ.ПриказОбУвольнении.Форма.Модуль(618)}: Процедура не обнаружена (СчитатьДниКомпенсации)
Подскажите,как ее устранить
Большое спасибо, очень пригодилось.
так и не учтено, что длина отпуска м.б. не 28 дней.
В принципе, на сколько я понимаю, можно добавить на форму поле, в которое «ручками» вводится кол-во дней отпуска, если оно отличное от 28, передается в переменную N, и в формуле
ДнейКомпенсацииОтпуска = Месяцев*28/12 — ДнейОтпуска7 — ДнейОтпуска6*28/24;
«28» заменяется на эту переменную.
Если не права, подправьте;-) На досуге попробую провернуть сей финт)
Спасибо
Спасибо