Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
44 lines
1.7 KiB
Python
44 lines
1.7 KiB
Python
"""Манифест ожиданий по реальным формам `fixtures/statements-xlsx/**` (`statements_manifest.yaml`)."""
|
|
|
|
from functools import cache
|
|
from pathlib import Path
|
|
from typing import Literal
|
|
|
|
import yaml
|
|
from fixtures_helpers import STATEMENTS_DIR
|
|
from pydantic import BaseModel, ConfigDict
|
|
|
|
MANIFEST_PATH = Path(__file__).resolve().parent / "statements_manifest.yaml"
|
|
|
|
|
|
class DocumentExpectation(BaseModel):
|
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
|
|
type: Literal["BALANCE", "INCOME", "DISCLOSURE"]
|
|
status: Literal["done", "needs_check"]
|
|
complete: bool
|
|
reason: str | None = None
|
|
sheets: int | None = None
|
|
failed_relations: list[str] | None = None # None — не проверяется; список — точное множество relations_failed
|
|
error_warnings: list[str] | None = None # None — не проверяется; список — точное множество кодов уровня error
|
|
|
|
|
|
class Expectation(BaseModel):
|
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
|
|
organization: str | None = None
|
|
inn: str | None = None
|
|
inn_optional_for: tuple[str, ...] = ()
|
|
documents: list[DocumentExpectation]
|
|
|
|
|
|
@cache
|
|
def load_manifest() -> dict[str, Expectation]:
|
|
"""Ожидания по файлам; ключ — путь относительно `statements-xlsx/` (posix)."""
|
|
raw = yaml.safe_load(MANIFEST_PATH.read_text(encoding="utf-8"))
|
|
return {key: Expectation.model_validate(value) for key, value in raw["files"].items()}
|
|
|
|
|
|
def relative_key(fixtures_dir: Path, path: Path) -> str:
|
|
return path.relative_to(fixtures_dir / STATEMENTS_DIR).as_posix()
|