"""PostgreSQL order repository.""" from contextlib import AbstractAsyncContextManager from dataclasses import dataclass from typing import Any from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from app.repositories.order.models import Order @dataclass(frozen=True) class OrderData: order_uuid: str payment_url: str price: int tariff_code: int account_email: str payload: dict[str, Any] class OrderRepository: def __init__(self, session_factory: async_sessionmaker[AsyncSession]) -> None: self._session_factory = session_factory def session(self) -> AbstractAsyncContextManager[AsyncSession]: return self._session_factory.begin() async def create_order(self, session: AsyncSession, order_data: OrderData) -> Order: order = Order( order_uuid=order_data.order_uuid, payment_url=order_data.payment_url, price=order_data.price, tariff_code=order_data.tariff_code, account_email=order_data.account_email, payload=order_data.payload, ) session.add(order) await session.flush() await session.refresh(order) return order async def get_order_by_order_uuid( self, session: AsyncSession, order_uuid: str, ) -> Order | None: result = await session.execute( select(Order).where(Order.order_uuid == order_uuid) ) return result.scalar_one_or_none() async def mark_payment_status( self, session: AsyncSession, order_uuid: str, status: str, payment_id: int, ) -> Order | None: order = await self.get_order_by_order_uuid(session, order_uuid) if order is None: return None order.payment_status = status order.tbank_payment_id = payment_id await session.flush() return order async def mark_cdek_order_registered( self, session: AsyncSession, order_uuid: str, cdek_order_uuid: str, cdek_waybill_uuid: str | None = None, cdek_waybill_url: str | None = None, ) -> Order | None: order = await self.get_order_by_order_uuid(session, order_uuid) if order is None: return None order.cdek_order_uuid = cdek_order_uuid order.cdek_waybill_uuid = cdek_waybill_uuid order.cdek_waybill_url = cdek_waybill_url await session.flush() return order