Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
67 lines
3.7 KiB
Python
67 lines
3.7 KiB
Python
"""Review Focus плана 4 на реальных книгах `../fixtures/statements-xlsx/**` (спека «Манифест ожиданий...»)."""
|
||
|
||
from pathlib import Path
|
||
from typing import cast
|
||
|
||
import pytest
|
||
|
||
from src.contract import FileType, StatementDocument
|
||
from src.parser import get_parser
|
||
|
||
pytestmark = pytest.mark.fixtures
|
||
STATEMENTS = "statements-xlsx"
|
||
TITLE_BLOCK_FILES = [
|
||
"unagrande-co/2024-FY/Б.Б Лист 1.xls",
|
||
"unagrande-co/2024-FY/ОФР. Лист 1.xls",
|
||
"unagrande-group/2024-FY/ББ. Лист 1 .xls",
|
||
"unagrande-group/2025-Q3/ББ. Лист 1 3кв.25.xls",
|
||
"unagrande-group/2025-Q3/ОФР. Лист 1 3кв.25.xls",
|
||
]
|
||
NPZ = "npz/2025-Q3/Бухгалтерская отчетность за Январь - Сентябрь 2025 г. (НОВОРОССИЙСКИЙ ПРОКАТНЫЙ ЗАВОД).xlsx"
|
||
MEZHENINOVSKAYA = [
|
||
"mezheninovskaya/2025-Q3/1_Форма1_бух_09.xlsx",
|
||
"mezheninovskaya/2025-Q3/1_Форма2_бух_09.xlsx",
|
||
]
|
||
|
||
|
||
def statement_docs(fixtures_dir: Path, key: str) -> list[StatementDocument]:
|
||
path = fixtures_dir / STATEMENTS / key
|
||
outcome = get_parser().parse(path.read_bytes(), cast(FileType, path.suffix.lstrip(".").upper()))
|
||
assert outcome.error is None, outcome.error
|
||
return [document for document in outcome.documents if isinstance(document, StatementDocument)]
|
||
|
||
|
||
def test_unagrande_title_codes_block(fixtures_dir: Path) -> None:
|
||
"""Review Focus 1: ОКОПФ из блока кодов шапки не становится строкой формы."""
|
||
for key in TITLE_BLOCK_FILES:
|
||
for doc in statement_docs(fixtures_dir, key):
|
||
assert doc.header.okopf == "12267", key
|
||
assert not any("12267" in (line.line_code_text or "") for line in doc.lines), key
|
||
|
||
|
||
def test_npz_documents(fixtures_dir: Path) -> None:
|
||
"""Review Focus 2; спека «НПЗ «Реализация иного имущества»»."""
|
||
balance, income = statement_docs(fixtures_dir, NPZ)
|
||
assert (balance.status, income.status) == ("done", "done")
|
||
bad = {"SHEET_NOT_JOINED", "SEGMENT_COLUMNS_MISMATCH", "SEGMENT_WITHOUT_CODES", "HEADER_ROW_NOT_FOUND"}
|
||
assert not bad & {w.code for d in (balance, income) for w in d.warnings}
|
||
cols = {c.column_index for c in balance.columns}
|
||
assert all(v.column_index in cols for line in balance.lines for v in line.values)
|
||
income_cols = {c.column_index for c in income.columns}
|
||
assert all(v.column_index in income_cols for line in income.lines for v in line.values)
|
||
# Строки F34/F44 «Реализация иного имущества…» состоят только из прочерков (0 с форматом `[=0]"-"`, value None):
|
||
# по спеке строка без кода и без содержимого — не строка данных, пакет её не выдаёт (R-10; вопрос владельцу O-8.2:
|
||
# сценарий спеки «с суммами» не соответствует файлу, где суммы — прочерки).
|
||
assert any(
|
||
line.line_code == "2400" and line.ref.startswith("'Отчет о финансовых результата_2'") for line in income.lines
|
||
)
|
||
|
||
|
||
def test_mezheninovskaya_numbering_and_signatures(fixtures_dir: Path) -> None:
|
||
"""Review Focus 3: строка нумерации колонок «2» и подписи не становятся строками формы."""
|
||
for key in MEZHENINOVSKAYA:
|
||
(doc,) = statement_docs(fixtures_dir, key)
|
||
assert doc.status == "done" and doc.header.inn == "7016006635", key
|
||
assert not any(line.line_code_text == "2" for line in doc.lines), key
|
||
assert not any(line.line_status in ("unreadable", "missing") for line in doc.lines), key
|