arm-core/api/src/schemas/documents.py

112 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Схемы API документов и строк ОСВ (spec documents-api «Документ и строки», «Подтверждение документа»; design D-11).
`DocumentOut` — карточка документа: поля `document`, `file_id`, схема группировок листа из
`recognition_job.group_schema` (элемент с `locator` документа) и предупреждения маппинга файла целиком (R-6).
`EntryOut` — строка `osv_entry`; суммы — `Decimal` (в JSON — строка, без `float`). `EntriesPageParams` — пагинация
строк: `limit` ≤ 2000, по умолчанию 500.
"""
import datetime
import uuid
from decimal import Decimal
from typing import Any
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
from src.models.enums import (
CounterpartyMatchKind,
DocumentCheckResult,
DocumentStatus,
DocumentType,
OsvDataType,
OsvGroupType,
PeriodQuarter,
)
from src.schemas.issues import IssueCountsOut, IssueOut
DEFAULT_ENTRIES_LIMIT = 500
MAX_ENTRIES_LIMIT = 2000
class GroupOut(BaseModel):
"""Группировка из шапки листа ОСВ (как в результате распознавания): тип, исходный текст, есть ли ИНН."""
type: str
name: str | None = None
has_inn: bool | None = None
class DocumentOut(BaseModel):
"""Карточка документа: статус, проверки, `locator`, схема группировок листа и предупреждения маппинга файла."""
id: uuid.UUID
file_id: uuid.UUID
legal_entity_id: uuid.UUID
document_type: DocumentType
osv_account_code: str | None
period_year: int | None
period_quarter: PeriodQuarter | None
is_cumulative: bool | None
locator: str | None
status: DocumentStatus
period_check: DocumentCheckResult | None
counterparty_check: DocumentCheckResult | None
confirmed_by: uuid.UUID | None
confirmed_at: datetime.datetime | None
group_schema: list[GroupOut] | None
warnings: list[str]
is_modified: bool = False
original_values: dict[str, Any] | None = None
modified_by: uuid.UUID | None = None
modified_at: datetime.datetime | None = None
comments_count: int = 0 # число комментариев документа (D-11)
issues: list[IssueOut] = Field(default_factory=list) # v5.19: записи `document_issue` документа (любого типа)
issue_counts: IssueCountsOut = Field(default_factory=IssueCountsOut) # P3-23
class EntryOut(BaseModel):
"""Строка ОСВ (`osv_entry`); дерево восстанавливается по `parent_entry_id`."""
model_config = ConfigDict(from_attributes=True)
id: uuid.UUID
row_number: int | None
level: int | None
parent_entry_id: uuid.UUID | None
row_value: str | None
group_type: OsvGroupType | None
group_name: str | None
data_type: OsvDataType | None
account_code: str | None
account_root: str | None
account_id: uuid.UUID | None
counterparty_name: str | None
counterparty_inn: str | None
counterparty_id: uuid.UUID | None
# способ сопоставления контрагента (v5.16); в API — `match_kind`, в ORM — `counterparty_match_kind`
match_kind: CounterpartyMatchKind | None = Field(validation_alias="counterparty_match_kind")
opening_debit: Decimal | None
opening_credit: Decimal | None
turnover_debit: Decimal | None
turnover_credit: Decimal | None
closing_debit: Decimal | None
closing_credit: Decimal | None
class EntriesPageParams(BaseModel):
"""Пагинация строк документа из query: `Annotated[EntriesPageParams, Query()]`."""
limit: int = Field(DEFAULT_ENTRIES_LIMIT, ge=1, le=MAX_ENTRIES_LIMIT)
offset: int = Field(0, ge=0)
class OsvHeaderPatch(BaseModel):
"""Строгие типы проверяет Pydantic, допустимость значений — домен."""
model_config = ConfigDict(extra="forbid")
period_year: StrictInt | None = None
period_quarter: StrictStr | None = None
is_cumulative: StrictBool | None = None
osv_account_code: StrictStr | None = None