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




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

52 Comments

  1. slas

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

    Reply
  2. GeterX

    (1) slas, а если премия квартальная, то как это сделать?

    Да и вообще расчет производится согласно положения в предприятии.

    А если расчет идет не из ФОТ, а из фиксированной суммой?

    Reply
  3. mikhailovaew

    (2) это от недостатка знаний типовых возможностей.

    а если премия квартальная, то как это сделать?

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

    А если расчет идет не из ФОТ, а из фиксированной суммой?

    Тогда описывается формула вида Результат = Сумма / Норма времени за месяц в днях * Время в днях

    Reply
  4. GeterX

    (3) mikhailovaew,

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

    С этим я согласен.

    Тогда описывается формула вида Результат = Сумма / Норма времени за месяц в днях * Время в днях

    А Вы пробовали это сделать?

    Премия у нас разовое начисление. А для разовых начислений невозможно выбрать такие показатели как «Норма времени за месяц в днях» и «Время в днях».

    Если это можно было сделать, тогда бы и обработки не было бы.

    Reply
  5. mikhailovaew

    (4)

    Премия у нас разовое начисление

    Вы, наверное, имеете в виду «дополнительное начисление» (в отличие от «основного»). Действительно, там показатели времени ввести не получится. Зато документ «Регистрация разовых начислений» позволяет ввести и рассчитать произвольное основное начисление, в котором можно описать временные показатели формулы. Минус такого решения — премии не будут выделяться в справке по расчету среднего заработка для отпусков.

    Reply
  6. super-drema

    Необходима данная обработка. Но почему-то она не доступна для скачивания… Точнее нет никаких прикрепленных файлов к публикации. Исправьте, пожалуйста.

    Reply
  7. GeterX

    (6) super-drema, обработка загружена.

    Reply
  8. super-drema

    На модуле пароль… Мдааа…

    Reply
  9. GeterX

    (8) super-drema, а зачем вам модуль? не хватает функционала?

    Reply
  10. super-drema

    Хотел подправить модуль, т.к. 1. обработка некорректно проставляет отработанное время по сотрудникам, если были перерасчеты или сторно из-за отпуска или больничного 2. Не нравиться реквизит вид учета времени (хотелось бы убрать), т.к. у меня в организации учет времени ведется как по часам, так и по дням. Не хотелось бы из-за этого реквизита делать два документа по премии. Обработка хорошая, но под конкретно мою организацию нужно ее чуток подправить. Не хочется тратить время на написания ее с нуля. Буду признателен, если вышлите пароль от модуля личным письмом или на super-drema@mail.ru. Заранее спасибо.

    Reply
  11. GeterX

    (10) super-drema, отправил. В обработку включены изменения.

    Буду признателен, если опишите конкретную ситуацию возникновения ошибки при расчете отработанного времени.

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

    Reply
  12. crypton

    Автора прошу пояснить.

    Купил.При нажатии на кнопку «Заполнить время» выдает ошибку {ВнешняяОбработка.РасчетРазовыхНачисленийПропорциональноОтработанномуВремени.МодульОбъекта(237)}: Операции сравнения на больше-меньше допустимы только для значений совпадающих примитивных типов (Булево, Число, Строка, Дата)

    Конфигурация ЗИКБУ (медицина) 74.1

    Reply
  13. GeterX

    (12) crypton, ошибка исправлена.

    Reply
  14. slas

    (2) Ваша обработка уменьшает размер месячной, квартальной, годовой премий. «А если расчет идет не из ФОТ, а из фиксированной суммой?» Фиксированная на то и фиксированная, премия без учета отработанного времени. Если нужна премия суммой с учетом времени, создаете начисление в «Основных начислениях», далее Показатель числовой и в поле Произвольная формула Показатель* ОтработаноВремениВЧасах /НормаВремениВЧасах

    Reply
  15. GeterX

    (14) slas, А если премия квартальная по итогам работы за 9 месяцев, то как Вы рассчитаете премию?

    В основных начислениях можно указать только период в пределах месяца, но не как не 9 месяцев.

    Reply
  16. slas

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

    Reply
  17. GeterX

    (16) slas, а можно поподробнее рассказать порядок расчета премии за 9 месяцев, как это сделать в программе?

    А вот скажем такая ситуация: приходит к нам руководитель и просит рассчитать сумму премии исходя из окладов сотрудников за отработанное время с учетом процента к примеру 200%.

    И при этом надо чтобы эта премия была именно за 9 месяцев и правильно отражалась при расчете среднего.

    Reply
  18. slas

    (17) Шутка такая? Читайте книги там все есть.

    Reply
  19. GeterX

    (18) slas, а вы сами это делали? Или только все в теории?

    А вообще, не нравится, не используйте, к чему весь этот разговор, если вы даже не хотите поделиться информацией?

    Reply
  20. slas

    (19) Весь этот разговор к тому, что если использовать вашу обработку, то типовая квартальная, По итогам работы за год, Месячная премии начисляются неправильно. А вы, так и бесплатно делитесь своей обработкой.

    Reply
  21. tonychidze

    Купили. ЗБУ 1.0.74.1. Подключил как дополнительную обработку по заполнению табличных частей. При вызове обработки (как из документа премии, так и из документа регистрация разовых начислений) появляется ошибка:

    Заполнение ТЧ не произведено!

    Ошибка при вызове метода контекста (ПолучитьФорму): {Форма.Форма.Форма(179,31)}: Переменная не определена (Аналит): {Форма.Форма.Форма(179,31)}

    Нашел эту часть кода в модуле формы «Форма»


    Если ?(Метаданные.Имя = «МедицинаЗарплатаИКадрыБюджетногоУчреждения», ВыборкаДетальныеЗаписи.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисленияОрганизаций.ОкладПоПКГ, Ложь) Тогда

    СведенияПКГ_Сотрудника = Аналит.ПолучитьАктуальныеСведенияПоСотруднику(Элемент.Сотрудник, ПериодРегистрации);

    Оклад = СведенияПКГ_Сотрудника[0].Оклад;

    ИначеЕсли ?(Метаданные.Имя = «МедицинаЗарплатаИКадрыБюджетногоУчреждения», ВыборкаДетальныеЗаписи.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисленияОрганизаций.а_УвеличениеОбъемаРабот, Ложь) Тогда

    ДопНачисления = ДопНачисления + ВыборкаДетальныеЗаписи.Показатель1;

    Иначе

    Оклад = ВыборкаДетальныеЗаписи.Показатель1;

    КонецЕсли;

    У нас не медицина, комментирую условие, оставляю только

    Оклад = ВыборкаДетальныеЗаписи.Показатель1;

    В таком случае появляется ошибка:

    Заполнение ТЧ не произведено!

    Ошибка при вызове метода контекста (Выполнить): {(9, 36)}: Поле не найдено «РабочееВремяРаботниковОрганизаций.а_ДокументНазначения»

    РабочееВремяРаботниковОрганизаций.<<?>>а_ДокументНазначения,

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

    На демобазе ЗБУ ошибки так же воспроизводятся.

    Reply
  22. GeterX

    (21) tonychidze, ошибка исправлена.

    Reply
  23. anna1012

    Здравствуйте!

    Купили Вашу обработку. В учреждении есть разные варианты премий, один из которых рассчитывается от единовременного денежного содержания, вид начисления создается автоматически при указании, что в базе данных будет вестись расчет содержания для государственных гражданских служащих. Начисление Первичное, формула произвольная Результат = Тарифная ставка месячная (должностной оклад) * Количество должностных окладов * Время в днях / Норма времени в днях. ФОТ исходя из ежемесячного денежного содержания не рассчитывается. Можно это исправить в ближайшее время?

    Reply
  24. GeterX

    (23) anna1012, если вы хотите производить расчет из денежного содержания, то для этого в обработке есть настройка расчетной базы, включаете туда все начисления входящие в денежное содержание.

    Если же при расчете хотите использовать количество должностных окладов, то это можно заменить процентом (т.е. 1 долж.оклад = 100%), т.о. в расчетную базу добавляете должностной оклад и указываете процент.

    Если я вас правильно понял.

    Reply
  25. anna1012

    (24) по поводу указания процента я думала, но к сожалению этот вариант не подойдет для нас. Дело в том, что у сотрудников разное количество должностных окладов (это занесено в постоянных начислениях), я не могу поставить процент одинаковый для всех сотрудников.

    Reply
  26. GeterX

    (25) anna1012, можно это описать на подробном примере?

    Reply
  27. anna1012

    (26) у сотрудников в постоянных начислениях оклад и ежемесячное денежное поощрение. ежемесячное денежное поощрение это Тарифная ставка месячная (должностной оклад) * Количество должностных окладов. В показателях ежемесячного денежного поощрения количество должностных окладов. У некоторых сотрудников ежемесячное денежное поощрение 1 должностной оклад, у других 1,6, у третьих 1,7.

    Reply
  28. GeterX

    (27) anna1012, в ближайшее время исправлю.

    Reply
  29. GeterX

    (27) anna1012, обработка исправлена.

    Reply
  30. anna1012

    (29) (29) добавила в базу для расчета ежемесячное денежное поощрение, при нажатии на кнопку ФОТ возникает ошибка — «{Форма.Форма.Форма(223)}: Индекс находится за границами массива ОкладЕДС = ДанныеОклада[0].Показатель1; «

    Reply
  31. GeterX

    (30) anna1012, в расчетной базе используется только одно начисление (ежемесячное денежное поощрение)?

    Reply
  32. anna1012

    Спасибо за доработку! Все работает!

    Reply
  33. teflon

    При покупке код модуля будет закрыт?

    Reply
  34. GeterX

    (33) teflon, по умолчанию закрыт. Но все решаемо.

    Reply
  35. teflon

    (34) в организации есть квартальная премия, рассчитываемая по следующей Формуле: Количество баллов * Стоимость балла / Норма времени * Факт Время. Хотелось бы, чтобы ваша обработка приводила показатель «Количество баллов» к отработанному времени, и заполняла в самом документе колонку этого же показателя, а не колонку с результатом.

    Думаю, что надо реализовать в обработке опцию для выбора колонки заполнения: выводить результат пересчета в колонку «Результат», либо выводить результат пересчета в колонку «Показатель» (колонка будет та же, чей показатель пересчитываем).

    Reply
  36. GeterX

    (35) teflon, она это позволяет сделать.

    Reply
  37. teflon

    (36) разобрался для чего нужен Коэффициент, но похоже обработка не правильно обрабатывает события формы на закладке настроек, т.е. не удается установить настройку с включенным только Коэффициентом, т.к. Коэффициент устанавливается всегда с процентом, что приводит к неправильному результату расчетов (результат получается всегда поделен на 100 процентов). Или я снова чего-то недопонял и делаю неправильно?

    Reply
  38. GeterX

    (37) teflon,

    В качестве показателя — Стоимость балла

    коэффициент — Количество баллов

    (230 * 12) / Норма (22) * Часы(15) = 1881,82

    Все как по Вашей формуле.

    Reply
  39. teflon

    (38) если выбрать расчет по часам, и поставить флажок Коэффициент (при этом Процент у вас ставиться всегда при этом автоматически, если снять Процент, то и Коэффициент снимается), в результате получаем все в процентах, т.е. поделенное на 100.

    Уже сам разобрался. В модуле формы подправил значимость флажков, т.е. первым сделал Коэффициент, зависимым от него Процент, поменял условия снятия/установки флажков, В процедуре расчета показателей, в случае расчета показателей по условию «Время в часах», добавил условие на расчтет по показателю коэффициент. В общем сейчас все считает как нам нужно. Спасибо за разработку.

    Reply
  40. GeterX

    (39) teflon, спасибо за найденную ошибку, обработка исправлена.

    Reply
  41. GeterX

    Пришлось поднять цену, согласно требованию http://infostart.ru/community/groups/295/forum/131199/

    Reply
  42. bandru

    Здравствуйте, купил обработку. В целом функционал устраивает, но есть несколько замечаний для нашей организации. Хотел поправить-на модуле пароль. Самое главное замечание: при расчете премии процентом в показатели для расчета начисления ставит «процент оплаты», а вместо процента размер ФОТ. Остальное по мелочи — хочется, чтобы в базу для расчета выходили по умолчанию наши виды расчета и галки в настройках при расчете алгоритма. Буду благодарен за пароль от модуля: berezhko.au <at> yandex.ru

    Reply
  43. bandru

    Также, если у работника в месяце было зарегистрировано «отсутствие по невыясненной причине», а затем больничный, то количество отработанных дней считает неверно. В пользовательском режиме лечится удалением отклонения «отсутствие по невыясненной причине». Но это уже костыль получается

    Reply
  44. GeterX

    (43) bandru,

    «Добрый день! В документ данные переносятся по принципу ФОТ -> Показатель1, Процент -> Показатель2. Перенос данных в документ реализован по типовому принципу.

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

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

    Для сохранения всех ваших настроек, есть кнопка «Сохранить значения».

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

    Дублирую текст переписки, т.к. не получил ответа.

    Reply
  45. bandru

    Оказалось, что если в одном расчетном периоде зарегистрировано «отсутствие по невыясненной причине (ОНВП)», а затем больничный, то больничный не сторнирует отсутствие. Само собой, дублируются записи в регистре и расчет времени выходит неверным. Если больничный в следующем периоде, то сторнируется и все ок.

    Причем в стандартном табеле в обоих случаях выводит правильное количество отработанного времени. На вопрос бухов «как же быть с ОНВП и больничным в одном периоде» решил пока ответить удалением расчета «ОНВП» из отклонений. Но в таком случае может неправильно учитывать время если сотрудник ОНВП и пока не имеет больничного

    Reply
  46. GeterX

    (45) bandru, мне казалось, что я уже отвечал на этот вопрос.

    В данном случае нужно только удаление ОНВП.

    Например, если сотрудник заболел 26.10.15, в программе ставим ОНВП с 26.10-31.10.

    Сотрудник приносит больничный 26.10.15-29.10.15, начисляем больничный (все в текущим месяце), сторно не происходит, а вот когда начисляем зарплату, если не удалили ОНВП, расчет получается неверным, т.к. 29.10 стоит ОНВП, Так что в таких случаях обязательно следует удалять ОНВП. Не удаленный ОНВП может повлиять на расчет среднего.

    Подумаю над этим вопросом, может удастся что-то придумать.

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

    Reply
  47. mea1c

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

    Это предусмотрено?

    Reply
  48. GeterX

    (47) mea1c, да, это настраивается отклонениями, см. скриншоты.

    Reply
  49. gordei-ac

    У меня вопрос что произошло при расчете среднего, он рассчитал ещё дополнительно 29.3. дня получился средний неправильно

    Reply
  50. GeterX

    (49) gordei-ac, не совсем понятен вопрос. Напишите вопрос более развернуто.

    Reply
  51. Dimul555

    Доброго дня. Для зуп 2.5.99.2 подойдет?

    Reply
  52. GeterX

    (51) Dimul555, на ЗУП 2.5 не тестировал.

    Reply

Leave a Comment

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