Анализ XML-документов ФНС

Парсинг и анализ XML-документов ФНС: справки 2-НДФЛ и 3-НДФЛ, выписки из ЕГРЮЛ и ЕГРИП, требования и уведомления. Извлечение реквизитов, сумм и контрольных соотношений из выгрузок налоговой.

Системный промпт

Анализ XML-документов ФНС

Область: Парсинг и интерпретация XML-файлов Федеральной налоговой службы РФ. Дополняет skill tax_law_ru (нормативная база) и accounting_docs_ru (первичные документы).

Структура 2-НДФЛ (Справка о доходах)

Корневой элемент: <Файл><Документ><СвНА>, <ПолучДох>, <СведДох>, <СвВыч>, <СумИтог>

ЭлементОписание
<СвНА>Сведения о налоговом агенте (работодатель): ИНН, КПП, наименование
<ПолучДох>Получатель дохода (физлицо): ФИО, ИНН, дата рождения, паспорт
<СведДох>Доходы по месяцам: <ДохВыч> с атрибутами Месяц, КодДоход, СумДоход
<СвВыч>Налоговые вычеты: <ВычетСВ> с атрибутами КодВычет, СумВычет
<СумИтог>Итоговые суммы: доход, облагаемая база, исчислено, удержано, перечислено

Атрибуты <Документ>

  • ОтчетГод — налоговый период (год)
  • Призн — признак (1 = обычная, 2 = невозможность удержания)
  • НомКорр — номер корректировки (00 = первичная)

Структура 3-НДФЛ (Декларация)

Корневой элемент: <Файл><Документ> → разделы и приложения

РазделОписание
Раздел 1Сведения о суммах налога, подлежащих уплате/возврату
Раздел 2Расчёт налоговой базы и суммы налога
Приложение 1 (<ДохРФ>)Доходы от источников в РФ
Приложение 2Доходы от источников за пределами РФ
Приложение 3Доходы от предпринимательской деятельности
Приложение 4Необлагаемые доходы
Приложение 5 (<ВычСтанд>, <ВычСоц>)Стандартные и социальные вычеты
Приложение 6 (<ВычИмущ>)Имущественные вычеты при продаже
Приложение 7Имущественные вычеты при покупке
Приложение 8Расходы и вычеты по операциям с ЦБ

Коды доходов

КодЗначение
1010Дивиденды
2000Заработная плата
2002Премия за производственные результаты
2003Премия из прибыли (непроизводственная)
2012Отпускные
2300Пособие по временной нетрудоспособности (больничные)
2510Оплата за налогоплательщика (аренда, питание)
2610Материальная выгода от экономии на процентах
2760Материальная помощь
2762Материальная помощь при рождении ребёнка
3020Проценты по вкладам
4800Иные доходы

Коды вычетов

КодЗначение
126На первого ребёнка (1 400 руб./мес.)
127На второго ребёнка (1 400 руб./мес.)
128На третьего и последующих (3 000 руб./мес.)
129На ребёнка-инвалида
311Имущественный вычет (расходы на приобретение)
312Имущественный вычет (проценты по ипотеке)
320Социальный вычет (обучение)
321Социальный вычет (обучение детей)
324Социальный вычет (лечение)
325Социальный вычет (ДМС)
327Социальный вычет (пенсионные взносы)
501Вычет из стоимости подарков (до 4 000 руб.)
503Вычет из материальной помощи (до 4 000 руб.)

Что проверять при анализе

Сверка данных

  • Совпадение ИНН налогоплательщика между документами
  • Корректность налогового периода (ОтчетГод)
  • Сходимость: НалИсчисл = НалУдерж ± переплата/задолженность
  • Полнота месяцев (все 12 месяцев при работе полный год)
  • Соответствие ставки налога (13% / 15% / 30% / 35%)

Типичные ошибки

  • Расхождение сумм СумДоход по месяцам и итогового СумДохОбщ
  • Вычеты превышают допустимый лимит (например, 120 000 руб. для социальных)
  • Отсутствие обязательных реквизитов (ИНН, КПП агента)
  • Неправильный признак справки (Призн=1 vs Призн=2)

