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

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

В процессе ведения учета в программных продуктах 1С:Зарплата и управление персоналом 3.1 и 1С:Зарплата и кадры государственного учреждения 3.1 бухгалтеры часто сталкиваются с методологической особенностью распределения налоговых вычетов. Если физическое лицо работает в организации одновременно по основному месту работы и по внутреннему совместительству, программа автоматически распределяет стандартные налоговые вычеты (например, вычеты на детей) пропорционально начисленным доходам по обоим местам работы.

С точки зрения налогового законодательства (НК РФ) налоговым агентом выступает организация в целом, а не конкретные трудовые договоры. Однако на практике бухгалтерия часто требует, чтобы все 100% вычетов применялись строго к доходам по основному месту работы, а по совместительству вычеты были равны нулю. В этой статье мы подробно разберем, почему так происходит, где именно в коде выполняется расчет и как корректно изменить это поведение с помощью механизма расширений.

Методологическая основа: почему 1С распределяет вычеты?

Прежде чем переходить к изменению программного кода, нам необходимо разобраться в логике разработчиков фирмы "1С" и требованиях законодательства:

  1. Единый налоговый агент: Согласно статье 218 НК РФ, стандартные налоговые вычеты предоставляются налогоплательщику одним из работодателей (налоговых агентов) по выбору налогоплательщика на основании его письменного заявления. Так как основное место и внутреннее совместительство находятся в рамках одного юридического лица, работодатель здесь один.
  2. Разные ИФНС и ОКТМО: Если сотрудник работает в разных подразделениях, которые зарегистрированы в разных налоговых органах (имеют разные КПП и ОКТМО), НДФЛ должен перечисляться по месту нахождения каждого подразделения. Чтобы налоговая база в разных ИФНС рассчитывалась корректно, программа пропорционально распределяет и сумму вычета.
  3. Изменения с 2023 года: Ранее бухгалтеры могли использовать обходные пути (например, рассчитывать сначала документ по основному сотруднику, а затем по совместителю). С переходом на расчет НДФЛ на дату фактической выплаты дохода (в связи с введением ЕНС) этот метод перестал работать. Программа анализирует совокупный доход физического лица на дату выплаты и принудительно перераспределяет вычеты.

Если бухгалтерия полностью осознает все налоговые риски и настаивает на своем требовании, нам потребуется внести изменения в программный код.

Где выполняется расчет и распределение вычетов в коде 1С?

Проанализируем структуру программных модулей, отвечающих за расчет НДФЛ:

Пошаговый алгоритм решения задачи через расширение

Для того чтобы не снимать конфигурацию с поддержки и сохранить возможность беспрепятственного обновления, мы реализуем доработку через Расширение конфигурации. Нам потребуется перехватить результат выполнения функции расчета НДФЛ и перераспределить суммы вычетов вручную.

Разберем алгоритм по шагам:

Шаг 1. Создание расширения и заимствование объектов

Создадим новое расширение конфигурации. Добавим в него общий модуль УчетНДФЛ. Также нам понадобятся кадровые функции для определения вида занятости сотрудников. Для этого мы будем использовать программный интерфейс общего модуля КадровыйУчет.

Шаг 2. Перехват функции расчета НДФЛ

Мы будем использовать аннотацию &После для функции РассчитатьНалогПоОсновнойСтавке в общем модуле УчетНДФЛ. Это позволит нам получить уже готовую, рассчитанную по типовому алгоритму таблицу значений с распределенными вычетами и налогами, а затем скорректировать ее.

Рассмотрим пример программного кода, который решает эту задачу:


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

Шаг 3. Перерасчет сумм налога

Поскольку мы перенесли вычеты с совместителей на основное место работы, облагаемая база по основному месту уменьшится, а по совместительству — увеличится. Общая сумма исчисленного НДФЛ по физическому лицу в целом должна остаться неизменной (так как совокупный доход и общая сумма вычетов не изменились), но налог внутри таблиц должен быть перераспределен:


Процедура ПересчитатьНалогиПослеКорректировкиВычетов(ТаблицаВычетов, ТаблицаНалогов)
    
    Для Каждого СтрокаНалога Из ТаблицаНалогов Цикл
        
        // Находим сумму примененных вычетов для конкретного сотрудника из скорректированной таблицы вычетов
        Отбор = Новый Структура("Сотрудник, ФизическоеЛицо", СтрокаНалога.Сотрудник, СтрокаНалога.ФизическоеЛицо);
        СтрокиПримененныхВычетов = ТаблицаВычетов.НайтиСтроки(Отбор);
        
        ОбщаяСуммаВычетовСотрудника = 0;
        Для Каждого СтрокаВычета Из СтрокиПримененныхВычетов Цикл
            ОбщаяСуммаВычетовСотрудника = ОбщаяСуммаВычетовСотрудника + СтрокаВычета.СуммаРазмещенная;
        КонецЦикла;
        
        // Пересчитываем налог по формуле: (Доход - Вычеты) * Ставка
        // Обратите внимание на необходимость учета округлений и ставок налога (например, 13%)
        НоваяНалоговаяБаза = Макс(СтрокаНалога.Доход - ОбщаяСуммаВычетовСотрудника, 0);
        СтрокаНалога.Налог = Округлить(НоваяНалоговаяБаза * (СтрокаНалога.Ставка / 100));
        
    КонецЦикла;
    
КонецПроцедуры

Примечание: приведенный код является концептуальной схемой решения. В реальной конфигурации 1С:ЗУП 3.1 структура таблиц ТаблицаВычетов и ТаблицаНалогов содержит множество дополнительных аналитических разрезов (категории дохода, ОКТМО/КПП, ставки, периоды действия). При реализации доработки программисту необходимо детально сопоставить все колонки таблиц и выполнять перерасчет с сохранением целостности ключевых полей.

Важные риски и предупреждения для бизнеса

Перед тем как внедрять данную доработку в промышленную базу, обязательно обсудите с главным бухгалтером следующие последствия:

← На главную