Приветствуем вас, уважаемые коллеги! Сегодня мы разберем одну из классических и в то же время сложных задач автоматизации расчета заработной платы в программе «1С:Зарплата и управление персоналом» редакции 2.5. Несмотря на то что редакция 2.5 уже давно считается устаревшей, на практике множество производственных предприятий продолжают использовать ее механизмы из-за высокой кастомизации под свои нужды.
Рассмотрим ситуацию, когда сотрудникам установлена повременно-сдельная система оплаты труда с гарантированным минимумом. Бизнес-логика выглядит следующим образом: сотруднику гарантированно выплачивается стабильный оклад (повременная часть), но если его фактическая сдельная выработка за месяц оказалась больше оклада, то ему выплачивается оклад плюс разница между сделкой и окладом. Если же сделка оказалась меньше оклада, выплачивается просто оклад.
Для реализации этой схемы в программе часто настраивают специальный вид расчета с формулой, анализирующей разницу между сдельной выработкой и рассчитанным окладом. Все работает идеально до тех пор, пока сотрудник не подвергается кадровому перемещению в середине месяца. В этот момент расчет «ломается»: по новому начислению программа выдает нулевой результат. Давайте подробно разберем, почему так происходит, и найдем наиболее эффективные пути решения этой проблемы.
Проанализируем техническое поведение программы. Когда в середине расчетного месяца проводится документ Кадровое перемещение организаций, происходит разделение расчетного периода на два подпериода (до даты перемещения и после). Для каждого подпериода программа пытается рассчитать запись в регистре расчета отдельно.
Сбой происходит по трем ключевым причинам:
Сдельная выработка накапливается за весь месяц. В формуле расчета за подпериод программа пытается сопоставить общую сдельную выработку за месяц с окладом, начисленным только за часть месяца. Поскольку агрегатные функции вроде СУММА() внутри формул начислений в 1С использовать напрямую невозможно, механизм распределения показателей либо задваивает вычитаемые суммы, либо полностью обнуляет результат из-за несоответствия интервалов.Ниже представлена исходная формула, которая отлично работает при стабильном месяце, но дает сбой при перемещении:
Результат = ?((Сдельная выработка - (Тарифная ставка часовая / Норма времени в часах * Отработано времени в часах )) > 0, (Сдельная выработка - (Тарифная ставка часовая / Норма времени в часах * Отработано времени в часах)), 0)
Давайте выясним, как обойти данные ограничения архитектуры 1С:ЗУП 2.5.
Самый надежный и архитектурно правильный способ решить проблему пересечения и вытеснения времени — исключить «Оплату по производственному заданию» из списка основных начислений и сделать ее дополнительным начислением.
Поскольку дополнительные начисления не имеют собственного Фактического периода действия (ФПД) и рассчитываются поверх основного времени, они не будут конфликтовать с окладом при кадровых изменениях. Выполним настройку по шагам:
Дополнительные начисления организаций и создадим новый вид расчета «Оплата по производственному заданию (доплата)».Отработано времени в часах и Норма времени в часах брались из данных основного начисления (оклада).После этой настройки при проведении кадрового перемещения оклад сотрудника будет рассчитываться по двум строкам (до и после перемещения), а дополнительное начисление рассчитается одной строкой за весь месяц, корректно сопоставив общую сдельную выработку с суммой окладов за все периоды месяца.
Если по каким-то причинам перевести начисление в дополнительные невозможно, и оно должно оставаться в списке основных начислений, нам потребуется правильно зарегистрировать факт кадрового перемещения. Разберем, как это сделать:
Кадровое перемещение организаций, зарегистрировавший перевод сотрудника в середине месяца.Если этого не сделать, программа посчитает, что с даты перемещения данное плановое начисление прекращает свое действие, и во втором периоде расчет просто не запустится, выдав итоговый ноль.
Если кадровые перемещения на предприятии происходят нечасто, и вам нужно быстро получить верный расчет без изменения конфигурации и настроек видов расчета, можно прибегнуть к ручной корректировке непосредственно в документе расчета зарплаты. Проанализируем этот алгоритм:
Начисление зарплаты сотрудникам организаций.В этом случае программа увидит цельный период, корректно соберет всю сдельную выработку за месяц и вычтет из нее суммарную величину оклада за оба подпериода (так как отработанное время в формуле за полный месяц соберется в полном объеме). Мы получим математически верный результат, удовлетворяющий условиям задачи.
Если на предприятии настроен автоматический расчет и ручные корректировки исключены, потребуется небольшая доработка с привлечением программиста 1С. Выясним причину технического ограничения: в формулах начислений нельзя использовать конструкции агрегации данных по регистру расчета за весь месяц.
Решением является создание дополнительного предопределенного показателя, например, ВсегоНачисленоПоОкладуЗаМесяц. Программисту необходимо внести изменения в модуль расчета (как правило, это модуль объекта документа НачислениеЗарплатыСотрудникамОрганизаций):
// Примерный алгоритм сбора оклада для передачи в показатель
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СУММА(ОсновныеНачисления.Результат) КАК РезультатОклада
|ИЗ
| РегистрРасчета.ОсновныеНачисленияОрганизаций КАК ОсновныеНачисления
|ГДЕ
| ОсновныеНачисления.Сотрудник = &Сотрудник
| И ОсновныеНачисления.ПериодРегистрации = &ПериодРегистрации
| И ОсновныеНачисления.ВидРасчета = &ВидРасчетаОклад";
Запрос.УстановитьПараметр("Сотрудник", ТекущийСотрудник);
Запрос.УстановитьПараметр("ПериодРегистрации", ПериодРегистрации);
Запрос.УстановитьПараметр("ВидРасчетаОклад", ПланыВидовРасчета.ОсновныеНачисленияОрганизаций.ОкладПоЧасам);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Полученное значение передается в таблицу показателей для расчета формулы
После внедрения такого показателя ваша формула расчета упростится и примет надежный вид, не зависящий от разбиения периодов внутри месяца:
Результат = ?((Сдельная выработка - ВсегоНачисленоПоОкладуЗаМесяц) > 0, Сдельная выработка - ВсегоНачисленоПоОкладуЗаМесяц, 0)
Подводя итог, можно сказать, что самым простым и стабильным решением для пользователя без изменения программного кода является Способ 1 (перевод начисления в дополнительные с настройкой доплаты за уже отработанное время). Он полностью решает проблему конфликта периодов действия и обеспечивает автоматический точный расчет даже при нескольких кадровых перемещениях сотрудника в течение одного расчетного периода.