Добавлен провайдер доставки CSE: SOAP-адаптер (Calc + SaveDocuments), маршрутизация init-payment по провайдеру, обобщение tariff_code до строки, география CSE в cities_map
Deploy / deploy (push) Failing after 52s
Deploy / deploy (push) Failing after 52s
This commit is contained in:
+96
-44
@@ -22,9 +22,6 @@ from app.adapters.delivery_providers.base import (
|
||||
ProviderClientError,
|
||||
ProviderRequestError,
|
||||
)
|
||||
from app.adapters.delivery_providers.cdek.order_mapper import (
|
||||
CDEKOrderRegistrationResult,
|
||||
)
|
||||
from app.adapters.tbank.base import (
|
||||
TBankPaymentAdapterError,
|
||||
TBankPaymentNotificationTokenError,
|
||||
@@ -121,7 +118,7 @@ class PaymentPriceValidationAdapterProtocol(Protocol):
|
||||
class OrderRegistrationAdapterProtocol(Protocol):
|
||||
async def register_order(
|
||||
self, request: InitPaymentRequest, order_uuid: str
|
||||
) -> CDEKOrderRegistrationResult: ...
|
||||
) -> object: ...
|
||||
|
||||
|
||||
class OrderRepositoryProtocol(Protocol):
|
||||
@@ -150,6 +147,13 @@ class OrderRepositoryProtocol(Protocol):
|
||||
cdek_order_uuid: str,
|
||||
) -> object | None: ...
|
||||
|
||||
async def mark_cse_order_registered(
|
||||
self,
|
||||
session: object,
|
||||
order_uuid: str,
|
||||
cse_order_number: str,
|
||||
) -> object | None: ...
|
||||
|
||||
|
||||
class EmailSenderProtocol(Protocol):
|
||||
async def send_email(
|
||||
@@ -177,11 +181,13 @@ class AggregatorService:
|
||||
providers: Sequence[DeliveryProvider],
|
||||
cache: PriceCacheProtocol | None = None,
|
||||
payment_adapter: PaymentAdapterProtocol | None = None,
|
||||
payment_price_validation_adapter: (
|
||||
PaymentPriceValidationAdapterProtocol | None
|
||||
payment_price_validation_adapters: (
|
||||
Mapping[str, PaymentPriceValidationAdapterProtocol] | None
|
||||
) = None,
|
||||
order_repository: OrderRepositoryProtocol | None = None,
|
||||
order_registration_adapter: OrderRegistrationAdapterProtocol | None = None,
|
||||
order_registration_adapters: (
|
||||
Mapping[str, OrderRegistrationAdapterProtocol] | None
|
||||
) = None,
|
||||
email_sender: EmailSenderProtocol | None = None,
|
||||
address_suggestion_providers: Sequence[AddressSuggestionProvider] = (),
|
||||
address_suggestion_country_to_provider: Mapping[str, str] | None = None,
|
||||
@@ -194,9 +200,11 @@ class AggregatorService:
|
||||
self._providers = tuple(providers)
|
||||
self._cache = cache
|
||||
self._payment_adapter = payment_adapter
|
||||
self._payment_price_validation_adapter = payment_price_validation_adapter
|
||||
self._payment_price_validation_adapters = dict(
|
||||
payment_price_validation_adapters or {}
|
||||
)
|
||||
self._order_repository = order_repository
|
||||
self._order_registration_adapter = order_registration_adapter
|
||||
self._order_registration_adapters = dict(order_registration_adapters or {})
|
||||
self._email_sender = email_sender
|
||||
self._weight_round_scale = weight_round_scale
|
||||
self._provider_price_multiplier = provider_price_multiplier
|
||||
@@ -323,17 +331,22 @@ class AggregatorService:
|
||||
request: InitPaymentRequest,
|
||||
order_uuid: str,
|
||||
) -> None:
|
||||
if self._payment_price_validation_adapter is None:
|
||||
raise InitPaymentUnavailableError(
|
||||
"Payment price validation adapter is not configured."
|
||||
provider = request.system_data.tariff.provider
|
||||
validation_adapter = self._payment_price_validation_adapters.get(provider)
|
||||
if validation_adapter is None:
|
||||
logger.warning(
|
||||
"init_payment_price_validation_provider_not_configured",
|
||||
order_uuid=order_uuid,
|
||||
provider=provider,
|
||||
)
|
||||
raise InvalidInitPaymentRequestError(
|
||||
"Payment price validation is not configured for the tariff provider."
|
||||
)
|
||||
|
||||
tariff_code = request.system_data.tariff.tariff_code
|
||||
requested_price = request.system_data.tariff.price
|
||||
try:
|
||||
provider_price = await self._payment_price_validation_adapter.get_payment_price(
|
||||
request
|
||||
)
|
||||
provider_price = await validation_adapter.get_payment_price(request)
|
||||
except ProviderRequestError as exc:
|
||||
logger.warning(
|
||||
"init_payment_price_validation_request_rejected",
|
||||
@@ -430,16 +443,17 @@ class AggregatorService:
|
||||
if action is TBankPaymentNotificationAction.ACKNOWLEDGE_ONLY:
|
||||
return "OK"
|
||||
|
||||
existing_cdek_order_uuid = getattr(order, "cdek_order_uuid", None)
|
||||
if existing_cdek_order_uuid:
|
||||
provider = self._resolve_order_provider(order)
|
||||
if self._has_existing_registration(order, provider):
|
||||
return "OK"
|
||||
|
||||
registration_result = await self._register_cdek_order(
|
||||
order, order_uuid=notification.OrderId
|
||||
registration_result = await self._register_provider_order(
|
||||
order, order_uuid=notification.OrderId, provider=provider
|
||||
)
|
||||
await self._save_cdek_order_uuid(
|
||||
await self._save_order_registration(
|
||||
order_uuid=notification.OrderId,
|
||||
cdek_order_uuid=registration_result.order_uuid,
|
||||
provider=provider,
|
||||
result=registration_result,
|
||||
)
|
||||
await self._send_payment_confirmation_email(
|
||||
order, order_uuid=notification.OrderId
|
||||
@@ -543,65 +557,102 @@ class AggregatorService:
|
||||
"TBank payment notification order update failed."
|
||||
) from exc
|
||||
|
||||
async def _register_cdek_order(
|
||||
self, order: object, *, order_uuid: str
|
||||
) -> CDEKOrderRegistrationResult:
|
||||
if self._order_registration_adapter is None:
|
||||
@staticmethod
|
||||
def _resolve_order_provider(order: object) -> str:
|
||||
provider = getattr(order, "provider", None)
|
||||
if isinstance(provider, str) and provider:
|
||||
return provider
|
||||
request = AggregatorService._to_init_payment_request_from_order(order)
|
||||
return request.system_data.tariff.provider
|
||||
|
||||
@staticmethod
|
||||
def _has_existing_registration(order: object, provider: str) -> bool:
|
||||
if provider == "cdek":
|
||||
return bool(getattr(order, "cdek_order_uuid", None))
|
||||
if provider == "cse":
|
||||
return bool(getattr(order, "cse_order_number", None))
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _extract_registration_id(result: object) -> str:
|
||||
for attr in ("order_uuid", "order_number"):
|
||||
value = getattr(result, attr, None)
|
||||
if isinstance(value, str) and value:
|
||||
return value
|
||||
raise TBankPaymentNotificationProcessingError(
|
||||
"Order registration result is missing an identifier."
|
||||
)
|
||||
|
||||
async def _register_provider_order(
|
||||
self, order: object, *, order_uuid: str, provider: str
|
||||
) -> object:
|
||||
registration_adapter = self._order_registration_adapters.get(provider)
|
||||
if registration_adapter is None:
|
||||
raise TBankPaymentNotificationProcessingError(
|
||||
"CDEK order registration adapter is not configured."
|
||||
"Order registration adapter is not configured for the provider."
|
||||
)
|
||||
|
||||
try:
|
||||
request = self._to_init_payment_request_from_order(order)
|
||||
return await self._order_registration_adapter.register_order(
|
||||
request, order_uuid
|
||||
)
|
||||
return await registration_adapter.register_order(request, order_uuid)
|
||||
except Exception as exc:
|
||||
logger.exception(
|
||||
"cdek_order_registration_failed",
|
||||
"provider_order_registration_failed",
|
||||
provider=provider,
|
||||
order_uuid=getattr(order, "order_uuid", None),
|
||||
)
|
||||
raise TBankPaymentNotificationProcessingError(
|
||||
"CDEK order registration failed."
|
||||
"Provider order registration failed."
|
||||
) from exc
|
||||
|
||||
async def _save_cdek_order_uuid(
|
||||
async def _save_order_registration(
|
||||
self,
|
||||
*,
|
||||
order_uuid: str,
|
||||
cdek_order_uuid: str,
|
||||
provider: str,
|
||||
result: object,
|
||||
) -> None:
|
||||
if self._order_repository is None:
|
||||
raise TBankPaymentNotificationProcessingError(
|
||||
"Order repository is not configured."
|
||||
)
|
||||
|
||||
registration_id = self._extract_registration_id(result)
|
||||
try:
|
||||
async with self._order_repository.session() as session:
|
||||
order = await self._order_repository.mark_cdek_order_registered(
|
||||
session,
|
||||
order_uuid,
|
||||
cdek_order_uuid,
|
||||
)
|
||||
if provider == "cse":
|
||||
order = await self._order_repository.mark_cse_order_registered(
|
||||
session,
|
||||
order_uuid,
|
||||
registration_id,
|
||||
)
|
||||
else:
|
||||
order = await self._order_repository.mark_cdek_order_registered(
|
||||
session,
|
||||
order_uuid,
|
||||
registration_id,
|
||||
)
|
||||
if order is None:
|
||||
logger.warning(
|
||||
"cdek_order_uuid_order_not_found",
|
||||
"order_registration_order_not_found",
|
||||
provider=provider,
|
||||
order_uuid=order_uuid,
|
||||
cdek_order_uuid=cdek_order_uuid,
|
||||
registration_id=registration_id,
|
||||
)
|
||||
raise TBankPaymentNotificationProcessingError(
|
||||
"Order was not found while saving CDEK order UUID."
|
||||
"Order was not found while saving registration identifier."
|
||||
)
|
||||
except TBankPaymentNotificationProcessingError:
|
||||
raise
|
||||
except Exception as exc:
|
||||
logger.exception(
|
||||
"cdek_order_uuid_persistence_failed",
|
||||
"order_registration_persistence_failed",
|
||||
provider=provider,
|
||||
order_uuid=order_uuid,
|
||||
cdek_order_uuid=cdek_order_uuid,
|
||||
registration_id=registration_id,
|
||||
)
|
||||
raise TBankPaymentNotificationProcessingError(
|
||||
"CDEK order UUID persistence failed."
|
||||
"Order registration persistence failed."
|
||||
) from exc
|
||||
|
||||
async def _persist_order(
|
||||
@@ -642,6 +693,7 @@ class AggregatorService:
|
||||
payment_url=payment_url,
|
||||
price=request.system_data.tariff.price,
|
||||
tariff_code=request.system_data.tariff.tariff_code,
|
||||
provider=request.system_data.tariff.provider,
|
||||
account_email=request.account_email,
|
||||
payload=request.model_dump(mode="json", by_alias=True),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user