В последнее время многие специалисты по расчету заработной платы и разработчики 1С столкнулись с проблемой некорректного расчета стоимости часа для оплаты сверхурочных в программе «1С:Зарплата и управление персоналом». Особенно остро это проявилось после вступления в силу изменений в статье 152 ТК РФ, согласно которым при расчете сверхурочных необходимо учитывать не только тарифную ставку или оклад, но и все стимулирующие и компенсационные выплаты (премии, надбавки). Рассмотрим, почему типовой алгоритм иногда дает сбои и как программно исправить эту ошибку.
Согласно Постановлению Конституционного Суда РФ № 35-П, с сентября 2024 года расчет оплаты за сверхурочную работу должен включать в себя все составляющие заработной платы. В 1С:ЗУП для реализации этого требования был пересмотрен механизм формирования базы ФОТ (Фонда оплаты труда), которая используется для вычисления «Стоимости часа». Однако в коде алгоритмов, отвечающих за сбор этих данных из плановых и разовых начислений, обнаружились ошибки группировки, из-за которых часть начислений (например, разовые премии) может «выпадать» из расчета или учитываться некорректно.
Разберем ситуацию: если у сотрудника в расчетном периоде есть несколько начислений, входящих в ФОТ, программа должна собрать их в таблицу, определить периоды их действия и корректно рассчитать совокупную стоимость часа. Ошибка часто кроется в том, как программа преобразует эти данные во временные интервалы.
Для диагностики проблемы нам необходимо обратиться к программному коду. Основная логика подготовки данных сосредоточена в обработке МенеджерРасчетаЗарплаты. Проанализируем функцию ВкладВФОТПлановыхБазовыхНачисленийСотрудников. Именно здесь формируется кэш данных, который впоследствии используется для расчета совокупной тарифной ставки.
Рассмотрим, как выглядит проблемный участок кода, который часто подвергается исправлениям в патчах (например, в известном патче EF_60018112) и в последующих релизах. Проблема заключается в вызове метода ПреобразоватьТаблицуДвиженийВТаблицуИнтервалов.
Посмотрим на пример кода, который вызывает ошибку из-за недостаточной детализации группировки:
// Старый или ошибочный вариант кода
КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников = Запрос.Выполнить().Выгрузить();
ПреобразоватьТаблицуДвиженийВТаблицуИнтервалов(КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников, ТаблицаПолученияПериодическихДанныхСотрудников, "Сотрудник", "Сотрудник", Истина);
В данном случае, когда в качестве измерения для преобразования указан только Сотрудник, система «схлопывает» все начисления сотрудника в одну строку интервала, зачастую теряя данные о конкретных разовых начислениях или премиях, если их несколько. Выясним причину: программа видит разные виды расчетов как одну сущность в рамках интервала, если они не разделены по измерениям.
В официальных обновлениях разработчики 1С предложили добавить в группировку ВидРасчета. Это позволяет системе различать вклады разных начислений в общий ФОТ. Также важно убедиться, что в запросе присутствует правильная сортировка, иначе алгоритм формирования интервалов может сработать непредсказуемо.
Разберем обновленный алгоритм:
// Фрагмент запроса с правильной сортировкой
ТекстЗапроса = "...
|УПОРЯДОЧИТЬ ПО
| Сотрудник,
| ВидРасчета,
| Период";
КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников = Запрос.Выполнить().Выгрузить();
// Исправленный вызов функции преобразования
ПреобразоватьТаблицуДвиженийВТаблицуИнтервалов(
КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников,
ТаблицаПолученияПериодическихДанныхСотрудников,
"Сотрудник, ВидРасчета",
"Сотрудник",
Истина
);
Важный нюанс: Как отмечают практикующие программисты на форумах, даже при использовании ВидРасчета может возникнуть ситуация, когда в колонке ВидРасчета во всех строках таблицы КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников стоит одно и то же значение (например, «Оплата праздничных и сверхурочных дней»), а реальные разовые начисления (премии) находятся в колонке Начисление.
Если вариант с ВидРасчета в вашем релизе не приносит результата, проанализируем структуру таблицы значений КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников в отладчике. Если список разовых начислений (ваши премии и надбавки) содержится в колонке Начисление, то именно ее нужно добавить в параметры преобразования таблицы интервалов.
Рассмотрим реализацию этого подхода:
// Изменяем группировку на Сотрудник + Начисление
ПреобразоватьТаблицуДвиженийВТаблицуИнтервалов(
КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников,
ТаблицаПолученияПериодическихДанныхСотрудников,
"Сотрудник, Начисление",
"Сотрудник",
Истина
);
Этот способ позволяет системе четко разделить вклад каждого конкретного начисления (Оклад, Ежемесячная премия, Разовая премия) в общую стоимость часа, не позволяя алгоритму «затирать» одни данные другими при наложении периодов.
Прежде чем вносить изменения в программный код, обязательно проверим настройки самих начислений в интерфейсе программы. Никакой код не поможет, если начисление не включено в состав ФОТ на уровне настроек.
ВкладВФОТПлановыхБазовыхНачисленийСотрудников просто проигнорирует данную выплату.Чтобы окончательно убедиться, в чем причина ошибки — в коде или в данных — выполним следующие шаги в отладчике:
Войдем в расчет документа «Начисление зарплаты и взносов», найдем момент вызова функции ВкладВФОТПлановыхБазовыхНачисленийСотрудников. Посмотрим на содержимое таблицы КэшВкладВФОТПлановыхБазовыхНачисленийСотрудников до и после вызова ПреобразоватьТаблицуДвиженийВТаблицуИнтервалов.
Если до преобразования в таблице 10 строк (разные начисления за разные периоды), а после — только 3 строки, и суммы в них не соответствуют ожидаемым, значит, проблема именно в параметрах группировки (третий параметр функции). Попробуйте последовательно протестировать варианты "Сотрудник, ВидРасчета" и "Сотрудник, Начисление".
Совет: Не забывайте отключать устаревшие патчи (например, EF_60018112), если вы обновили конфигурацию до свежего релиза, так как старые исправления могут конфликтовать с новыми механизмами ядра ЗУП.