Andrey Epifancev a1c6c10869 Спека: строки ИНН рядом с контрагентом — 8 раскладок (#35)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 16:27:02 +04:00

6.6 KiB
Raw Blame History

Why

Требование владельца (13.10.2026, RSHB/arm-tabular-parser#35): ОСВ, где ИНН контрагента выведен отдельной строкой рядом с наименованием, должна разбираться во всех восьми раскладках: (ИНН над / под наименованием) × (в дереве / не в дереве) × (с суммами / без сумм). Сейчас парсер знает две частные раскладки: «над, не в дереве, без сумм» (OQ-130, _glue_inn_rows) и «под, в дереве, с суммами» только при подсказке «Контрагенты.ИНН» в шапке (OQ-162, #32, glue_inn_attributes). Остальные шесть дают задвоение контрагентов, ИНН вместо наименования или потерю ИНН, а «под, не в дереве, без сумм» — дефект main: ИНН первого контрагента молча достаётся второму, документ done.

Входит RSHB/arm-tabular-parser#34: числовая ячейка строки ИНН из 9/11 цифр (потерянный ведущий ноль, R-24) не распознаётся как ИНН.

Срез: доработка Среза 2a (парсер ОСВ, 09-delivery-plan.md). Репозитории: tabular-parser (код и эта спека), arm-ka-docs (05-domain-rules.md §1.1, §1.3, новый OQ), arm-ka-fixtures (синтетика и golden). Таблицы DBML не затрагиваются (osv_entry.counterparty_inn заполняет ядро из контракта, контракт не меняется).

What Changes

  • Новый модуль api/src/parser/inn_rows.py: один проход по дереву строк между построением иерархии и классификацией. Находит строки ИНН, сопоставляет каждую с её контрагентом, убирает склеенную строку из дерева (дети переходят к контрагенту), отдаёт классификатору чистое дерево и ИНН для строк контрагентов.
  • Строка ИНН распознаётся по содержимому (inn_only_row в osv_headers.yaml, 10/12 цифр; число из 9/11 цифр — с ведущим нулём, #34). Без подсказки в шапке ИНН MUST пройти проверку контрольной суммы; строка из 10/12 цифр рядом с контрагентом с неверной контрольной суммой — не строка ИНН, предупреждение и needs_check.
  • Подсказка в шапке — элемент <группировка>.ИНН (OQ-162): снимает проверку контрольной суммы и задаёт направление порядком («Контрагенты, Контрагенты.ИНН» — под; «Контрагенты.ИНН, Контрагенты» — над; второй порядок сейчас не распознаётся).
  • Сопоставление: связь в дереве (строка ИНН — родитель единственного ребёнка или ребёнок наименования) важнее соседства; соседи — по равенству сумм или по направлению документа (шапка → пары по суммам → однозначные блоки). Неоднозначность — строка не склеивается, group_type = OTHER, предупреждение с причиной, needs_check.
  • Удаляются _glue_inn_rows (OQ-130), glue_inn_attributes и тип InnAttribute в схеме классификатора (#32); поле BodyRow.inn_above заменяется ИНН из соседней строки.
  • Синтетика s20…s27 (по одной на раскладку); s18 получает ИНН с верной контрольной суммой.
  • Требование «Классификация строк» спеки osv-parsing переписывается целиком: текущая версия устарела («ИНН только из колонки», R-17) и не отражает OQ-100, OQ-130, OQ-162.

Non-goals

  • Контракт результата (counterparty_inn, rows, warnings) не меняется, CONTRACT_VERSION прежний.
  • ИНН в тексте названия (OQ-100) и в колонке ИНН (R-15, R-24, «ИНН/КПП») — прежние правила, порядок приоритета прежний: колонка → строка ИНН → хвост названия.
  • Проверка контрольной суммы ИНН из колонки и из хвоста названия не вводится.
  • Реквизиты, кроме ИНН (Контрагенты.КПП и др.), строками не склеиваются.
  • Follow-ups #36 (флейк интеграционного теста O-1, дубли extra O-2) — не здесь.

Capabilities

New Capabilities

Modified Capabilities

  • osv-parsing: требование «Шапка документа и схема группировок» (подсказка <группировка>.ИНН в обоих порядках); требование «Классификация строк» (переписано целиком: ИНН из колонки, строки ИНН, хвоста названия); новое требование «Строки ИНН рядом с контрагентом».

Impact

  • Документы с ИНН строкой, у которых контрольная сумма ИНН неверна и подсказки в шапке нет, переходят из done в needs_check (решение владельца). Какие реальные файлы fixtures затронуты, покажет сравнение main и ветки на всех файлах; каждое отличие golden согласуется с владельцем до make golden-update.
  • Файл банка Новопетровской (#32, подсказка в шапке) MUST NOT измениться.
  • После выкладки: пересобрать контейнер парсера на стенде; в ядре правок нет.