Добавлен заказ накладной
This commit is contained in:
+104
-43
@@ -1,61 +1,122 @@
|
||||
"""Schemas for delivery payment initialization."""
|
||||
|
||||
from datetime import datetime
|
||||
from decimal import Decimal, InvalidOperation
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
||||
from pydantic.alias_generators import to_camel
|
||||
|
||||
|
||||
class PaymentPhone(BaseModel):
|
||||
number: str = Field(min_length=1)
|
||||
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 PaymentParty(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
name: str = Field(min_length=1)
|
||||
email: str = Field(min_length=1)
|
||||
phone: PaymentPhone
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def reject_company_field(cls, value: object) -> object:
|
||||
if isinstance(value, dict) and "company" in value:
|
||||
raise ValueError("company is not allowed")
|
||||
return value
|
||||
class _CamelModel(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
alias_generator=to_camel,
|
||||
populate_by_name=False,
|
||||
extra="forbid",
|
||||
)
|
||||
|
||||
|
||||
class DeliveryLocation(BaseModel):
|
||||
address: str = Field(min_length=1)
|
||||
class Address(_CamelModel):
|
||||
city_id: int = Field(gt=0, strict=True)
|
||||
city: str = Field(min_length=1)
|
||||
country_code: str = Field(min_length=2, max_length=2)
|
||||
|
||||
|
||||
class PaymentService(BaseModel):
|
||||
code: str = Field(min_length=1)
|
||||
parameter: str = Field(min_length=1)
|
||||
|
||||
|
||||
class PaymentPackage(BaseModel):
|
||||
number: str = Field(min_length=1)
|
||||
weight: int = Field(gt=0)
|
||||
length: int = Field(gt=0)
|
||||
width: int = Field(gt=0)
|
||||
height: int = Field(gt=0)
|
||||
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 InitPaymentRequest(BaseModel):
|
||||
order_uuid: str = Field(min_length=1)
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
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.")
|
||||
type: Literal[2]
|
||||
tariff_code: int
|
||||
comment: str | None = None
|
||||
sender: PaymentParty
|
||||
recipient: PaymentParty
|
||||
from_location: DeliveryLocation
|
||||
to_location: DeliveryLocation
|
||||
services: list[PaymentService] | None = Field(default=None, min_length=1)
|
||||
packages: list[PaymentPackage] = Field(min_length=1)
|
||||
delivery_days_min: int = Field(ge=0, strict=True)
|
||||
delivery_days_max: int = Field(ge=0, strict=True)
|
||||
tariff_code: int = Field(gt=0, strict=True)
|
||||
|
||||
|
||||
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):
|
||||
order_uuid: str = Field(min_length=1)
|
||||
sender_address: Address
|
||||
sender_contact: Contact
|
||||
receiver_address: Address
|
||||
receiver_contact: Contact
|
||||
content: Content
|
||||
pickup_date: datetime
|
||||
delivery_date: datetime | None = None
|
||||
account_email: str = Field(min_length=1)
|
||||
system_data: SystemData
|
||||
|
||||
|
||||
class InitPaymentResponse(BaseModel):
|
||||
|
||||
Reference in New Issue
Block a user