Initial commit: svg backend

This commit is contained in:
adminko
2026-03-19 13:39:32 +03:00
commit 85fb2f4bb9
78 changed files with 6161 additions and 0 deletions

View File

@@ -0,0 +1,179 @@
from decimal import Decimal, InvalidOperation
from typing import List
from pydantic import BaseModel, field_validator
class PricingCategoryCreateRequest(BaseModel):
name: str
code: str | None = None
class PricingCategoryUpdateRequest(BaseModel):
name: str
code: str | None = None
class PricingCategoryCreateResponse(BaseModel):
pricing_category_id: str
scheme_id: str
name: str
code: str | None
class PricingCategoryUpdateResponse(BaseModel):
pricing_category_id: str
scheme_id: str
name: str
code: str | None
class DeleteResponse(BaseModel):
status: str
class PriceRuleCreateRequest(BaseModel):
pricing_category_id: str | None = None
target_type: str
target_ref: str
amount: Decimal
currency: str = "RUB"
@field_validator("target_type")
@classmethod
def validate_target_type(cls, value: str) -> str:
allowed = {"sector", "group", "seat"}
if value not in allowed:
raise ValueError("Поле target_type должно быть одним из: sector, group, seat")
return value
@field_validator("currency")
@classmethod
def validate_currency(cls, value: str) -> str:
if value != "RUB":
raise ValueError("В v1 поддерживается только валюта RUB")
return value
@field_validator("amount", mode="before")
@classmethod
def parse_amount(cls, value):
if value is None:
raise ValueError("Поле amount обязательно")
text = str(value).strip()
if text == "":
raise ValueError("Поле amount обязательно")
try:
return Decimal(text)
except (InvalidOperation, ValueError):
raise ValueError("Некорректная сумма. Используйте формат 2500.00")
@field_validator("amount")
@classmethod
def validate_amount(cls, value: Decimal) -> Decimal:
if value < Decimal("0.00"):
raise ValueError("Сумма не может быть отрицательной")
if value.quantize(Decimal("0.01")) != value:
raise ValueError("Сумма должна быть с точностью до 2 знаков после запятой")
return value
class PriceRuleUpdateRequest(BaseModel):
pricing_category_id: str | None = None
target_type: str
target_ref: str
amount: Decimal
currency: str = "RUB"
@field_validator("target_type")
@classmethod
def validate_target_type(cls, value: str) -> str:
allowed = {"sector", "group", "seat"}
if value not in allowed:
raise ValueError("Поле target_type должно быть одним из: sector, group, seat")
return value
@field_validator("currency")
@classmethod
def validate_currency(cls, value: str) -> str:
if value != "RUB":
raise ValueError("В v1 поддерживается только валюта RUB")
return value
@field_validator("amount", mode="before")
@classmethod
def parse_amount(cls, value):
if value is None:
raise ValueError("Поле amount обязательно")
text = str(value).strip()
if text == "":
raise ValueError("Поле amount обязательно")
try:
return Decimal(text)
except (InvalidOperation, ValueError):
raise ValueError("Некорректная сумма. Используйте формат 2500.00")
@field_validator("amount")
@classmethod
def validate_amount(cls, value: Decimal) -> Decimal:
if value < Decimal("0.00"):
raise ValueError("Сумма не может быть отрицательной")
if value.quantize(Decimal("0.01")) != value:
raise ValueError("Сумма должна быть с точностью до 2 знаков после запятой")
return value
class PriceRuleCreateResponse(BaseModel):
price_rule_id: str
scheme_id: str
pricing_category_id: str | None
target_type: str
target_ref: str
amount: Decimal
currency: str
class PriceRuleUpdateResponse(BaseModel):
price_rule_id: str
scheme_id: str
pricing_category_id: str | None
target_type: str
target_ref: str
amount: Decimal
currency: str
class PricingCategoryItem(BaseModel):
pricing_category_id: str
scheme_id: str
name: str
code: str | None
created_at: str
class PriceRuleItem(BaseModel):
price_rule_id: str
scheme_id: str
pricing_category_id: str | None
target_type: str
target_ref: str
amount: Decimal
currency: str
created_at: str
class SchemePricingResponse(BaseModel):
categories: List[PricingCategoryItem]
rules: List[PriceRuleItem]
class EffectiveSeatPriceResponse(BaseModel):
scheme_id: str
scheme_version_id: str
seat_id: str
sector_id: str | None
group_id: str | None
matched_rule_level: str
matched_target_ref: str
pricing_category_id: str | None
amount: Decimal
currency: str