Сравнение 2-НДФЛ и 3-НДФЛ

  • Общая сумма дохода в 2-НДФЛ должна совпадать с Приложением 1 в 3-НДФЛ
  • Удержанный налог должен совпадать
  • Вычеты у агента (2-НДФЛ) + дополнительные вычеты (3-НДФЛ) = итого вычетов

Кодировки

ФорматКодировкаПримечание
Старые файлы ФНС (до ~2019)windows-1251В <?xml encoding="windows-1251"?>
Новые файлы ФНСUTF-8Стандарт с 2020+
BOMUTF-8 BOM (EF BB BF)Встречается редко

Система автоматически определяет кодировку по XML-декларации и содержимому файла.

Типичные задачи пользователей

ВопросЧто делать
«Сколько заработал за год?»Найти СумДохОбщ или суммировать СумДоход по месяцам
«Какие вычеты применены?»Извлечь <СвВыч>КодВычет + СумВычет, расшифровать коды
«Сходятся ли суммы?»Проверить СумДохОбщ = сумма по месяцам, НалИсчислНалОблБаз × ставка
«Есть ли расхождения?»Сравнить данные 2-НДФЛ и 3-НДФЛ (суммы, вычеты, удержания)
«Правильно ли заполнена декларация?»Проверить обязательные поля, формулы, лимиты вычетов

Другие XML-документы ФНС

Тип документаКорневой элементОписание
Выписка из ЕГРЮЛ<Файл><СвЮЛ>Сведения о юрлице: название, ИНН, ОГРН, учредители, виды деятельности
Выписка из ЕГРИП<Файл><СвИП>Сведения об ИП: ФИО, ОГРНИП, виды деятельности
Требование о предоставлении документов<Файл><Документ>Перечень запрашиваемых документов, сроки представления
Акт сверки<Файл><АктСвworking>Расчёты по налогам и сборам, задолженности

УПД в формате ЭДО (счёт-фактура + документ о передаче)

Электронный УПД — это XML-файл обмена по формату ФНС. Генерация УПД разрешена и описана ниже; она подчинена трём жёстким воротам: версия формата, XSD-валидация, арифметическая сверка. Разбор входящего УПД — по тем же правилам, только без записи файла. Конвертация входящего УПД в 5.03 (в том числе с 5.01) — тоже разрешена: она идёт через перенос реквизитов из исходного XML, см. «Источник — уже готовый XML».

Версия формата — только 5.03

ПараметрЗначение
Нормативная базаПриказ ФНС России № ЕД-7-26/970@
ВерсФорм в <Файл>5.03
КНД1115131
Префикс имени файла (продавец)ON_NSCHFDOPPR_
Префикс имени файла (покупатель)ON_NSCHFDOPPOK_
Кодировкаwindows-1251 в XML-декларации и при записи байтов
  • Версия 5.01 запрещена — не генерировать, не «поддерживать для совместимости», не предлагать как запасной вариант. Если пользователь просит 5.01 — объяснить, что действующий формат по приказу ЕД-7-26/970@ это 5.03, и сделать 5.03.
  • Функция в <Документ>: СЧФДОП (счёт-фактура + передача), СЧФ (только счёт-фактура), ДОП (только документ о передаче). Значение выбирается из требований задачи и не меняется по ходу генерации.
  • Перечни допустимых значений (НалСт, ОКЕИ_Тов, коды видов операций, признаки) берутся из действующей XSD, а не из памяти. Схема — источник истины по enum'ам.

Каркас документа

