6 Commits

Author SHA1 Message Date
Andrey Epifancev
f6e8da9cf6 test(fixtures): обобщение тестов и golden на osv-dkb/** (многолистовые книги, ожидаемые needs_check, период каталога)
- test_osv_dkb.py: на каждом из 25 файлов пакета ДКБ — статусы листов по манифесту osv_dkb_expectations.yaml (данные, не
  if по имени файла), период по каталогу (2025-Q3, 2024-10_2025-09), структура строк, контракт, время разбора.
- golden: osv-dkb/** до порога GOLDEN_MAX_BYTES = 1 МиБ (22 из 25 файлов; три файла Агрокомплекса 9–14 МБ — без снимков);
  golden_update, golden_helpers (подкаталог osv-dkb/), conftest (dkb_file, dkb_golden_file), хелперы.
- dkb_helpers: expected_period, манифест; юнит-тесты без каталога fixtures.

Stacked on #15. Closes #10

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 13:23:34 +04:00
Andrey Epifancev
af8ec918c5 feat(osv): шапка ОСВ без меток и «Счет: Код / Наименование» (ОСВ 63 Новоросметалл), «Итого» ↔ Σ уровня 0 по нетто
- header: период отдельной ячейкой (periods.yaml: standalone), тип данных отдельной ячейкой («Бухгалтерский»,
  data_types.yaml: standalone_header), организация — хвост названия ведомости; код счёта — из первой строки-счёта
  таблицы (с предупреждением), если «по счету» в шапке нет.
- classify/detect: текст строки может стоять правее колонки текста (колонка задаёт уровень), подписи «Код»/
  «Наименование» (osv_headers.yaml: column_captions) — не группировки, строка сумм без подписи в конце таблицы —
  «Итого» (с предупреждением).
- checks: сумма уровня 0 сверяется с «Итого» по правилу R-21 (свёрнутое сальдо «Итого» — по нетто), как у родителя.
- tests: osv_dkb_files, покрытие словарей включает osv-dkb/**; README.

Refs #11

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 13:04:31 +04:00
Andrey Epifancev
9b8b8ea727 fix: финальное ревью — лимиты чтения xlsx (I-1), лог traceback (I-2), ACCOUNT_RE (M-1), ИНН/КПП (M-3)
- I-1 (R-23): readers/_limits.py — сумма ZipInfo.file_size ≤ 10 × PARSE_MAX_BYTES (параметр read_book от
  OsvParser), потоковый скан <mergeCell ref> до openpyxl и площадь merged после чтения любого формата
  (MERGED_AREA_LIMIT = 200 000; реальный максимум 10 090) → UNSUPPORTED_FORMAT; дедлайн в циклах detect
  (поиск строки групп, дополнительные колонки); README «Лимиты» исправлен, «Известные ограничения» (defusedxml).
- I-2: OsvParser логирует стек непредвиденной ошибки (loguru ERROR), UNREADABLE — WARNING без стека.
- M-1: ACCOUNT_RE с re.ASCII | re.DOTALL (многострочное название после запятой, только цифры 0–9).
- M-3 (R-24): правило детектора ИНН не дополняет 9/11 цифр нулём; дополнение — только при извлечении
  (numbers.inn_digits) из колонки, выбранной по заголовку или по строгому правилу.
- T9.1: тесты R-21 (свёрнутый родитель на противоположной стороне; (0,0) при детях (X, X)).
- T1.1: хелперы фикстур пропускают скрытые файлы/каталоги и lock-файлы Excel (~$…).
- T12.3: golden-update не удаляет снимки части без исходного каталога (osv/synthetic или реальные файлы).

Golden-снимки не изменились (82/82).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 16:29:53 +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
e1559c9770 test: генератор синтетики и сценарии спеки на синтетических файлах
api/tests/synthetic: детерминированный генератор s01…s13 (openpyxl, метки времени книги и zip зафиксированы),
минимальный писатель BIFF12 для s13.xlsb (ruling R-9, читается pyxlsb), тесты сценариев спеки osv-parsing на файлах
из fixtures/osv/synthetic/ (таблица «файл → ожидания», s13 равен s02 кроме предупреждения xlsb), тест побайтовой
воспроизводимости генерации. synthetic_files() учитывает только файлы Excel (README.md каталога не файл набора).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 15:04:50 +04:00
Andrey Epifancev
38386b53a2 test: доступ к ../fixtures (ARM_KA_FIXTURES), параметризация по 66 ОСВ; зависимости openpyxl/xlrd/pyxlsb
- requirements: openpyxl==3.1.5, pyxlsb==1.0.10, xlrd==2.0.2, et_xmlfile==2.0.0 (транзитивная)
- tests/fixtures_helpers.py, conftest: фикстура fixtures_dir, параметризация osv_file/synthetic_file, skip маркера fixtures
- pyproject: mypy ignore_missing_imports для openpyxl/xlrd/pyxlsb, disallow_untyped_defs для src.parser.*

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