Files
Раис Юсупалиев c6c37640fd
Deploy / deploy (push) Successful in 53s
добавлен declaredValue
2026-06-21 22:55:29 +03:00

147 lines
4.3 KiB
Python

"""Schemas for delivery payment initialization."""
from datetime import datetime
from decimal import Decimal, InvalidOperation
from typing import Literal
from pydantic import (
BaseModel,
ConfigDict,
EmailStr,
Field,
field_validator,
model_validator,
)
from pydantic.alias_generators import to_camel
def _validate_positive_decimal_string(value: str) -> str:
try:
parsed = Decimal(value)
except (InvalidOperation, TypeError, ValueError) as exc:
raise ValueError("must be a positive decimal number") from exc
if not parsed.is_finite() or parsed <= 0:
raise ValueError("must be a positive decimal number")
return value
class _CamelModel(BaseModel):
model_config = ConfigDict(
alias_generator=to_camel,
populate_by_name=False,
extra="forbid",
)
class Address(_CamelModel):
city_id: int = Field(gt=0, strict=True)
city: str = Field(min_length=1)
street: str = Field(min_length=1)
house: str = Field(min_length=1)
apartment: str | None = None
zip: str = Field(min_length=1)
comment: str | None = None
class Contact(_CamelModel):
full_name: str = Field(min_length=1)
email: str | None = None
phone: str = Field(min_length=1)
phone_ext: str | None = None
has_extra_phone: str | None = None
is_company: bool
company_name: str | None = None
inn: str | None = None
kpp: str | None = None
@model_validator(mode="after")
def _validate_company_requisites(self) -> "Contact":
if self.is_company:
missing = [
name
for name, value in (
("companyName", self.company_name),
("inn", self.inn),
("kpp", self.kpp),
)
if value is None or value == ""
]
if missing:
raise ValueError(
f"{', '.join(missing)} are required when isCompany is true"
)
return self
class Content(_CamelModel):
description: str | None = None
declared_value: int = Field(alias="declared_value", strict=True)
class SystemDataTariff(_CamelModel):
provider: str = Field(min_length=1)
service_name: str = Field(min_length=1)
price: int = Field(gt=0, strict=True, description="Payment amount in kopecks.")
delivery_days_min: int = Field(ge=0, strict=True)
delivery_days_max: int = Field(ge=0, strict=True)
tariff_code: str = Field(min_length=1)
class Dimensions(_CamelModel):
length: str = Field(min_length=1)
width: str = Field(min_length=1)
height: str = Field(min_length=1)
_validate_dimensions = field_validator("length", "width", "height")(
_validate_positive_decimal_string
)
class SystemData(_CamelModel):
tariff: SystemDataTariff
parcel_type: Literal["doc", "parcel"]
doc_packaging: Literal["envelope", "bag"] | None = None
weight: str = Field(min_length=1)
dimensions: Dimensions | None = None
_validate_weight = field_validator("weight")(_validate_positive_decimal_string)
@model_validator(mode="after")
def _validate_dimensions_for_parcel_type(self) -> "SystemData":
if self.parcel_type == "parcel" and self.dimensions is None:
raise ValueError("dimensions are required when parcelType is 'parcel'")
if self.parcel_type == "doc" and self.doc_packaging is None:
raise ValueError("docPackaging is required when parcelType is 'doc'")
return self
class InitPaymentRequest(_CamelModel):
sender_address: Address
sender_contact: Contact
receiver_address: Address
receiver_contact: Contact
content: Content
pickup_date: datetime
delivery_date: datetime | None = None
account_email: EmailStr
system_data: SystemData
agree_privacy: bool
agree_terms: bool
class InitPaymentResponse(BaseModel):
payment_url: str = Field(min_length=1)
class TBankPaymentNotification(BaseModel):
model_config = ConfigDict(extra="allow")
TerminalKey: str = Field(min_length=1)
OrderId: str = Field(min_length=1)
Success: bool
Status: str = Field(min_length=1)
PaymentId: int = Field(gt=0, strict=True)
ErrorCode: str = Field(min_length=1)
Amount: int
Token: str = Field(min_length=1)