Files
g2s-aggregator/app/adapters/delivery_providers/cdek/mapper.py
T
Раис Юсупалиев 86dbd2bdd6 003 Add cdek
2026-03-07 14:57:16 +03:00

52 lines
1.7 KiB
Python

"""CDEK response mapper to unified delivery schema."""
from decimal import Decimal
from typing import Any
from app.schemas.response import DeliveryPrice
class CDEKMappingError(ValueError):
"""Raised when CDEK response cannot be mapped."""
def map_cdek_response(payload: dict[str, Any]) -> DeliveryPrice:
tariff = _get_first_tariff(payload)
service_name = tariff.get("tariff_name") or tariff.get("tariff_code")
if service_name is None:
raise CDEKMappingError("CDEK tariff_name is missing.")
raw_price = tariff.get("delivery_sum")
if raw_price is None:
raise CDEKMappingError("CDEK delivery_sum is missing.")
period_min = tariff.get("period_min")
if period_min is None:
raise CDEKMappingError("CDEK period_min is missing.")
period_max = tariff.get("period_max", period_min)
raw_currency = tariff.get("currency") or payload.get("currency") or "RUB"
try:
return DeliveryPrice(
provider="cdek",
service_name=str(service_name),
price=Decimal(str(raw_price)),
currency=str(raw_currency).upper(),
delivery_days_min=int(period_min),
delivery_days_max=int(period_max),
)
except (ArithmeticError, TypeError, ValueError) as exc:
raise CDEKMappingError("CDEK response fields have invalid values.") from exc
def _get_first_tariff(payload: dict[str, Any]) -> dict[str, Any]:
tariff_codes = payload.get("tariff_codes")
if not isinstance(tariff_codes, list) or not tariff_codes:
raise CDEKMappingError("CDEK response must include non-empty tariff_codes.")
tariff = tariff_codes[0]
if not isinstance(tariff, dict):
raise CDEKMappingError("CDEK tariff entry must be an object.")
return tariff