141 lines
5.5 KiB
Python
141 lines
5.5 KiB
Python
from __future__ import annotations
|
|
from dataclasses import replace
|
|
from datetime import datetime,timezone
|
|
from sqlalchemy import desc,select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from src.application.abstractions.repositories import ISbpWithdrawalRepository
|
|
from src.application.contracts import ILogger
|
|
from src.application.domain.entities import SbpWithdrawalEntity
|
|
from src.application.domain.enums import SbpWithdrawalStatus
|
|
from src.infrastructure.database.models.sbp_withdrawal import SbpWithdrawal
|
|
|
|
|
|
class SbpWithdrawalRepository(ISbpWithdrawalRepository):
|
|
def __init__(self,session: AsyncSession,logger: ILogger):
|
|
self._session=session
|
|
self._logger=logger
|
|
|
|
|
|
@staticmethod
|
|
def _to_entity(model: SbpWithdrawal) -> SbpWithdrawalEntity:
|
|
return SbpWithdrawalEntity(
|
|
id=model.id,
|
|
created_at=model.created_at,
|
|
updated_at=model.updated_at,
|
|
user_id=model.user_id,
|
|
bank_id=model.bank_id,
|
|
bank_name=model.bank_name,
|
|
phone=model.phone,
|
|
usdt_amount=model.usdt_amount,
|
|
rub_amount=model.rub_amount,
|
|
usdt_exchange_rate=model.usdt_exchange_rate,
|
|
service_fee_rate=model.service_fee_rate,
|
|
service_fee_usdt=model.service_fee_usdt,
|
|
mozen_order_id=model.mozen_order_id,
|
|
trace_id=model.trace_id,
|
|
status=model.status,
|
|
provider_error=model.provider_error,
|
|
usdt_received_at=model.usdt_received_at,
|
|
payout_created_at=model.payout_created_at,
|
|
payout_completed_at=model.payout_completed_at,
|
|
)
|
|
|
|
|
|
async def create(self,withdrawal: SbpWithdrawalEntity) -> SbpWithdrawalEntity:
|
|
values={
|
|
'user_id':withdrawal.user_id,
|
|
'bank_id':withdrawal.bank_id,
|
|
'bank_name':withdrawal.bank_name,
|
|
'phone':withdrawal.phone,
|
|
'usdt_amount':withdrawal.usdt_amount,
|
|
'rub_amount':withdrawal.rub_amount,
|
|
'usdt_exchange_rate':withdrawal.usdt_exchange_rate,
|
|
'service_fee_rate':withdrawal.service_fee_rate,
|
|
'service_fee_usdt':withdrawal.service_fee_usdt,
|
|
'mozen_order_id':withdrawal.mozen_order_id,
|
|
'trace_id':withdrawal.trace_id,
|
|
'status':withdrawal.status or SbpWithdrawalStatus.CREATED,
|
|
'provider_error':withdrawal.provider_error,
|
|
'usdt_received_at':withdrawal.usdt_received_at,
|
|
'payout_created_at':withdrawal.payout_created_at,
|
|
'payout_completed_at':withdrawal.payout_completed_at,
|
|
}
|
|
if withdrawal.id is not None:
|
|
values['id']=withdrawal.id
|
|
model=SbpWithdrawal(**values)
|
|
self._session.add(model)
|
|
await self._session.flush()
|
|
return replace(withdrawal,id=model.id,created_at=model.created_at,updated_at=model.updated_at)
|
|
|
|
|
|
async def get_by_id(self,withdraw_id: str) -> SbpWithdrawalEntity | None:
|
|
stmt=select(SbpWithdrawal).where(SbpWithdrawal.id==withdraw_id)
|
|
model=await self._session.scalar(stmt)
|
|
if model is None:
|
|
return None
|
|
return self._to_entity(model)
|
|
|
|
|
|
async def get_by_id_for_user(self,*,withdraw_id: str,user_id: str) -> SbpWithdrawalEntity | None:
|
|
stmt=select(SbpWithdrawal).where(SbpWithdrawal.id==withdraw_id,SbpWithdrawal.user_id==user_id)
|
|
model=await self._session.scalar(stmt)
|
|
if model is None:
|
|
return None
|
|
return self._to_entity(model)
|
|
|
|
|
|
async def list_by_user_id(self,*,user_id: str,limit: int,offset: int,cursor_created_at=None) -> list[SbpWithdrawalEntity]:
|
|
stmt=(
|
|
select(SbpWithdrawal)
|
|
.where(SbpWithdrawal.user_id==user_id)
|
|
.order_by(desc(SbpWithdrawal.created_at))
|
|
.limit(limit)
|
|
)
|
|
if cursor_created_at is not None:
|
|
stmt=stmt.where(SbpWithdrawal.created_at < cursor_created_at)
|
|
else:
|
|
stmt=stmt.offset(offset)
|
|
result=await self._session.scalars(stmt)
|
|
return [self._to_entity(model) for model in result.all()]
|
|
|
|
|
|
async def update_status(
|
|
self,
|
|
*,
|
|
withdraw_id: str,
|
|
status: SbpWithdrawalStatus,
|
|
provider_error: str | None = None,
|
|
) -> None:
|
|
model=await self._session.get(SbpWithdrawal,withdraw_id)
|
|
if model is None:
|
|
return
|
|
model.status=status
|
|
model.provider_error=provider_error
|
|
if status==SbpWithdrawalStatus.USDT_RECEIVED:
|
|
model.usdt_received_at=datetime.now(timezone.utc)
|
|
if status==SbpWithdrawalStatus.PAYOUT_PROCESSING:
|
|
model.payout_created_at=datetime.now(timezone.utc)
|
|
if status==SbpWithdrawalStatus.PAYOUT_COMPLETED:
|
|
model.payout_completed_at=datetime.now(timezone.utc)
|
|
await self._session.flush()
|
|
|
|
|
|
async def update_payout_created(
|
|
self,
|
|
*,
|
|
withdraw_id: str,
|
|
mozen_order_id: str | None,
|
|
status: SbpWithdrawalStatus,
|
|
provider_error: str | None,
|
|
) -> None:
|
|
model=await self._session.get(SbpWithdrawal,withdraw_id)
|
|
if model is None:
|
|
return
|
|
model.mozen_order_id=mozen_order_id
|
|
model.status=status
|
|
model.provider_error=provider_error
|
|
model.payout_created_at=datetime.now(timezone.utc)
|
|
if status==SbpWithdrawalStatus.PAYOUT_COMPLETED:
|
|
model.payout_completed_at=datetime.now(timezone.utc)
|
|
await self._session.flush()
|