AURORA-1714: счёт шапки «Счет Поставщика | 60*» и коды контрагентов в ОСВ #74

Merged
aep merged 4 commits from feat/71-osv-account-marker into main 2026-10-27 09:56:28 +03:00
Owner

Closes #71. Jira AURORA-1714. Правила: RSHB/arm-ka-docs#173 (§1.1/§1.3/§1.5, решения владельца 27.10.2026). Синтетика и golden: RSHB/arm-ka-fixtures#31.

Порядок merge

fixtures #31 -> этот PR -> docs #173 (вместе с этим PR). Без s45/s46 в fixtures красны test_rules_coverage и тесты синтетики.

Что изменено

  • Счёт шапки: маркер \bсчет\s+(поставщика|клиента)\b в header_markers.account; код из соседней ячейки строки, «60*» -> «60», метка без значения пропускается; ячейка значения не становится организацией.
  • Период: метка «За период» (header_markers.period, первой в списке) со значением в соседней ячейке; диапазон 01.01.25..30.06.25 (periods.yaml, разделитель ..); год из двух цифр -> 20yy (short_year_date, PeriodRules.year_of). Результат: 2025, Q2, нарастающий.
  • Вид субконто строкой в таблице (detect.table_kind_row): одна текстовая ячейка вне колонки текста в первой строке данных, текст известен словарю групп («Поставщики» — синоним COUNTERPARTY, osv_groups.yaml); строка не данные, вид добавляется в group_schema.
  • Субсчёт с тремя цифрами в сегменте («60.111») — строка-счёт, только если код начинается со счёта шапки (classify.match_account); голый числовой код, не равный счёту шапки, счётом не считается.
  • Блоки субсчетов с кодами контрагентов (code_blocks.py, стратегия иерархии code_blocks, OSV_HIERARCHY_BY_CODE_BLOCKS): «ИТОГ по <субсчёт>» (subaccount_sums) отдаёт суммы строке-счёту и из rows исчезает; строка с суммами + строка без сумм = контрагент (COUNTERPARTY) + его название (склеено, counterparty_name); остальные строки с суммами — договоры (CONTRACT).
  • «ИТОГ» (точное, total_row_exact) — итог листа; «ИТОГ по …» итогом листа не является.
  • Синтетика: s45 (счёт, период, организация), s46 (блоки целиком); спека osv-parsing.

