mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-01-20 03:40:26 +00:00
80 lines
2.7 KiB
Python
80 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Optional
|
|
|
|
from fastapi import APIRouter, Depends, Query, Security
|
|
from sqlalchemy import and_, func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database.models import Transaction
|
|
|
|
from ..dependencies import get_db_session, require_api_token
|
|
from ..schemas.transactions import TransactionListResponse, TransactionResponse
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _serialize(transaction: Transaction) -> TransactionResponse:
|
|
return TransactionResponse(
|
|
id=transaction.id,
|
|
user_id=transaction.user_id,
|
|
type=transaction.type,
|
|
amount_kopeks=transaction.amount_kopeks,
|
|
amount_rubles=round(transaction.amount_kopeks / 100, 2),
|
|
description=transaction.description,
|
|
payment_method=transaction.payment_method,
|
|
external_id=transaction.external_id,
|
|
is_completed=transaction.is_completed,
|
|
created_at=transaction.created_at,
|
|
completed_at=transaction.completed_at,
|
|
)
|
|
|
|
|
|
@router.get("", response_model=TransactionListResponse)
|
|
async def list_transactions(
|
|
_: Any = Security(require_api_token),
|
|
db: AsyncSession = Depends(get_db_session),
|
|
limit: int = Query(50, ge=1, le=200),
|
|
offset: int = Query(0, ge=0),
|
|
user_id: Optional[int] = Query(default=None),
|
|
type_filter: Optional[str] = Query(default=None, alias="type"),
|
|
payment_method: Optional[str] = Query(default=None),
|
|
is_completed: Optional[bool] = Query(default=None),
|
|
date_from: Optional[datetime] = Query(default=None),
|
|
date_to: Optional[datetime] = Query(default=None),
|
|
) -> TransactionListResponse:
|
|
base_query = select(Transaction)
|
|
conditions = []
|
|
|
|
if user_id:
|
|
conditions.append(Transaction.user_id == user_id)
|
|
if type_filter:
|
|
conditions.append(Transaction.type == type_filter)
|
|
if payment_method:
|
|
conditions.append(Transaction.payment_method == payment_method)
|
|
if is_completed is not None:
|
|
conditions.append(Transaction.is_completed.is_(is_completed))
|
|
if date_from:
|
|
conditions.append(Transaction.created_at >= date_from)
|
|
if date_to:
|
|
conditions.append(Transaction.created_at <= date_to)
|
|
|
|
if conditions:
|
|
base_query = base_query.where(and_(*conditions))
|
|
|
|
total_query = base_query.with_only_columns(func.count()).order_by(None)
|
|
total = await db.scalar(total_query) or 0
|
|
|
|
result = await db.execute(
|
|
base_query.order_by(Transaction.created_at.desc()).offset(offset).limit(limit)
|
|
)
|
|
transactions = result.scalars().all()
|
|
|
|
return TransactionListResponse(
|
|
items=[_serialize(tx) for tx in transactions],
|
|
total=int(total),
|
|
limit=limit,
|
|
offset=offset,
|
|
)
|