"""Адаптер книги -> `FormCandidate` на реальных выгрузках (план 4, задача 5).""" from pathlib import Path import pytest from arm_statements import DocumentType, default_rules from src.parser.deadline import Deadline from src.parser.detect import is_osv_sheet from src.parser.readers import read_book from src.parser.rules import load_rules from src.parser.statements.adapter import build_candidates, plan_sheets pytestmark = pytest.mark.fixtures STATEMENTS = "statements-xlsx" NPZ = "npz/2025-Q3/Бухгалтерская отчетность за Январь - Сентябрь 2025 г. (НОВОРОССИЙСКИЙ ПРОКАТНЫЙ ЗАВОД).xlsx" UNAGRANDE_BALANCE = "unagrande-group/2025-Q3/ББ. Лист 1 3кв.25.xls" def _candidates(path: Path): # noqa: ANN202 sheets, _ = read_book(path.read_bytes(), path.suffix.lstrip(".").upper()) # type: ignore[arg-type] osv_rules = load_rules() rules = default_rules() plan = plan_sheets(sheets, lambda sheet: is_osv_sheet(sheet, osv_rules), rules) return build_candidates(plan.statements, rules, Deadline(600.0), xlsb=False) def test_npz_candidates(fixtures_dir: Path) -> None: candidates = _candidates(fixtures_dir / STATEMENTS / NPZ) assert [(c.type_hint, c.locator.count(",") + 1, len(c.segment_breaks)) for c in candidates] == [ (DocumentType.BALANCE, 5, 4), (DocumentType.INCOME, 3, 2), ] codes = {w.code for c in candidates for w in c.warnings} assert not codes & {"SHEET_NOT_JOINED", "CONTINUATION_TYPE_CONFLICT"} def test_unagrande_title_block_header(fixtures_dir: Path) -> None: candidates = _candidates(fixtures_dir / STATEMENTS / UNAGRANDE_BALANCE) header = candidates[0].header assert header.okopf is not None and header.okopf.text == "12267" assert header.inn is not None and "7728757141" in header.inn.text