Как проверено

  • Тесты test_osv_account_marker.py (книги openpyxl): сначала красные, потом зелёные.
  • make check: 3059 passed. make test-fixtures (fixtures из ветки PR #31): 1107 passed. make golden-check: существующие снимки (136) не изменились, изменился только s45 и добавлен s46.
  • Реальный файл из AURORA-1714: счёт 60, период 2025 Q2 нарастающий, 19 субсчетов ACCOUNT с суммами из «ИТОГ по», 1362 контрагента с названием, 2484 договора, «ИТОГ» найдена и сверена (total_row_matches_root, суммы детей и тождество строк без нарушений), статус done.

Rulings I made

  • R-1: вторичная защита (голые числовые коды не счета) — по правилу «голый код == корень счёта шапки».
  • R-2: «Счет Клиента» без значения пропускается; при двух значениях побеждает первая метка.
  • R-3: * отбрасывается как хвост кода, «60*» -> «60».
  • R-4: синтетика s45/s46 закреплена за #71.
  • R-9: договоры в блоке — CONTRACT по раскладке, хотя вид «Договоры» в шапке не назван и в group_schema не добавляется.
  • R-10: роли в блоках включаются только при наличии пары «субсчёт без сумм — ИТОГ по нему».
  • R-11: ключ словаря «ИТОГ по …» — subaccount_sums (subtotal_row ломал тест покрытия подстрокой total_row[0]).
  • R-12: «За период» без значения справа не даёт периода; значение берётся из ближайшей справа ячейки той же строки шапки.

🤖 Generated with Claude Code

Closes #71. Jira AURORA-1714. Правила: RSHB/arm-ka-docs#173 (§1.1/§1.3/§1.5, решения владельца 27.10.2026). Синтетика и golden: RSHB/arm-ka-fixtures#31. ## Порядок merge fixtures #31 -> этот PR -> docs #173 (вместе с этим PR). Без s45/s46 в fixtures красны `test_rules_coverage` и тесты синтетики. ## Что изменено - Счёт шапки: маркер `\bсчет\s+(поставщика|клиента)\b` в `header_markers.account`; код из соседней ячейки строки, «60*» -> «60», метка без значения пропускается; ячейка значения не становится организацией. - Период: метка «За период» (`header_markers.period`, первой в списке) со значением в соседней ячейке; диапазон `01.01.25..30.06.25` (`periods.yaml`, разделитель `..`); год из двух цифр -> 20yy (`short_year_date`, `PeriodRules.year_of`). Результат: 2025, Q2, нарастающий. - Вид субконто строкой в таблице (`detect.table_kind_row`): одна текстовая ячейка вне колонки текста в первой строке данных, текст известен словарю групп («Поставщики» — синоним COUNTERPARTY, `osv_groups.yaml`); строка не данные, вид добавляется в `group_schema`. - Субсчёт с тремя цифрами в сегменте («60.111») — строка-счёт, только если код начинается со счёта шапки (`classify.match_account`); голый числовой код, не равный счёту шапки, счётом не считается. - Блоки субсчетов с кодами контрагентов (`code_blocks.py`, стратегия иерархии `code_blocks`, `OSV_HIERARCHY_BY_CODE_BLOCKS`): «ИТОГ по <субсчёт>» (`subaccount_sums`) отдаёт суммы строке-счёту и из `rows` исчезает; строка с суммами + строка без сумм = контрагент (`COUNTERPARTY`) + его название (склеено, `counterparty_name`); остальные строки с суммами — договоры (`CONTRACT`). - «ИТОГ» (точное, `total_row_exact`) — итог листа; «ИТОГ по …» итогом листа не является. - Синтетика: s45 (счёт, период, организация), s46 (блоки целиком); спека `osv-parsing`. ## Как проверено - Тесты `test_osv_account_marker.py` (книги openpyxl): сначала красные, потом зелёные. - `make check`: 3059 passed. `make test-fixtures` (fixtures из ветки PR #31): 1107 passed. `make golden-check`: существующие снимки (136) не изменились, изменился только s45 и добавлен s46. - Реальный файл из AURORA-1714: счёт 60, период 2025 Q2 нарастающий, 19 субсчетов ACCOUNT с суммами из «ИТОГ по», 1362 контрагента с названием, 2484 договора, «ИТОГ» найдена и сверена (`total_row_matches_root`, суммы детей и тождество строк без нарушений), статус `done`. ## Rulings I made - R-1: вторичная защита (голые числовые коды не счета) — по правилу «голый код == корень счёта шапки». - R-2: «Счет Клиента» без значения пропускается; при двух значениях побеждает первая метка. - R-3: `*` отбрасывается как хвост кода, «60*» -> «60». - R-4: синтетика s45/s46 закреплена за #71. - R-9: договоры в блоке — `CONTRACT` по раскладке, хотя вид «Договоры» в шапке не назван и в `group_schema` не добавляется. - R-10: роли в блоках включаются только при наличии пары «субсчёт без сумм — ИТОГ по нему». - R-11: ключ словаря «ИТОГ по …» — `subaccount_sums` (`subtotal_row` ломал тест покрытия подстрокой `total_row[0]`). - R-12: «За период» без значения справа не даёт периода; значение берётся из ближайшей справа ячейки той же строки шапки. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
aep added 1 commit 2026-10-27 00:16:41 +03:00
Метки «Счет Поставщика»/«Счет Клиента» добавлены в header_markers.account; код счёта читается из соседней ячейки строки,
«*» отбрасывается. При известном счёте шапки голый числовой код, не совпадающий с ним, не считается счётом.
Синтетика s45, тест на книге openpyxl, сценарий в спеке osv-parsing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep added 1 commit 2026-10-27 00:28:52 +03:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep added 1 commit 2026-10-27 09:39:02 +03:00
Решения владельца 27.10.2026 (docs #172): субсчёт с 3 цифрами в сегменте под счётом шапки, код контрагента + название +
договоры (стратегия code_blocks), суммы субсчёта из «ИТОГ по …», «ИТОГ» — итог листа, «Поставщики» — вид субконто
в таблице, метка «За период» со значением в соседней ячейке, диапазон «01.01.25..30.06.25», год из двух цифр.
Синтетика s45 (период, организация) и s46 (блоки), спека osv-parsing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aep added 1 commit 2026-10-27 09:51:09 +03:00
aep merged commit c77e496f59 into main 2026-10-27 09:56:28 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RSHB/arm-tabular-parser#74
No description provided.