10 Commits

Author SHA1 Message Date
Andrey Epifancev
74ba89c417 Словари: колонка «Показатели», «В валюте» (#58)
Словари для колонки вида суммы «Показатели» (БУ/НУ/Кол./Вал./ПР/ВР) и строки «В валюте» (AURORA-1613, AURORA-1661).
Код их пока не читает — это Task 2–3 плана.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 11:34:33 +04:00
Andrey Epifancev
8b91bcae3d «Кол-во» — количество, «Вал» без точки — не валюта; таблица кончается на первой «Итого» (#47, AURORA-1663, AURORA-1664)
AURORA-1663: словарь строк data_types.yaml — «Кол-во» даёт QUANTITY, «Вал» без
точки больше не CURRENCY (материал «Вал» на счёте 10); метка — «Вал.» и код
валюты.

AURORA-1664: _find_total берёт первую «Итого» на корневом уровне оформления
(раньше — последнюю), вторая итоговая строка сразу за ней по-прежнему часть
таблицы; всё ниже вне документа. Числа в хвосте дают предупреждение «ниже
таблицы (после «Итого») есть числа» без смены статуса. Закрывает tp#7 M-2.
Предупреждение появляется и у реальной фикстуры rb/2024-Q1 (контрольные суммы
правее таблицы под «Итого») — тест property допускает его.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 11:50:39 +04:00
Andrey Epifancev
49400682bc feat(osv): счета без сальдо по аналитике (91, 99) вне тождества строки (OQ-132, #11 п. 2)
У 91 и 99 строки аналитики несут только обороты, сальдо закрыто на субсчёт закрытия
(91.09), поэтому каждая ОСВ 91 получала needs_check. Список счетов — данные
api/rules/osv_checks.yaml (accounts_without_analytic_balance: 91, 99; 90 не входит).

- тождество строки на таких счетах не проверяется;
- «сумма детей = родитель» сохраняется: обороты всегда, сальдо — только у родителя
  с дочерними субсчетами (корень -> субсчета); у родителя с одной аналитикой сальдо
  не сверяется;
- «Итого» сверяется как обычно;
- строка относится к счёту списка по коду ближайшего счёта ветки (91, 91.01; не 910).

Тесты: unit checks/rules, манифест osv_dkb_expectations (две ОСВ 91 теперь done).
README, CLAUDE.md, openspec/specs/osv-parsing, api/rules/README.md обновлены.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-08 00:18:36 +04:00
Andrey Epifancev
b8bf2f29e4 feat(statements): блоки форм, тип по заголовку и ОКУД, листы-продолжения; classify_sheet без statement_markers
Refs #14
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 15:36:26 +04:00
Andrey Epifancev
a592c68509 feat(osv): ИНН из текста названия контрагента, ИНН строкой выше, «ИНН/КПП» в ячейке
- OQ-100: ИНН в конце названия («Полиграф, 3528315710», «(ИНН …)», пробел) уходит в counterparty_inn, имя — без ИНН
  и разделителя; колонка ИНН приоритетнее; только для COUNTERPARTY.
- OQ-130: строка без сумм с одним ИНН над строкой с суммами того же уровня склеивается со следующей и не уходит в OTHER.
- «ИНН/КПП» в ячейке колонки ИНН даёт ИНН.
- Правила — osv_headers.yaml (counterparty_inn_suffix, inn_only_row, inn_kpp_cell), не код.
- Синтетика s17–s19 (генератор, тесты); golden — в репозитории fixtures (feat/9-golden).

Stacked on #13 (feat/11-dkb-formats).
Closes #9

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 13:13:44 +04:00
Andrey Epifancev
30f78c42e7 feat(osv): период-диапазон месяцев «Октябрь 2024 г. – Сентябрь 2025 г.» (скользящий, не с начала года)
Раньше первый месяц диапазона давал «2024 Q4, нарастающий». Теперь словарь periods.yaml (months, range)
разбирает диапазон: период режется по году конца, январь–конец квартала — нарастающий, ровно квартал — квартальный,
остальное (скользящие 12 месяцев) — год конца, квартал и is_cumulative = null + предупреждение «не с начала года».
Контракт v1.1 не менялся.

Refs #11

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 12:49:11 +04:00
Andrey Epifancev
bc143ef140 test: golden-снимки, линтер координат, покрытие словарей; make golden-update
- golden_helpers, scripts/golden_update.py (--check), test_golden на 66 ОСВ и синтетике; make golden-update/golden-check/test-fixtures
- тест покрытия словарей (R-22): счётчик срабатываний Pattern; из osv_headers.yaml удалены неиспользуемые service_columns kpp/code/quantity/currency
- синтетика s14–s16 в генераторе и таблице ожиданий; skip вместо падения при отсутствии osv/synthetic (T11.1); комментарий R-21 в s07 (T11.2)
- линтер: предел адреса 10 вместо 4 (T3.1), обращение cell(3, 4) (T3.8); реальные файлы не фиксируют BU/RUB (T3.9)
- README: golden-процесс; отмечены Task 12 и пункты 4.2, 4.3

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 15:28:41 +04:00
Andrey Epifancev
8e627e80c5 fix(parser): шапка ОСВ — «за»/«валюта» в названии организации, диапазоны дат с «г.» (T5.1–T5.5, T5.7)
- T5.1: организация исключается только по структурным меткам (лист, счёт, тип данных, параметры, субконто),
  строка периода выбирается по опознанному словарём периоду, метка валюты — только с двоеточием
- T5.2: конец периода — самое короткое начало, которое узнаёт словарь; диапазон «01.01.2025 г. - 31.03.2025 г.» цел
- T5.3: граница по цифрам в правиле счёта из имени файла
- T5.4: тест has_inn для варианта 2 (правило оставлено); T5.5: период только датами -> "" + предупреждение
- T5.7: тест обязательного ключа periods.end

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 13:19:18 +04:00
Andrey Epifancev
a833945669 feat(parser): детекторы листов ОСВ, заголовка таблицы и колонок по содержимому
detect.py: classify_sheet (ОСВ / форма ББ-ОФР / прочее по словарю), find_table_header
(строка с ≥ 2 группами сумм, «Дебет/Кредит» под группой в пределах merged-диапазона
или до следующей группы, заголовок в 1–4 строки, в т.ч. «Нач. сальдо Дт» в одной
ячейке; без «начала»; свёрнутое сальдо в *_debit + collapsed; свёрнутые «Обороты» и
половинчатая пара Дт/Кт — InvalidFormatError с названием группы), text_col, inn_col
(заголовок «ИНН» или ≥ 80 % значений из 10/12 цифр), right_edge, extra_cols,
group_label_rows, first_data_row, is_header_repeat (две группы или копия строки блока).

Pattern.search_normalized — ячейка нормализуется один раз (T3.6). osv_groups: известные
группировки OTHER перечислены явно, чтобы строка-метка «Основные средства» в
неслитом заголовке была частью блока. Хелпер тестов gridbuilder (Sheet из «картинки»).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 12:54:11 +04:00
Andrey Epifancev
fcd609c633 feat(rules): словари ОСВ (заголовки, группировки, периоды, типы данных) и загрузчик
Словари api/rules/{osv_headers,osv_groups,periods,data_types}.yaml и src/parser/rules.py
(normalize_text, Pattern, load_rules, pydantic-валидация с RuntimeError по файлу и ключу,
currency_aliases по R-6). AST-линтер координат tests/unit/parser/test_no_coordinates.py
перенесён из Task 12 (R-7, правила R-4/R-5). Тест формулировок реальных ОСВ.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 12:28:46 +04:00