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

62 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 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 измениться.
- После выкладки: пересобрать контейнер парсера на стенде; в ядре правок нет.