Как программно пересчитать НДФЛ и удержания сотрудника в документе 1С:ЗУП без открытия формы?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Налоговый учет IT и автоматизация бизнеса
← На главную

При автоматизации рутинных процессов в 1С:Зарплата и Управление Персоналом (ЗУП 3.1) разработчики часто сталкиваются с задачей: необходимо программно скорректировать начисление для одного или нескольких сотрудников в документе (например, «Разовое начисление»), а затем пересчитать для них НДФЛ и удержания. Традиционно пользователи делают это по кнопке «Пересчитать сотрудника» в интерфейсе, но как выполнить этот пересчет программно, не открывая саму форму документа? Разберем эту задачу по шагам.

Архитектурные особенности расчетов в ЗУП 3.1

Проанализируем ситуацию: почему простой пересчет вызывает такие сложности? Значительная часть бизнес-логики расчета и заполнения табличных частей в конфигурации жестко привязана к модулям форм. Многие общие модули являются клиентскими и требуют передачи объекта типа «Форма» или ее специфических коллекций (данных формы).

При программном расчете мы лишаемся контекста формы. К тому же, при открытии окна документа часто программно генерируются динамические колонки (например, Показатель1 и Значение1), в которые переносятся данные из связанных табличных частей. Если мы попытаемся пересчитать налог «в лоб», зависимые начисления и налоги рассчитаются неверно — исправить подобные расхождения поможет исправление расхождений по исчисленному НДФЛ в ЗУП.

Подход первый: «Имитация формы»

Рассмотрим первый вариант обхода ограничений системы — создание «структуры-обманки». Суть заключается в том, что мы формируем на сервере структуру, которая по составу полей и коллекций полностью дублирует реквизиты формы документа.

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

Подход второй: Использование Менеджера Расчета

Посмотрим на более изящное и правильное решение, использующее типовой объект МенеджерРасчета. Мы можем переписать логику, которая срабатывает при нажатии на кнопку пересчета, чтобы она выполнялась полностью на сервере без привязки к форме — для автоматизации этой задачи подойдёт обработка программного пересчета отпускных и НДФЛ в ЗУП.

Разберем готовый пример кода, который позволит выполнить пересчет НДФЛ:


&НаСервере
Процедура ПересчитатьНДФЛ(Объект)
    
    УстановитьПривилегированныйРежим(Истина);
    
    // Создаем экземпляр менеджера расчета для нужного месяца и организации
    МенеджерРасчета = РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета(Объект.МесяцНачисления, Объект.Организация);
    
    // Получаем список сотрудников из табличной части
    Сотрудники = ОбщегоНазначения.ВыгрузитьКолонку(Объект.Начисления, "Сотрудник");
    ФизическиеЛицаСотрудников = ОбщегоНазначения.ЗначениеРеквизитаОбъектов(Сотрудники, "ФизическоеЛицо");
    ФизическиеЛица = ОбщегоНазначения.ВыгрузитьКолонку(ФизическиеЛицаСотрудников, "Значение");
    
    // Передаем физических лиц в настройки менеджера
    ЗаполнитьНастройкиМенеджераРасчета(ФизическиеЛица, МенеджерРасчета);
    МенеджерРасчета.НастройкиРасчета.ФизическиеЛица = ФизическиеЛица;
    
    // Очищаем старые данные налогов и вычетов (если расчет не отложен)
    Если ОтложитьРасчетНалогаДоРасчетаЗарплатыВКонцеМесяца Тогда
        Объект.НДФЛ.Очистить();
        Объект.КорректировкиВыплаты.Очистить();
        Объект.ПримененныеВычетыНаДетейИИмущественные.Очистить();
    КонецЕсли;
    
    // Передаем данные в менеджер расчета и инициируем пересчет
    ДанныеФормыВДанныеМенеджераРасчета(МенеджерРасчета);
    МенеджерРасчета.ПересчитатьНДФЛ();
    
    // Возвращаем рассчитанные данные обратно в объект/форму
    РасчетЗарплатыВДанныеФормы(МенеджерРасчета.Зарплата);
    ЗаполнитьНалогиУдержания();
    
    УстановитьПривилегированныйРежим(Ложь);
    
КонецПроцедуры

Важно: Приведенные процедуры вроде ДанныеФормыВДанныеМенеджераРасчета и ЗаполнитьНастройкиМенеджераРасчета потребуется либо скопировать из модуля формы в свой серверный модуль, адаптировав под передаваемый контекст, либо вызывать из общих серверных модулей, предварительно подготовив требуемые параметры.

Внимание на планируемую дату выплаты

Выясним еще одну критически важную деталь. В ЗУП 3.1 исчисление НДФЛ и определение даты получения дохода строго привязаны к предполагаемой дате выплаты дохода. Если вы пересчитываете налог программно, вы обязаны актуализировать эту дату.

В типовых конфигурациях для этого может применяться вызов:


РасчетЗарплатыРасширенныйКлиентСервер.УстановитьПланируемуюДатуВыплаты(ВладелецФормы, ОписаниеДокумента(ВладелецФормы));

Если проигнорировать этот шаг, суммы исчисленного налога могут некорректно распределиться по периодам, что неизбежно приведет к ошибкам в отчетности — своевременно выявить проблемы поможет проверка корректности расчета НДФЛ в ЗУП.

Риски программного пересчета

Проанализируем последствия такого технического решения с точки зрения учета. Скрытые программные пересчеты таят в себе огромную опасность. Если документ пересчитывается без сохранения истории (без использования документа-исправления):

  1. Теряются следы изменений. Бухгалтер не сможет понять, кто, когда и на каком основании изменил налоги в проведенном документе.
  2. Возникают проблемы со сдачей корректирующих форм 6-НДФЛ и персонифицированных сведений.
  3. Нарушается логика межрасчетных выплат, если зарплата за месяц уже была закрыта.

Если зарплата уже рассчитана и выплачена, настоятельно рекомендуется не менять текущий документ программно, а использовать типовой механизм 1С по вводу документа-исправления. Программное обновление строк оправдано только для документов текущего, еще не закрытого периода.

← На главную