Исходный код tbank.selfemployed.models
from __future__ import annotations
import uuid
from datetime import date, datetime
from decimal import Decimal
from typing import Annotated, List, Optional
from pydantic import BaseModel, ConfigDict, Field, PlainSerializer
from pydantic.alias_generators import to_camel
from tbank.core.models import Rubles
from tbank.selfemployed.enums import (
AddressKind,
DocumentType,
DraftStatus,
IncomeType,
PaymentInfoStatus,
PaymentResultStatus,
PayResultStatus,
PhoneType,
ReceiptsRequestStatus,
ReceiptStatus,
RecipientStatus,
RegistryCreateType,
RegistryStatus,
RevenueTypeCode,
SelfEmployedAgreementStatus,
SelfEmployedIdentificationStatus,
SelfEmployedStatus,
SubmitResultStatus,
)
# Суммы на запись: Decimal у пользователя, но в JSON уходит числом (T-API ждёт number).
WriteRubles = Annotated[
Decimal, PlainSerializer(lambda v: float(v), return_type=float, when_used="json")
]
[документация]
class SelfEmployedModel(BaseModel):
"""Базовая модель домена: snake_case в Python, camelCase на проводе."""
model_config = ConfigDict(
alias_generator=to_camel,
populate_by_name=True,
extra="ignore",
)
def _correlation_id() -> str:
return str(uuid.uuid4())
# --- Общие ошибки (три формы в разных ответах T-API) ---
[документация]
class FieldError(SelfEmployedModel):
field_name: str
error_description: str
[документация]
class CodeMessageError(SelfEmployedModel):
error_code: str
error_message: str
[документация]
class CodeDescriptionError(SelfEmployedModel):
error_code: str
error_description: str
# --- Самозанятые: анкеты (recipients/create) ---
[документация]
class RecipientPhone(SelfEmployedModel):
type: PhoneType
number: str
[документация]
class RecipientAddress(SelfEmployedModel):
type: AddressKind
postal_code: str
state: str
country: Optional[str] = None
city: Optional[str] = None
district: Optional[str] = None
settlement: Optional[str] = None
street: Optional[str] = None
house: Optional[str] = None
building: Optional[str] = None
construction: Optional[str] = None
apartment: Optional[str] = None
[документация]
class RecipientDocument(SelfEmployedModel):
type: DocumentType
serial: str
issued_on: date = Field(alias="date")
organization: str
number: Optional[str] = None
division: Optional[str] = None
expire_date: Optional[date] = None
[документация]
class RegistrationInfo(SelfEmployedModel):
oktmo: str
activity_codes: List[str] = Field(default_factory=list)
[документация]
class RecipientDraft(SelfEmployedModel):
number: int
first_name: str
last_name: str
birth_date: date
birth_place: str
citizenship: str
middle_name: Optional[str] = None
email: Optional[str] = None
latin_first_name: Optional[str] = None
latin_last_name: Optional[str] = None
phones: Optional[List[RecipientPhone]] = None
addresses: Optional[List[RecipientAddress]] = None
documents: Optional[List[RecipientDocument]] = None
registration_info: Optional[RegistrationInfo] = None
[документация]
class CreateRecipientsRequest(CorrelatedRequest):
recipients: List[RecipientDraft]
[документация]
class RecipientResult(SelfEmployedModel):
number: int
first_name: str
last_name: str
status: DraftStatus
recipient_id: Optional[int] = None
middle_name: Optional[str] = None
errors: List[FieldError] = Field(default_factory=list)
[документация]
class RecipientResults(SelfEmployedModel):
recipient_results: List[RecipientResult] = Field(default_factory=list)
# --- Самозанятые: добавление по реквизитам (recipients/add/by-requisites) ---
[документация]
class RecipientBankInfo(SelfEmployedModel):
account_number: str
bank_bic: Optional[str] = None
[документация]
class RecipientByRequisites(SelfEmployedModel):
number: int
first_name: str
last_name: str
bank_info: RecipientBankInfo
middle_name: Optional[str] = None
mobile_number: Optional[str] = None
inn: Optional[str] = None
[документация]
class AddRecipientsByRequisitesRequest(CorrelatedRequest):
recipients: List[RecipientByRequisites]
# --- Самозанятые: список (recipients/list) ---
[документация]
class DateRange(SelfEmployedModel):
from_: Optional[datetime] = Field(default=None, alias="from")
to: Optional[datetime] = None
[документация]
class ListRecipientsRequest(SelfEmployedModel):
recipient_ids: Optional[List[int]] = None
inn: Optional[List[str]] = None
status: Optional[List[str]] = None
self_employed_status: Optional[List[str]] = None
creation_date: Optional[DateRange] = None
offset: Optional[int] = None
limit: Optional[int] = None
[документация]
class RecipientBankInfoFull(SelfEmployedModel):
account_number: Optional[str] = None
agreement_number: Optional[str] = None
bank_bic: Optional[str] = None
[документация]
class RecipientInfo(SelfEmployedModel):
id: int
status: RecipientStatus
self_employed_status: SelfEmployedStatus
self_employed_identification_status: SelfEmployedIdentificationStatus
self_employed_agreement_status: SelfEmployedAgreementStatus
first_name: str
last_name: str
bank_info: RecipientBankInfoFull
middle_name: Optional[str] = None
birth_date: Optional[date] = None
phones: Optional[List[RecipientPhone]] = None
documents: Optional[List[RecipientDocument]] = None
registration_info: Optional[RegistrationInfo] = None
inn: Optional[str] = None
creation_date: Optional[datetime] = None
[документация]
class ListRecipientsResult(SelfEmployedModel):
recipients: List[RecipientInfo] = Field(default_factory=list)
# --- Реестр: создание черновика (payment-registry/create) ---
[документация]
class SelfEmployedInfo(SelfEmployedModel):
first_name: str
last_name: str
middle_name: Optional[str] = None
[документация]
class RegistryPayment(SelfEmployedModel):
number: int
account_number: str
payment_purpose: str
self_employed_info: SelfEmployedInfo
sum: WriteRubles
revenue_type_code: Optional[RevenueTypeCode] = None
collection_amount: Optional[WriteRubles] = None
[документация]
class CreatePaymentRegistryRequest(CorrelatedRequest):
payments: List[RegistryPayment]
company_account_number: Optional[str] = None
registry_create_type: Optional[RegistryCreateType] = None
tax_holding: Optional[bool] = None
income_type: Optional[IncomeType] = None
[документация]
class PaymentError(SelfEmployedModel):
number: int
account_number: Optional[str] = None
errors: List[FieldError] = Field(default_factory=list)
[документация]
class CreateRegistryResult(SelfEmployedModel):
status: DraftStatus
payment_registry_id: Optional[int] = None
error: Optional[FieldError] = None
payment_errors: List[PaymentError] = Field(default_factory=list)
# --- Реестр: подписание / оплата / чеки (submit / pay / receipts) ---
[документация]
class SubmitRegistryResult(SelfEmployedModel):
payment_registry_id: int
status: SubmitResultStatus
error: Optional[CodeMessageError] = None
payment_errors: List[PaymentError] = Field(default_factory=list)
[документация]
class PaymentResult(SelfEmployedModel):
number: int
payment_status: PaymentResultStatus
account_number: Optional[str] = None
errors: List[FieldError] = Field(default_factory=list)
[документация]
class PayRegistryResult(SelfEmployedModel):
payment_registry_id: int
status: PayResultStatus
count: int
error: Optional[CodeDescriptionError] = None
payment_results: List[PaymentResult] = Field(default_factory=list)
[документация]
class ReceiptSelfEmployedInfo(SelfEmployedModel):
first_name: str
last_name: str
middle_name: Optional[str] = None
inn: Optional[str] = None
recipient_id: Optional[int] = None
[документация]
class Receipt(SelfEmployedModel):
number: int
self_employed_info: ReceiptSelfEmployedInfo
status: ReceiptStatus
link: Optional[str] = None
sum: Optional[Rubles] = None
comment: Optional[str] = None
error: Optional[CodeMessageError] = None
[документация]
class ReceiptsResult(SelfEmployedModel):
status: ReceiptsRequestStatus
error: Optional[CodeMessageError] = None
receipts: List[Receipt] = Field(default_factory=list)
# --- Реестр: список и карточка (list / {id}) ---
[документация]
class ListRegistriesRequest(SelfEmployedModel):
offset: Optional[int] = None
statuses: Optional[List[RegistryStatus]] = None
period_start: Optional[date] = None
period_end: Optional[date] = None
[документация]
class PaymentOrder(SelfEmployedModel):
number: int
created_at: datetime = Field(alias="date")
count: int
sum: Rubles
status: RegistryStatus
[документация]
class ListRegistriesResult(SelfEmployedModel):
payment_orders: List[PaymentOrder] = Field(default_factory=list)
[документация]
class RegistryPaymentInfo(SelfEmployedModel):
status: PaymentInfoStatus
self_employed_info: SelfEmployedInfo
sum: Rubles
number: Optional[int] = None
account_number: Optional[str] = None
payment_purpose: Optional[str] = None
revenue_type_code: Optional[RevenueTypeCode] = None
collection_amount: Optional[Rubles] = None
[документация]
class PaymentRegistryInfo(SelfEmployedModel):
status: RegistryStatus
payments_count: int
total_sum: Rubles
load_date: Optional[str] = None
payments: List[RegistryPaymentInfo] = Field(default_factory=list)
# --- Служебные модели запросов (инициатор / поллинг по correlationId) ---
[документация]
class RegistryActionRequest(CorrelatedRequest):
"""Тело submit/pay/receipts: {correlationId, paymentRegistryId}."""
payment_registry_id: int
[документация]
class CorrelationRef(SelfEmployedModel):
"""Ссылка по correlationId (query для GET-результатов, тело для pay/result)."""
correlation_id: str