Merge pull request 'ОСВ §1.1/§1.3/§1.4: плоская форма, контрагенты расчётных счетов, OQ-169…172 (tabular-parser#59)' (#138) from feat/59-osv-flat-form into main

This commit is contained in:
aep 2026-10-19 13:21:58 +03:00
commit 49fd15016e
2 changed files with 45 additions and 2 deletions

View File

@ -82,6 +82,25 @@ r11 Договоры ←
такой элемент не попадает, у группировки-владельца `has_inn = true`; элемент — подсказка для строк ИНН (§1.3, OQ-163):
задаёт направление и снимает проверку контрольной суммы ИНН. Строки ИНН склеиваются с наименованием по §1.3.
**Плоская форма 1С по одному счёту (реализовано, tabular-parser #59, AURORA-1661, решения владельца 16.10 и 19.10.2026).**
Пример — выгрузка «Оборотно-сальдовая ведомость по счету: 76.Н.1»:
```
r2 Оборотно-сальдовая ведомость по счету: 76.Н.1 ← код счёта — и через двоеточие
r3 Контрагенты ← строка вида субконто (у файла-письма — «Организации»)
r4 за 2025 г.
r5 ООО "Товарное хозяйство" ← организация (или хвост «План счетов <организация>»)
r9 Субконто | Сальдо на начало периода | Обороты за период | Сальдо на конец периода
r11 Август - Агро ООО | … ← сразу контрагенты, строки-счёта нет
```
- Код счёта после «по счету» читается и через двоеточие («по счету: 76.Н.1»). **Счёт шапки важнее счёта строки
таблицы:** фолбэк «код первой строки-счёта» (выше, OQ-134) работает, только если в шапке кода нет.
- Строка шапки **между названием ведомости и периодом** — строка вида субконто, а не организация. Её элементы
(через запятую) — виды субконто: известный вид (`osv_groups.yaml`, явная запись `mapping`: «Контрагенты», «Организации» —
синоним `COUNTERPARTY`, «Договоры» …) становится группировкой схемы после `ACCOUNT`, если схема варианта 1 — одна
`ACCOUNT` («Субконто»); неизвестный вид («Материалы») в схему не попадает.
- Организация — по порядку: хвост «План счетов <организация>» (`header_markers.chart_of_accounts`) → первая не-метка
шапки вне строки вида субконто → хвост названия ведомости.
Нормализация значений шапки в типы:
| Текст в шапке | `group_type` |
@ -204,6 +223,22 @@ AURORA-1661; прикладной сценарий валютных строк
дерево строится по номеру родителя, строка с несуществующим родителем сохраняется с `parent_entry_id = NULL` и даёт
предупреждение маппинга (документ `NEEDS_CHECK`). Суммы и `data_type` (включая `NU`) пишутся как в результате.
**Плоский список под счётом шапки (реализовано, tabular-parser #59, AURORA-1661).** Если в шапке есть код счёта, а в теле
нет ни одной строки-счёта (п. 1), каскад иерархии (§1.0 п. 5) после `outline`, `indent`, `account_pattern` и до `sums`
пробует стратегию `header_account`: все строки таблицы — уровень 0, предупреждение `OSV_HIERARCHY_BY_HEADER_ACCOUNT`
(«плоский список под счётом шапки»). Условие — определение плоской формы 1С; при наличии outline или отступов побеждают
они (счёт шапки при этом всё равно наследуют строки). **Счёт шапки — счёт корня ветки:** строки до первой строки-счёта
(и все строки плоского списка) получают `account_code_raw` шапки, а не `null`.
**Контрагенты расчётных счетов без названия вида (решение владельца 16.10.2026; риск OQ-158).** Если схема группировок —
одна `ACCOUNT` (вид субконто в шапке не назван), строка на позиции 1 (первая не-счётная) под счётом из списка
`counterparty_accounts` (`osv_groups.yaml`, данные) — `COUNTERPARTY` без имени группировки, ИНН — по общим правилам (колонка,
строка ИНН, хвост названия). Список: 58, 60, 62, 66, 67, 75, 76, 80 (без 71 и 73 — подотчётные и персонал, R-9); запись
`76` покрывает `76`, `76.2`, `76.Н.1`, но не `760`. Глубже позиции 1 — `OTHER`; именованные группировки схемы («Учредители»,
«Работники организаций») правило не переопределяет. Предупреждение `OSV_ROWS` (по одному на различный код счёта):
«вид субконто в шапке не назван: строки аналитики счёта <код> приняты за контрагентов по плану счетов — проверьте».
Риск: физлица и подотчётные на расчётных счетах без названия вида попадут в «Осталось N» сопоставления (OQ-158).
Нормализация кода счёта (ядро, `domain/osv_mapping.py`): `60.1 → 60.01`, `60.01.1 → 60.01.1`, `76.7.1 → 76.07.1` —
числовой **второй** сегмент (1–3 цифры) дополняется нулём слева до двух цифр, первый и третий сегменты и буквенные
(`76.АВ`, `МЦ.04`) остаются как в файле. `account_code` строки хранится как в результате (`account_code_raw`),
@ -249,8 +284,12 @@ AURORA-1661; прикладной сценарий валютных строк
- Строка «Итого» (TOTAL) == корневая строка ACCOUNT (первая строка уровня 0); если корней уровня 0 несколько (лист без
строки корневого счёта: верхний уровень — субсчета 58.01, 58.03, OQ-133, PR #13) — «Итого» == **сумме строк уровня 0**
(показатели без суммы и сама «Итого» не входят; сальдо — по колонкам либо по нетто, если «Итого» свёрнуто, как у родителя
выше, R-21); при одном корне сверка прежняя. Вторая итоговая строка сразу за «Итого» («Итого развернутое») — тоже `TOTAL`,
в сверку не входит; строка сумм без подписи в конце таблицы принимается за «Итого» с предупреждением.
выше, R-21); при одном корне сверка прежняя. Плоский список под счётом шапки (§1.3, `header_account`) — тоже случай
«корня ACCOUNT нет»: «Итого» == сумме строк уровня 0 (прежняя сверка пустой/нулевой «Итого» — только когда строк уровня 0
нет). Вторая итоговая строка («Итого развернутое») — тоже `TOTAL`, **в любом порядке относительно «Итого»**: и сразу за ней,
и **перед** ней (плоская форма 1С, tabular-parser #59); в сверку «Итого = корень» не входит; тождество строки на ней не проверяется, только если обороты пусты и на листе есть другая
«Итого» (перед «Итого» в 1С — без оборотов, тождество не проверяется; после «Итого» — с оборотами, проверяется как обычная строка;
tabular-parser #59, R-16, R-19) — сверяется основная «Итого» (если на листе только «Итого развернутое», она единственная итоговая и сверяется как «Итого»); строка сумм без подписи в конце таблицы принимается за «Итого» с предупреждением.
**Таблица кончается на первой «Итого»** (на корневом уровне оформления; плюс «Итого развернутое» сразу за ней): всё
ниже (подпись «Ответственный:», блоки, дописанные аналитиком, в том числе строки, начинающиеся с «Итого») — вне
документа, в `rows` не попадает. Сначала ищется первая строка корневого уровня с текстом ровно «Итого»

View File

@ -174,3 +174,7 @@
| OQ-166 | Упрощённая форма ББ/ОФР (приказ 66н, прил. 5): признак — по структуре кодов (ББ: есть 1600, нет 1100 и 1200; ОФР: есть 2400 или 2110, нет 2100, 2200, 2300), ОКУД 0710096 признаком не служит. Набор соотношений §7 и перечень кодов упрощённой формы заданы по бланку (`05-domain-rules.md` §7, решение S-5 спеки; ББ — жёсткие, ОФР `2400 = 2110 − 2120 − 2330 + 2340 − 2350 − 2410` — мягкое, как `2400` полного набора, решение владельца 18.10.2026, Р-22; перечни — `contracts/statement-code-orders.yaml`, у `fsbu4` — как у 66н) без образца в `fixtures/` | change `unified-statement-normalization`, design (Decisions № 14) | `arm_statements` `statement_checks.yaml`, перечень кодов, `form_variant` | открыт: допущение — формулы §7 «Упрощённый набор»; нужен реальный образец упрощённой отчётности (Excel и скан) в `fixtures/` для проверки признака и формул |
| OQ-167 | Несколько отчётных периодов в одном файле, отданном в ИС Сканирование (например, ББ за два квартала в одном PDF): шапка в json ИС одна на json и копируется во все его таблицы | change `unified-statement-normalization`, design шаг 1 (допущение владельца 17.10.2026) | scan-gateway (адаптер шага 1), период документа | допущение владельца: ИС отдаёт разные периоды разными json; образца нет — проверить на первом таком файле, при расхождении — шапка из json неверна для части таблиц |
| OQ-168 | Коды упорядоченного перечня форм без образца в `fixtures/` (`contracts/statement-code-orders.yaml`, §11.9): в перечень вошли только коды шаблонов банка и коды печатных форм 1С и сканов, найденные в `fixtures/` (1105, 1130, 1140, 1215, 1231, 1530, 2420, 2460, 2530, 2930, повторы 1220 / 1520 / 2410 у `fsbu4`, раздел III НКО у `66n`). Не подтверждены образцом: 1120 в `fsbu4`; 1105, 1215, 2420 в `66n`; 2421, 2430, 2450 (прежние строки ОФР 66н); 2930 и раздел III НКО в `fsbu4`; клиентский 1231 в `fsbu4`; упрощённые перечни обеих редакций (OQ-166). Добавлять ли их без образца | change `unified-statement-normalization`, ревью спеки K-5 (18.10.2026) | `arm_statements` (перечень кодов, структурное подтверждение неуверенного кода), ядро (`CODE_NOT_IN_EDITION`) | открыт до появления образцов; **временное правило принято владельцем 18.10.2026 (Р-26):** коды без образца (2421 / 2430 / 2450 в `66n`, 1120 и другие в `fsbu4`) в перечень не входят; неуверенный такой код на скане не подтверждается структурой — `needs_review` строки, `needs_check`; у Excel и уверенного кода — только `info` ядра `CODE_NOT_IN_EDITION`. Пополнение — строкой в yaml с источником (файл fixtures), когда образец появится |
| OQ-169 | Группировка «Учредители» на счёте 80 в плоской форме ОСВ 1С (O-29 прогона контура, файл `02c5df51`): правило расчётных счетов (§1.3) её не переопределяет — строки остаются `OTHER` с именем группировки, в сопоставление контрагентов не попадают. Нужно ли делать учредителей `COUNTERPARTY` (гудвилл §8 п. 2 / §4 п. 2 берёт участие в капитале по контрагенту-учредителю) или оставить ручное сопоставление | tabular-parser #59, change `osv-flat-form` (R-8, решение сессии при одобрении запуска владельцем 19.10.2026) | §1.3, §4 п. 2 (гудвилл), сопоставление контрагентов | открыт; допущение принято: именованная группировка «Учредители» остаётся `OTHER` (R-8) |
| OQ-170 | Состав `counterparty_accounts` (контрагенты расчётных счетов без названия вида, §1.3): исключены 71 «Расчёты с подотчётными лицами» и 73 «Расчёты с персоналом» (физлица, OQ-158), список — 58, 60, 62, 66, 67, 75, 76, 80. Верно ли исключение; нужны ли 68, 69, 70, 77 и др. | tabular-parser #59, change `osv-flat-form` (R-9, решение сессии при одобрении запуска 19.10.2026) | §1.3, сопоставление контрагентов (OQ-158) | открыт; допущение принято: 71/73 исключены (аналитика без названия вида на них остаётся `OTHER`, в сопоставление не попадает) |
| OQ-171 | Вид субконто «Организации» в строке между названием ведомости и периодом (файл-письмо «ОСВ сч. 60 за 2 кв. 2026», план счетов ООО Хреновская Нива): что это за вид в 1С — организации-контрагенты (справочник «Организации» или «Контрагенты» под другим названием) или собственные организации учёта; на каких счетах встречается | tabular-parser #59, change `osv-flat-form` (R-10, решение сессии при одобрении запуска 19.10.2026) | §1.1 (синоним в `osv_groups.yaml`), сопоставление контрагентов | открыт; допущение принято: синоним `COUNTERPARTY` — только множественное число «Организации» (`^организации\b`, R-17); единственное «Организация» (собственная организация учёта в шапке) остаётся `OTHER`; другой смысл «Организации» на иных счетах даст `COUNTERPARTY` вместо `OTHER`, виден по предупреждениям |
| OQ-172 | Безымянная аналитика первого уровня на счёте **63** (резервы по сомнительным долгам) в плоской форме без названия вида: на файлах контура таких строк нет; 51 строка — в fixtures, golden `osv-dkb/nm/2025-Q3/НМ_ОСВ_63_Контрагенты_…json` (имя файла «63_Контрагенты» — довод за включение 63); счёт 63 не входит в `counterparty_accounts` (§1.3), строки остаются `OTHER` без имени. Нужен ли 63 в списке (аналитика резерва — контрагенты-должники) | tabular-parser #59, приёмка Task 6 (19.10.2026) | §1.3, сопоставление контрагентов | открыт; допущение принято: 63 в список не входит, строки `OTHER` |