Добавлено сохранение заказов в postgres
This commit is contained in:
@@ -4,9 +4,12 @@ import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
from collections.abc import Iterable, Mapping, Sequence
|
||||
from contextlib import AbstractAsyncContextManager
|
||||
from decimal import Decimal
|
||||
from typing import Protocol
|
||||
|
||||
import structlog
|
||||
|
||||
from app.adapters.address_suggestions.base import (
|
||||
AddressSuggestionClientError,
|
||||
AddressSuggestionProvider,
|
||||
@@ -24,10 +27,13 @@ from app.domain.price import (
|
||||
filter_and_sort_prices,
|
||||
normalize_delivery_request,
|
||||
)
|
||||
from app.repositories.order import OrderData
|
||||
from app.schemas.payment import InitPaymentRequest, InitPaymentResponse
|
||||
from app.schemas.request import AddressSuggestRequest, DeliveryCalculationRequest
|
||||
from app.schemas.response import AddressSuggestion, DeliveryPrice
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class AggregatorServiceError(RuntimeError):
|
||||
"""Base exception for AggregatorService failures."""
|
||||
@@ -67,6 +73,12 @@ class PaymentAdapterProtocol(Protocol):
|
||||
async def create_payment_link(self, order_uuid: str, amount_kopecks: int) -> str: ...
|
||||
|
||||
|
||||
class OrderRepositoryProtocol(Protocol):
|
||||
def session(self) -> AbstractAsyncContextManager[object]: ...
|
||||
|
||||
async def create_order(self, session: object, order_data: OrderData) -> object: ...
|
||||
|
||||
|
||||
class FilterAndSortPricesFn(Protocol):
|
||||
def __call__(
|
||||
self,
|
||||
@@ -83,6 +95,7 @@ class AggregatorService:
|
||||
providers: Sequence[DeliveryProvider],
|
||||
cache: PriceCacheProtocol | None = None,
|
||||
payment_adapter: PaymentAdapterProtocol | None = None,
|
||||
order_repository: OrderRepositoryProtocol | None = None,
|
||||
address_suggestion_providers: Sequence[AddressSuggestionProvider] = (),
|
||||
address_suggestion_country_to_provider: Mapping[str, str] | None = None,
|
||||
*,
|
||||
@@ -93,6 +106,7 @@ class AggregatorService:
|
||||
self._providers = tuple(providers)
|
||||
self._cache = cache
|
||||
self._payment_adapter = payment_adapter
|
||||
self._order_repository = order_repository
|
||||
self._weight_round_scale = weight_round_scale
|
||||
self._provider_price_multiplier = provider_price_multiplier
|
||||
self._filter_and_sort_prices = filter_and_sort_prices_fn
|
||||
@@ -180,6 +194,14 @@ class AggregatorService:
|
||||
amount_kopecks=request.price,
|
||||
)
|
||||
except TBankPaymentRequestError as exc:
|
||||
logger.exception(
|
||||
"payment_init_rejected",
|
||||
order_uuid=request.order_uuid,
|
||||
provider_status_code=exc.status_code,
|
||||
provider_error_code=exc.error_code,
|
||||
provider_error_message=exc.provider_message,
|
||||
provider_error_details=exc.details,
|
||||
)
|
||||
raise InvalidInitPaymentRequestError(
|
||||
"Payment init request is invalid for the configured provider."
|
||||
) from exc
|
||||
@@ -192,8 +214,52 @@ class AggregatorService:
|
||||
"Payment initialization is temporarily unavailable."
|
||||
) from exc
|
||||
|
||||
await self._persist_order(request=request, payment_url=payment_url)
|
||||
return InitPaymentResponse(payment_url=payment_url)
|
||||
|
||||
async def _persist_order(
|
||||
self,
|
||||
*,
|
||||
request: InitPaymentRequest,
|
||||
payment_url: str,
|
||||
) -> None:
|
||||
if self._order_repository is None:
|
||||
return
|
||||
|
||||
try:
|
||||
async with self._order_repository.session() as session:
|
||||
await self._order_repository.create_order(
|
||||
session,
|
||||
self._to_order_data(request=request, payment_url=payment_url),
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"order_persistence_failed",
|
||||
order_uuid=request.order_uuid,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _to_order_data(
|
||||
*,
|
||||
request: InitPaymentRequest,
|
||||
payment_url: str,
|
||||
) -> OrderData:
|
||||
payload = request.model_dump(mode="json")
|
||||
return OrderData(
|
||||
order_uuid=request.order_uuid,
|
||||
payment_url=payment_url,
|
||||
price=request.price,
|
||||
delivery_type=request.type,
|
||||
tariff_code=request.tariff_code,
|
||||
sender=payload["sender"],
|
||||
recipient=payload["recipient"],
|
||||
from_location=payload["from_location"],
|
||||
to_location=payload["to_location"],
|
||||
packages=payload["packages"],
|
||||
services=payload["services"],
|
||||
comment=request.comment,
|
||||
)
|
||||
|
||||
async def _get_provider_prices(
|
||||
self,
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user