113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
"""Адаптер пакета `arm_statements` за протоколом `StatementsEngine` (часть Б, B1).
|
||
|
||
Единственная точка вызова функций пакета в ядре; остальной код работает с протоколом, модульные тесты подменяют
|
||
его `FakeEngine`. Правила пакета читаются один раз на процесс (`default_engine` кэширует адаптер).
|
||
"""
|
||
|
||
import datetime
|
||
import functools
|
||
from collections.abc import Mapping, Sequence
|
||
from decimal import Decimal
|
||
from typing import Any, Protocol
|
||
|
||
from arm_statements import (
|
||
DocStatus,
|
||
DocumentType,
|
||
Edition,
|
||
FailedRelation,
|
||
FormVariant,
|
||
PeriodKind,
|
||
RecomputeResult,
|
||
Rules,
|
||
StatementChecks,
|
||
StoredForm,
|
||
choose_edition,
|
||
default_rules,
|
||
document_status,
|
||
recompute,
|
||
resolve_relative,
|
||
statements_version,
|
||
status_input_from_contract,
|
||
)
|
||
|
||
__all__ = [
|
||
"ArmStatementsEngine",
|
||
"DocStatus",
|
||
"DocumentType",
|
||
"Edition",
|
||
"FailedRelation",
|
||
"FormVariant",
|
||
"PeriodKind",
|
||
"StatementChecks",
|
||
"StatementsEngine",
|
||
"default_engine",
|
||
]
|
||
|
||
|
||
class StatementsEngine(Protocol):
|
||
@property
|
||
def version(self) -> str | None: ...
|
||
def recompute(self, form: StoredForm) -> RecomputeResult: ...
|
||
def contract_document_status(self, document: Mapping[str, Any]) -> DocStatus: ...
|
||
def edition(
|
||
self,
|
||
document_type: DocumentType,
|
||
codes: Sequence[tuple[str, bool]],
|
||
effective_date: datetime.date | None,
|
||
form_variant: FormVariant | None,
|
||
) -> Edition | None: ...
|
||
def code_order(
|
||
self, edition: Edition, document_type: DocumentType, form_variant: FormVariant
|
||
) -> tuple[str, ...]: ...
|
||
def editions(self) -> tuple[Edition, ...]: ...
|
||
def resolve_relative(self, kind: PeriodKind, effective_date: datetime.date | None) -> datetime.date | None: ...
|
||
def tolerance(self) -> Decimal: ...
|
||
|
||
|
||
class ArmStatementsEngine:
|
||
"""Реализация поверх пакета: правила — `default_rules()` пакета."""
|
||
|
||
def __init__(self, rules: Rules) -> None:
|
||
self._rules = rules
|
||
|
||
@property
|
||
def version(self) -> str | None:
|
||
return statements_version()
|
||
|
||
def recompute(self, form: StoredForm) -> RecomputeResult:
|
||
return recompute(form, self._rules)
|
||
|
||
def contract_document_status(self, document: Mapping[str, Any]) -> DocStatus:
|
||
return document_status(status_input_from_contract(document))
|
||
|
||
def edition(
|
||
self,
|
||
document_type: DocumentType,
|
||
codes: Sequence[tuple[str, bool]],
|
||
effective_date: datetime.date | None,
|
||
form_variant: FormVariant | None,
|
||
) -> Edition | None:
|
||
return choose_edition(document_type, codes, effective_date, self._rules, variant=form_variant)
|
||
|
||
def code_order(self, edition: Edition, document_type: DocumentType, form_variant: FormVariant) -> tuple[str, ...]:
|
||
if document_type is DocumentType.DISCLOSURE:
|
||
return ()
|
||
return self._rules.code_orders.sequence(edition, document_type, form_variant)
|
||
|
||
def editions(self) -> tuple[Edition, ...]:
|
||
return self._rules.code_orders.editions
|
||
|
||
def resolve_relative(self, kind: PeriodKind, effective_date: datetime.date | None) -> datetime.date | None:
|
||
if kind in (PeriodKind.ABSOLUTE, PeriodKind.NONE):
|
||
return None
|
||
return resolve_relative(kind, effective_date)
|
||
|
||
def tolerance(self) -> Decimal:
|
||
return self._rules.checks.tolerance
|
||
|
||
|
||
@functools.cache
|
||
def default_engine() -> StatementsEngine:
|
||
"""Адаптер с правилами пакета; кэш на процесс."""
|
||
return ArmStatementsEngine(default_rules())
|