Export user payments to CSV
This commit is contained in:
@@ -180,3 +180,34 @@ async def cancel_expired_pending_payments(session: AsyncSession) -> int:
|
||||
await session.commit()
|
||||
affected = res.rowcount or 0
|
||||
return affected
|
||||
|
||||
|
||||
async def get_all_payments(
|
||||
session: AsyncSession,
|
||||
tg_id: int,
|
||||
statuses: list[str] | None = None,
|
||||
) -> list[dict]:
|
||||
query = select(Payment).where(Payment.tg_id == tg_id)
|
||||
|
||||
if statuses:
|
||||
query = query.where(Payment.status.in_(statuses))
|
||||
|
||||
query = query.order_by(Payment.created_at.desc())
|
||||
|
||||
result = await session.execute(query)
|
||||
payments = result.scalars().all()
|
||||
return [
|
||||
{
|
||||
"id": p.id,
|
||||
"tg_id": p.tg_id,
|
||||
"amount": p.amount,
|
||||
"currency": p.currency,
|
||||
"status": p.status,
|
||||
"payment_system": p.payment_system,
|
||||
"payment_id": p.payment_id,
|
||||
"created_at": p.created_at,
|
||||
"metadata": p.metadata_,
|
||||
"original_amount": p.original_amount,
|
||||
}
|
||||
for p in payments
|
||||
]
|
||||
|
||||
@@ -142,6 +142,12 @@ async def build_users_balance_kb(session: AsyncSession, tg_id: int) -> InlineKey
|
||||
callback_data=AdminUserEditorCallback(action="users_balance_set", tg_id=tg_id).pack(),
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="Выгрузить платежи",
|
||||
callback_data=AdminUserEditorCallback(action="users_balance_export", tg_id=tg_id).pack(),
|
||||
)
|
||||
)
|
||||
|
||||
builder.row(build_editor_back_btn(tg_id, True))
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database import get_balance, set_user_balance, update_balance
|
||||
from utils.csv_export import export_user_all_payments_csv
|
||||
from database.models import Payment
|
||||
from database.payments import add_payment
|
||||
from filters.admin import IsAdminFilter
|
||||
@@ -92,6 +93,21 @@ async def handle_balance_change(
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(
|
||||
AdminUserEditorCallback.filter(F.action == "users_balance_export"),
|
||||
IsAdminFilter(),
|
||||
)
|
||||
async def handle_balance_export(
|
||||
callback_query: CallbackQuery,
|
||||
callback_data: AdminUserEditorCallback,
|
||||
session: AsyncSession,
|
||||
):
|
||||
tg_id = callback_data.tg_id
|
||||
csv_file = await export_user_all_payments_csv(tg_id=tg_id, session=session)
|
||||
await callback_query.message.answer_document(csv_file)
|
||||
await callback_query.answer()
|
||||
|
||||
|
||||
@router.callback_query(
|
||||
AdminUserEditorCallback.filter(F.action == "users_balance_add"),
|
||||
IsAdminFilter(),
|
||||
|
||||
@@ -6,6 +6,7 @@ from io import StringIO
|
||||
from aiogram.types import BufferedInputFile
|
||||
from sqlalchemy import exists, func, join, not_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
import json
|
||||
|
||||
from core.constants import PAYMENT_SYSTEMS_EXCLUDED
|
||||
from database.models import Key, Payment, Referral, Tariff, User
|
||||
@@ -258,3 +259,67 @@ async def export_keys_csv(session: AsyncSession) -> BufferedInputFile:
|
||||
|
||||
buffer.seek(0)
|
||||
return BufferedInputFile(file=buffer.getvalue().encode("utf-8-sig"), filename="keys_export.csv")
|
||||
|
||||
|
||||
async def export_user_all_payments_csv(tg_id: int, session: AsyncSession) -> BufferedInputFile:
|
||||
query = (
|
||||
select(
|
||||
Payment.id,
|
||||
Payment.tg_id,
|
||||
Payment.payment_id,
|
||||
Payment.amount,
|
||||
Payment.currency,
|
||||
Payment.payment_system,
|
||||
Payment.status,
|
||||
Payment.original_amount,
|
||||
Payment.created_at,
|
||||
)
|
||||
.where(Payment.tg_id == tg_id)
|
||||
.order_by(Payment.created_at.asc())
|
||||
)
|
||||
|
||||
result = await session.execute(query)
|
||||
rows = result.all()
|
||||
|
||||
buffer = StringIO()
|
||||
writer = csv.writer(buffer)
|
||||
writer.writerow([
|
||||
"id",
|
||||
"tg_id",
|
||||
"payment_id",
|
||||
"amount",
|
||||
"currency",
|
||||
"payment_system",
|
||||
"status",
|
||||
"original_amount",
|
||||
"created_at",
|
||||
])
|
||||
|
||||
for (
|
||||
internal_id,
|
||||
user_tg_id,
|
||||
external_payment_id,
|
||||
amount,
|
||||
currency,
|
||||
payment_system,
|
||||
status,
|
||||
original_amount,
|
||||
created_at,
|
||||
) in rows:
|
||||
writer.writerow([
|
||||
internal_id,
|
||||
user_tg_id,
|
||||
external_payment_id or "",
|
||||
amount,
|
||||
currency,
|
||||
payment_system,
|
||||
status,
|
||||
original_amount if original_amount is not None else "",
|
||||
created_at,
|
||||
])
|
||||
|
||||
buffer.seek(0)
|
||||
return BufferedInputFile(
|
||||
file=buffer.getvalue().encode("utf-8-sig"),
|
||||
filename=f"user_{tg_id}_payments_full.csv",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user