"""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