Добавлен провайдер доставки CSE: SOAP-адаптер (Calc + SaveDocuments), маршрутизация init-payment по провайдеру, обобщение tariff_code до строки, география CSE в cities_map
Deploy / deploy (push) Failing after 52s

This commit is contained in:
Раис Юсупалиев
2026-05-31 20:13:52 +03:00
parent 6a2bf05ba5
commit 6c0f97adf6
41 changed files with 16113 additions and 4806 deletions
@@ -0,0 +1,97 @@
"""CSE Calc response mapper to the unified delivery schema."""
from decimal import Decimal, InvalidOperation
from app.adapters.delivery_providers.cse.constants import (
CSE_PROVIDER_NAME,
normalize_currency,
)
from app.adapters.delivery_providers.cse.errors import CSEMappingError
from app.adapters.delivery_providers.cse.soap import Element
from app.schemas.response import DeliveryPrice
_TARIFF_KEY = "Tariff"
def map_cse_calc_response(root: Element) -> list[DeliveryPrice]:
"""Map a parsed ``Calc`` ``return`` Element into unified delivery prices."""
prices: list[DeliveryPrice] = []
for tariff in _iter_tariffs(root):
price = _map_tariff(tariff)
if price is not None:
prices.append(price)
return prices
def map_cse_calc_response_for_tariff_code(
root: Element,
*,
tariff_code: str,
) -> DeliveryPrice | None:
"""Return the tariff matching the given GUID, or ``None`` when absent."""
for tariff in _iter_tariffs(root):
if tariff.value == tariff_code:
return _map_tariff(tariff)
return None
def _iter_tariffs(root: Element):
for destination in root.items:
for tariff in destination.items:
if tariff.key == _TARIFF_KEY:
yield tariff
def _map_tariff(tariff: Element) -> DeliveryPrice | None:
tariff_code = tariff.value
if not tariff_code:
return None
raw_total = tariff.field_value("Total")
if raw_total is None:
raise CSEMappingError("CSE tariff is missing Total.")
try:
price = Decimal(raw_total)
except (InvalidOperation, TypeError, ValueError) as exc:
raise CSEMappingError("CSE tariff Total is not a valid decimal.") from exc
if not price.is_finite() or price <= 0:
return None
service_name = tariff.field_value("Service") or tariff.field_value("UrgencyName")
if not service_name:
service_name = tariff_code
currency = normalize_currency(tariff.field_value("CurrencyName"))
min_days = _to_int(tariff.field_value("MinPeriod"))
max_days = _to_int(tariff.field_value("MaxPeriod"))
if min_days is None:
min_days = 0
if max_days is None or max_days < min_days:
max_days = min_days
try:
return DeliveryPrice(
provider=CSE_PROVIDER_NAME,
service_name=str(service_name),
price=price,
currency=currency,
delivery_days_min=min_days,
delivery_days_max=max_days,
tariff_code=tariff_code,
bypass_parcel_type_filter=True,
)
except (ArithmeticError, TypeError, ValueError) as exc:
raise CSEMappingError("CSE tariff fields have invalid values.") from exc
def _to_int(value: str | None) -> int | None:
if value is None or value == "":
return None
try:
return int(Decimal(value))
except (InvalidOperation, TypeError, ValueError):
return None