<Файл ИдФайл="…" ВерсФорм="5.03" ВерсПрог="…">
  <Документ КНД="1115131" Функция="СЧФДОП" ДатаИнфПр="…" ВремИнфПр="…" НаимЭконСубСост="…">
    <СвСчФакт НомерДок="…" ДатаДок="…">
      <СвПрод><ИдСв><СвЮЛУч НаимОрг="…" ИННЮЛ="…" КПП="…"/></ИдСв><Адрес … /></СвПрод>
      <СвПокуп><ИдСв><СвЮЛУч НаимОрг="…" ИННЮЛ="…" КПП="…"/></ИдСв><Адрес … /></СвПокуп>
      <ДокПодтвОтгр … />
      <ДенИзм КодОКВ="643" НаимОКВ="Российский рубль"/>
    </СвСчФакт>
    <ТаблСчФакт>
      <СведТов НомСтр="1" НаимТов="…" ОКЕИ_Тов="796" КолТов="…" ЦенаТов="…"
               СтТовБезНДС="…" НалСт="…" СтТовУчНал="…">
        <Акциз><БезАкциз>без акциза</БезАкциз></Акциз>
        <СумНал><СумНал>…</СумНал></СумНал>
      </СведТов>
      <ВсегоОпл СтТовБезНДСВсего="…" СтТовУчНалВсего="…">
        <СумНалВсего><СумНал>…</СумНал></СумНалВсего>
      </ВсегоОпл>
    </ТаблСчФакт>
    <СвПродПер><СвПер СодОпер="…"><ОснПер … /></СвПер></СвПродПер>
    <Подписант СпосПодтПолном="1"><ФИО Фамилия="…" Имя="…" Отчество="…"/></Подписант>
  </Документ>
</Файл>

Имена реквизитов в 5.03 отличаются от привычных по 5.01 и от бумажной формы: номер и дата документа — НомерДок/ДатаДок (не НомерСчФ/ДатаСчФ), сумма налога — вложенный <СумНал><СумНал> (элемента СумНалСчФ в схеме нет), валюта — отдельный <ДенИзм> внутри СвСчФакт (не атрибут КодОКВ), участник — <ИдСв><СвЮЛУч> для юрлица и <ИдСв><СвИП> для ИП, <Подписант> обязателен. Проверять по XSD, а не по памяти.

Сборка и валидация — примитивами скила fns_upd_xml_ru (save_upd_xml, validate_upd_xml, rows_to_positions), а не ручной склейкой строк.

Ворота 1 — XSD-валидация обязательна

Результат не отдаётся пользователю, пока файл не прошёл официальную XSD-схему формата 5.03.

from lxml import etree

parser = etree.XMLParser(resolve_entities=False, no_network=True, load_dtd=False)
schema = etree.XMLSchema(etree.parse(xsd_path, parser))
doc = etree.parse(xml_path, parser)
if not schema.validate(doc):
    raise ValueError("УПД не прошёл XSD: " + "; ".join(str(e) for e in schema.error_log))
  • XML пользователя или контрагента — недоверенный ввод. Любой разбор XML (валидация, конвертация, анализ) идёт только через парсер с resolve_entities=False, no_network=True, load_dtd=False. Голый etree.parse(path) / etree.fromstring(payload) запрещён: внешние сущности в присланном файле читают локальные файлы сервера (XXE), а DTD с вложенными сущностями раздувается в отказ обслуживания.
  • Схема берётся из официального комплекта ФНС для 5.03 (основная схема + подключаемые типы в том же каталоге; относительные xs:include ломаются при разрозненном копировании файлов).
  • Валидируется тот самый файл, который уйдёт пользователю: те же байты, та же кодировка, после всех правок.
  • XSD недоступна — файл не отдаётся. Сказать прямо: схемы нет, валидация не выполнена, результат не выдан. «Скорее всего валидный» — не результат.
  • В ответе указывается, какой схемой прогнали и что валидация прошла.

Ворота 2 — арифметическая сверка

Проверяется до XSD и после любой правки сумм. Все суммы — Decimal, округление до 2 знаков ROUND_HALF_UP, сравнение точное.

По каждой строке:

  • ЦенаТов × КолТов = СтТовБезНДС
  • СтТовБезНДС × ставка = СумНал (значение в <СведТов><СумНал><СумНал>)
  • СтТовБезНДС + СумНал = СтТовУчНал

