Adding admin operations to the balance

This commit is contained in:
Vladless
2025-11-16 03:30:00 +03:00
parent 1d5c80cd35
commit 8b77ccda9e
9 changed files with 257 additions and 177 deletions
+2 -1
View File
@@ -1,10 +1,11 @@
from aiogram import Router
from . import users_bans, users_hwid, users_keys, users_manage
from . import users_bans, users_hwid, users_keys, users_manage, users_balance
router = Router()
router.include_router(users_manage.router)
router.include_router(users_balance.router)
router.include_router(users_hwid.router)
router.include_router(users_keys.router)
router.include_router(users_bans.router)
+225
View File
@@ -0,0 +1,225 @@
from datetime import datetime
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database import get_balance, set_user_balance, update_balance
from database.models import Payment
from database.payments import add_payment
from filters.admin import IsAdminFilter
from .keyboard import (
AdminUserEditorCallback,
build_users_balance_change_kb,
build_users_balance_kb,
)
from .users_states import UserEditorState
router = Router()
def format_admin_operation(amount: float, created_at: datetime) -> str:
date_str = created_at.strftime("%Y-%m-%d %H:%M:%S")
sign = "+" if amount > 0 else "-" if amount < 0 else ""
abs_amount = abs(amount)
return (
f"\n<blockquote>Админ {sign}{abs_amount}Р"
f"\n⏳ Дата: {date_str}</blockquote>"
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_edit"),
IsAdminFilter(),
)
async def handle_balance_change(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
session: AsyncSession,
):
tg_id = callback_data.tg_id
balance = await get_balance(session, tg_id)
balance = int(balance or 0)
stmt = (
select(Payment.amount, Payment.created_at)
.where(Payment.tg_id == tg_id, Payment.payment_system == "admin")
.order_by(Payment.created_at.desc())
.limit(5)
)
result = await session.execute(stmt)
records = result.all()
text = (
f"<b>💵 Изменение баланса</b>"
f"\n\n🆔 ID: <b>{tg_id}</b>"
f"\n💰 Баланс: <b>{balance}Р</b>"
f"\n📊 Операции админа (5):"
)
if records:
for amount, created_at in records:
text += format_admin_operation(amount, created_at)
else:
text += "\n<i>🚫 Операции отсутствуют</i>"
await callback_query.message.edit_text(
text=text,
reply_markup=await build_users_balance_kb(session, tg_id),
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_add"),
IsAdminFilter(),
)
async def handle_balance_add(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
state: FSMContext,
session: AsyncSession,
):
tg_id = callback_data.tg_id
amount = callback_data.data
if amount is not None:
amount = int(amount)
old_balance = await get_balance(session, tg_id)
if amount >= 0:
await update_balance(session, tg_id, amount)
new_balance = old_balance + amount
if amount != 0:
await add_payment(
session=session,
tg_id=tg_id,
amount=amount,
payment_system="admin",
status="success",
)
else:
new_balance = max(0, old_balance + amount)
await set_user_balance(session, tg_id, new_balance)
deducted = old_balance - new_balance
if deducted > 0:
await add_payment(
session=session,
tg_id=tg_id,
amount=-deducted,
payment_system="admin",
status="success",
)
if old_balance != new_balance:
await handle_balance_change(callback_query, callback_data, session)
return
await state.update_data(tg_id=tg_id, op_type="add")
await state.set_state(UserEditorState.waiting_for_balance)
await callback_query.message.edit_text(
text="✍️ Введите сумму, которую хотите добавить на баланс пользователя:",
reply_markup=build_users_balance_change_kb(tg_id),
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_take"),
IsAdminFilter(),
)
async def handle_balance_take(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
state: FSMContext,
):
tg_id = callback_data.tg_id
await state.update_data(tg_id=tg_id, op_type="take")
await state.set_state(UserEditorState.waiting_for_balance)
await callback_query.message.edit_text(
text="✍️ Введите сумму, которую хотите вычесть из баланса пользователя:",
reply_markup=build_users_balance_change_kb(tg_id),
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_set"),
IsAdminFilter(),
)
async def handle_balance_set(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
state: FSMContext,
):
tg_id = callback_data.tg_id
await state.update_data(tg_id=tg_id, op_type="set")
await state.set_state(UserEditorState.waiting_for_balance)
await callback_query.message.edit_text(
text="✍️ Введите баланс, который хотите установить пользователю:",
reply_markup=build_users_balance_change_kb(tg_id),
)
@router.message(UserEditorState.waiting_for_balance, IsAdminFilter())
async def handle_balance_input(message: Message, state: FSMContext, session: AsyncSession):
data = await state.get_data()
tg_id = data.get("tg_id")
op_type = data.get("op_type")
if not message.text.isdigit() or int(message.text) < 0:
await message.answer(
text="🚫 Пожалуйста, введите корректную сумму!",
reply_markup=build_users_balance_change_kb(tg_id),
)
return
amount = int(message.text)
if op_type == "add":
text = f"✅ К балансу пользователя добавлено <b>{amount}Р</b>"
await update_balance(session, tg_id, amount)
if amount != 0:
await add_payment(
session=session,
tg_id=tg_id,
amount=amount,
payment_system="admin",
status="success",
)
elif op_type == "take":
current_balance = await get_balance(session, tg_id)
new_balance = max(0, current_balance - amount)
deducted = current_balance if amount > current_balance else amount
text = f"✅ Из баланса пользователя было вычтено <b>{deducted}Р</b>"
await set_user_balance(session, tg_id, new_balance)
if deducted > 0:
await add_payment(
session=session,
tg_id=tg_id,
amount=-deducted,
payment_system="admin",
status="success",
)
else:
current_balance = await get_balance(session, tg_id)
text = f"✅ Баланс пользователя изменён на <b>{amount}Р</b>"
await set_user_balance(session, tg_id, amount)
delta = amount - current_balance
if delta != 0:
await add_payment(
session=session,
tg_id=tg_id,
amount=delta,
payment_system="admin",
status="success",
)
await message.answer(text=text, reply_markup=build_users_balance_change_kb(tg_id))
-160
View File
@@ -15,10 +15,7 @@ from sqlalchemy import func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from database import (
get_balance,
get_key_details,
set_user_balance,
update_balance,
update_trial,
)
from database.models import Key, ManualBan, Payment, Referral, User
@@ -35,8 +32,6 @@ from .keyboard import (
AdminUserEditorCallback,
build_editor_kb,
build_user_edit_kb,
build_users_balance_change_kb,
build_users_balance_kb,
)
from .users_states import UserEditorState
@@ -263,161 +258,6 @@ async def handle_trial_restore(
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_edit"),
IsAdminFilter(),
)
async def handle_balance_change(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
session: AsyncSession,
):
tg_id = callback_data.tg_id
stmt = (
select(Payment.amount, Payment.payment_system, Payment.status, Payment.created_at)
.where(Payment.tg_id == tg_id)
.order_by(Payment.created_at.desc())
.limit(5)
)
result = await session.execute(stmt)
records = result.all()
balance = await get_balance(session, tg_id)
balance = int(balance or 0)
text = (
f"<b>💵 Изменение баланса</b>"
f"\n\n🆔 ID: <b>{tg_id}</b>"
f"\n💰 Баланс: <b>{balance}Р</b>"
f"\n📊 Последние операции (5):"
)
if records:
for amount, payment_system, status, created_at in records:
date = created_at.strftime("%Y-%m-%d %H:%M:%S")
text += (
f"\n<blockquote>💸 Сумма: {amount} | {payment_system}"
f"\n📌 Статус: {status}"
f"\n⏳ Дата: {date}</blockquote>"
)
else:
text += "\n <i>🚫 Отсутствуют</i>"
await callback_query.message.edit_text(
text=text,
reply_markup=await build_users_balance_kb(session, tg_id),
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_add"),
IsAdminFilter(),
)
async def handle_balance_add(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
state: FSMContext,
session: AsyncSession,
):
tg_id = callback_data.tg_id
amount = callback_data.data
if amount is not None:
amount = int(amount)
old_balance = await get_balance(session, tg_id)
if amount >= 0:
await update_balance(session, tg_id, amount)
new_balance = old_balance + amount
else:
new_balance = max(0, old_balance + amount)
await set_user_balance(session, tg_id, new_balance)
if old_balance != new_balance:
await handle_balance_change(callback_query, callback_data, session)
return
await state.update_data(tg_id=tg_id, op_type="add")
await state.set_state(UserEditorState.waiting_for_balance)
await callback_query.message.edit_text(
text="✍️ Введите сумму, которую хотите добавить на баланс пользователя:",
reply_markup=build_users_balance_change_kb(tg_id),
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_take"),
IsAdminFilter(),
)
async def handle_balance_take(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
state: FSMContext,
):
tg_id = callback_data.tg_id
await state.update_data(tg_id=tg_id, op_type="take")
await state.set_state(UserEditorState.waiting_for_balance)
await callback_query.message.edit_text(
text="✍️ Введите сумму, которую хотите вычесть из баланса пользователя:",
reply_markup=build_users_balance_change_kb(tg_id),
)
@router.callback_query(
AdminUserEditorCallback.filter(F.action == "users_balance_set"),
IsAdminFilter(),
)
async def handle_balance_set(
callback_query: CallbackQuery,
callback_data: AdminUserEditorCallback,
state: FSMContext,
):
tg_id = callback_data.tg_id
await state.update_data(tg_id=tg_id, op_type="set")
await state.set_state(UserEditorState.waiting_for_balance)
await callback_query.message.edit_text(
text="✍️ Введите баланс, который хотите установить пользователю:",
reply_markup=build_users_balance_change_kb(tg_id),
)
@router.message(UserEditorState.waiting_for_balance, IsAdminFilter())
async def handle_balance_input(message: Message, state: FSMContext, session: AsyncSession):
data = await state.get_data()
tg_id = data.get("tg_id")
op_type = data.get("op_type")
if not message.text.isdigit() or int(message.text) < 0:
await message.answer(
text="🚫 Пожалуйста, введите корректную сумму!",
reply_markup=build_users_balance_change_kb(tg_id),
)
return
amount = int(message.text)
if op_type == "add":
text = f"✅ К балансу пользователя добавлено <b>{amount}Р</b>"
await update_balance(session, tg_id, amount)
elif op_type == "take":
current_balance = await get_balance(session, tg_id)
new_balance = max(0, current_balance - amount)
deducted = current_balance if amount > current_balance else amount
text = f"✅ Из баланса пользователя было вычтено <b>{deducted}Р</b>"
await set_user_balance(session, tg_id, new_balance)
else:
text = f"✅ Баланс пользователя изменен на <b>{amount}Р</b>"
await set_user_balance(session, tg_id, amount)
await message.answer(text=text, reply_markup=build_users_balance_change_kb(tg_id))
@router.callback_query(
AdminPanelCallback.filter(F.action == "restore_trials"),
IsAdminFilter(),