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