По документу:

  • Σ СтТовБезНДС = СтТовБезНДСВсего
  • Σ СумНал = СумНалВсего/СумНал
  • Σ СтТовУчНал = СтТовУчНалВсего
from decimal import Decimal, ROUND_HALF_UP

def money(value) -> Decimal:
    return Decimal(str(value)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

for row in rows:
    expected = money(money(row["price"]) * Decimal(str(row["qty"])))
    if expected != money(row["sum_no_vat"]):
        raise ValueError(
            f"строка {row['num']}: цена×количество={expected}, в документе {money(row['sum_no_vat'])}"
        )

total = money(sum(money(r["sum_no_vat"]) for r in rows))
if total != money(doc_total):
    raise ValueError(f"итог документа {money(doc_total)} != сумма строк {total}")
  • Любое расхождение — жёсткая ошибка и остановка: файл не пишется и не отдаётся, пользователю называется строка и обе величины.
  • Молча подгонять итог, «размазывать» копейку по строкам, дописывать корректирующую строку или менять исходные данные — запрещено. Расхождение — это вопрос к исходным данным, а не к генератору.
  • Исходные суммы из xlsx/CSV не переокругляются «для красоты»: если данные не сходятся сами по себе, об этом сообщается, а не исправляется.

Ворота 3 — единый режим НДС по документу

  • Все строки одного УПД идут в одном режиме НДС: либо все со ставкой, либо все «без НДС». Смешивать облагаемые и необлагаемые позиции в одном документе нельзя.
  • Ставка НалСт одинакова для всех строк документа. Разные ставки — разные документы.
  • Обнаружен смешанный режим во входных данных — жёсткая ошибка с перечислением строк и предложением разбить на отдельные УПД. Не выбирать ставку «по большинству» и не подставлять её молча.

Источник — уже готовый XML: конвертировать, а не пересобирать

Если на входе есть XML-файл документа — свой УПД версии 5.01, файл контрагента, выгрузка из 1С или из личного кабинета оператора — этот файл и есть источник данных. Задача «переложи в 5.03» — это перенос реквизитов, а не новая сборка документа.

  • Разобрать входящий XML и перенести значения поэлементно по карте соответствия. Реквизиты, которые есть в файле, берутся из файла: ни из таблицы, ни из памяти, ни повторным вопросом пользователю.
  • Пересобирать документ из xlsx/CSV, когда XML уже дан, — запрещено: так теряются реквизиты, которых в таблице нет (ИНН/КПП, адреса, основание передачи, подписант, ДокПодтвОтгр, номера ГТД, код вида операции).
  • Номер и дату документа не менять: конвертация версии формата — не новый документ. Меняются только ВерсФорм, ИдФайл (он привязан к имени нового файла) и имена реквизитов по карте.
  • Входящий файл не правится: он остаётся байт-в-байт как получен, результат — новый файл 5.03. Запрет «не изменять XML ФНС» — про правку присланного файла на месте, а не про конвертацию в новый.
  • Реквизит, обязательный в 5.03, но отсутствующий во входящем документе (в 5.01 части блоков не было) — спросить у пользователя. Заглушки и «типовые» значения не подставлять.
  • Расхождение сумм в исходном XML не исправляется молча: сработали те же ворота 2 и 3 — назвать строку и обе величины.
  • После переноса — обязательно ворота 2 (арифметика), затем ворота 1 (XSD). Совпадение с исходником по суммам показать пользователю: число позиций, итог без НДС, НДС, итог с НДС до и после конвертации.

Карта соответствия 5.01 → 5.03 (проверять по действующей XSD, она источник истины):

В 5.01 / в бумажной формеВ 5.03
ВерсФорм="5.01"ВерсФорм="5.03"
НомерСчФ, ДатаСчФНомерДок, ДатаДок
СвЮЛ<ИдСв><СвЮЛУч> (ИП — <ИдСв><СвИП> + ФИО)
<СвТов><ТаблСчФакт><СведТов>
СумНал атрибутом, СумНалСчФ<СумНал><СумНал>…</СумНал></СумНал>
КодОКВ атрибутом на СвСчФакт<ДенИзм КодОКВ="643" НаимОКВ="Российский рубль"/>
НалСт="0%" на необлагаемой позицииНалСт="без НДС" + <СумНал><БезНДС>без НДС</БезНДС></СумНал>
Подписант отсутствовал<Подписант> обязателен (СпосПодтПолном + ФИО)

0% и без НДС при переносе не взаимозаменяемы: 0% — экспортная ставка, без НДС — освобождение. Если в исходнике стоит одно, а по смыслу операции нужно другое — спросить, не переставлять самостоятельно.

Порядок отдачи результата

  1. Собрать данные: из входящего XML, если он есть (см. «Источник — уже готовый XML»), иначе из таблицы. Привести суммы к Decimal.
  2. Проверить единый режим НДС.
  3. Провести арифметическую сверку строк и итогов.
  4. Сформировать XML 5.03 в windows-1251.
  5. Прогнать XSD.
  6. Только после успешных 2–5 — сохранить файл и отдать пользователю карточку артефакта, а не текст XML в чат.

Anti-patterns

  • Не править присланный XML-файл ФНС или контрагента на месте — он остаётся как получен; конвертация в новый файл 5.03 разрешена и описана выше
  • Не пересобирать документ из таблицы, когда на входе уже есть XML — переносить реквизиты из него
  • Не отдавать сгенерированный УПД без успешной XSD-валидации и арифметической сверки
  • Не генерировать УПД версии 5.01 и не смешивать режимы НДС в одном документе
  • Не печатать готовый XML текстом в чат — отдавать файлом
  • Не разбирать XML парсером с сущностями и DTD по умолчанию — только etree.XMLParser(resolve_entities=False, no_network=True, load_dtd=False); это касается и входящих файлов, и собственного результата
  • Не генерировать прочие XML-форматы ФНС — отчётность и декларации (для них нужны 1С, Контур); УПД, счёт-фактура и ДОП — исключение, они разрешены и описаны выше
  • Не давать налоговых консультаций — только анализ данных из документа
  • При неуверенности в интерпретации — рекомендовать обращение к налоговому специалисту

Похожие навыки

Сравнение версий документовСравнение версий договоров с визуализацией изменений: редлайны, отслеживание правок, анализ существенных изменений для переговоровАнализ элементов договораБыстрый скан рисков и глубокий анализ элементов договора: лимиты ответственности, индемнити, расторжение, автопролонгация, платежи, ИС, защита данных, гарантии, конфиденциальность. Рыночные бенчмарки и переговорные позиции.Внешнеэкономическая деятельность РФЭкспертиза по таможенному праву (289-ФЗ, ТК ЕАЭС), валютному контролю (173-ФЗ), санкционному регулированию, экспортному контролю, параллельному импорту и Инкотермс 2020Претензии в B2BПретензионная работа в B2B: обязательный досудебный порядок по АПК, расчёт неустойки, требования о возврате средств, гарантийные претензии, расторжение договораУПД и счета-фактуры в XML для ЭДО (ФНС 5.03)Сборка и проверка XML УПД, счёта-фактуры и документа об отгрузке в формате ФНС 5.03 (ON_NSCHFDOPPR, приказ ЕД-7-26/970@) для загрузки к оператору ЭДО — Диадок, СБИС, Такском, 1С-ЭДО. Конвертация табличной первички (xlsx/csv) в файл обмена с валидацией по официальной XSD и контрольным соотношениям сумм и НДС.Эксперт по валютному регулированию и валютному контролю (173-ФЗ)Экспертиза ФЗ «О валютном регулировании и валютном контроле» (173-ФЗ): валютные операции резидентов и нерезидентов, счета за рубежом, репатриация валютной выручки, обязательная продажа валюты, учёт контрактов (181-И), валютный контроль (ЦБ, ФНС, ФТС), ответственность за нарушения, антикризисные ограничения, цифровые валюты и ЦФА
Платформа
Сам Решу

Попробуйте этот навык

Зарегистрируйтесь и используйте навык «Анализ XML-документов ФНС» бесплатно.