Andrey Epifancev 412a322b9d chore(arm_statements): копия пакета arm-statements@6bce80b (#52)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 19:38:43 +04:00

247 lines
5.1 KiB
Python

"""Типы входа (кандидат формы) и выхода (нормализованный документ) пакета."""
from dataclasses import dataclass
from datetime import date
from decimal import Decimal
from enum import StrEnum
class Source(StrEnum):
OCR = "ocr"
EXCEL = "excel"
class DocumentType(StrEnum):
BALANCE = "BALANCE"
INCOME = "INCOME"
DISCLOSURE = "DISCLOSURE"
class FormVariant(StrEnum):
FULL = "full"
SIMPLIFIED = "simplified"
class Edition(StrEnum):
RAS_66N = "66n"
FSBU4 = "fsbu4"
class PeriodKind(StrEnum):
ABSOLUTE = "absolute"
CURRENT = "relative:current"
PREV_YEAR_END = "relative:prev_year_end"
PREV_PREV_YEAR_END = "relative:prev_prev_year_end"
PREV_PERIOD = "relative:prev_period"
NONE = "none"
class LineStatus(StrEnum):
OK = "ok"
UNREADABLE = "unreadable"
MISSING = "missing"
DETAIL = "detail"
class Severity(StrEnum):
ERROR = "error"
INFO = "info"
class DocStatus(StrEnum):
DONE = "done"
NEEDS_CHECK = "needs_check"
class EnvelopeStatus(StrEnum):
DONE = "done"
NEEDS_CHECK = "needs_check"
ERROR = "error"
class SignForm(StrEnum):
PARENTHESES = "parentheses"
MINUS = "minus"
UNSIGNED = "unsigned"
class RowRole(StrEnum):
TITLE = "title"
HEADER = "header"
NUMBERING = "numbering"
DATA = "data"
CellValue = Decimal | date | bool | None
@dataclass(frozen=True, slots=True)
class Cell:
text: str
value: CellValue
confidence: float
ref: str
@dataclass(frozen=True, slots=True)
class Evidence:
okud: Cell | None = None
title: Cell | None = None
@dataclass(frozen=True, slots=True)
class HeaderCells:
organization_name: Cell | None = None
inn: Cell | None = None
report_date: Cell | None = None
units: Cell | None = None
okud: Cell | None = None
okpo: Cell | None = None
okopf: Cell | None = None
okfs: Cell | None = None
okei: Cell | None = None
address: Cell | None = None
HEADER_FIELDS: tuple[str, ...] = (
"organization_name",
"inn",
"report_date",
"units",
"okud",
"okpo",
"okopf",
"okfs",
"okei",
"address",
)
@dataclass(frozen=True, slots=True)
class StatementWarning:
code: str
severity: Severity
message: str
line_refs: tuple[str, ...] = ()
column_index: int | None = None
field: str | None = None
locator: str | None = None
@dataclass(frozen=True, slots=True)
class FormCandidate:
source: Source
locator: str
type_hint: DocumentType | None
evidence: Evidence
header: HeaderCells
rows: tuple[tuple[Cell | None, ...], ...]
segment_breaks: tuple[int, ...] = ()
warnings: tuple[StatementWarning, ...] = ()
@dataclass(frozen=True, slots=True)
class HeaderField:
text: str | None
confidence: float | None
value: str | None
@dataclass(frozen=True, slots=True)
class DateField:
text: str | None
confidence: float | None
value: date | None
@dataclass(frozen=True, slots=True)
class StatementHeader:
organization_name: HeaderField
inn: HeaderField
report_date: DateField
units: HeaderField
okud: HeaderField
okpo: HeaderField
okopf: HeaderField
okfs: HeaderField
okei: HeaderField
address: HeaderField
form_name: str | None = None
needs_review_fields: tuple[str, ...] = ()
@dataclass(frozen=True, slots=True)
class StatementColumn:
column_index: int
label: str
label_confidence: float | None
period_date: date | None
period_kind: PeriodKind
@dataclass(frozen=True, slots=True)
class StatementValue:
column_index: int
amount: Decimal | None
string_value: str | None
text: str | None
confidence: float
is_recognized: bool
needs_review: bool = False
@dataclass(frozen=True, slots=True)
class StatementLine:
row_index: int
ref: str
line_status: LineStatus
line_code: str | None
line_code_text: str | None
line_code_confidence: float | None
line_name: str | None
line_name_confidence: float | None
parent_ref: str | None
needs_review: bool
values: tuple[StatementValue, ...]
@dataclass(frozen=True, slots=True)
class FailedRelation:
column_index: int | None
column_key: str
relation: str
codes: tuple[str, ...]
expected: Decimal | None
actual: Decimal | None
@dataclass(frozen=True, slots=True)
class StatementChecks:
relations_failed: tuple[FailedRelation, ...]
soft_relations_failed: tuple[FailedRelation, ...]
@dataclass(frozen=True, slots=True)
class StatementDocument:
document_type: DocumentType
form_variant: FormVariant | None
locator: str
header: StatementHeader
columns: tuple[StatementColumn, ...]
lines: tuple[StatementLine, ...]
checks: StatementChecks | None
status: DocStatus
warnings: tuple[StatementWarning, ...]
@dataclass(frozen=True, slots=True)
class CandidateResult:
document: StatementDocument | None
file_warnings: tuple[StatementWarning, ...]
@dataclass(frozen=True, slots=True)
class NormalizationResult:
documents: tuple[StatementDocument, ...]
file_warnings: tuple[StatementWarning, ...]