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