Adding admin operations to the balance
This commit is contained in:
@@ -0,0 +1 @@
|
||||
PAYMENT_SYSTEMS_EXCLUDED = ("referral", "coupon", "cashback", "admin")
|
||||
@@ -2,6 +2,7 @@ from sqlalchemy import func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database.models import Key, Payment, User
|
||||
from core.constants import PAYMENT_SYSTEMS_EXCLUDED
|
||||
|
||||
|
||||
async def get_hot_leads(session: AsyncSession):
|
||||
@@ -16,7 +17,7 @@ async def get_hot_leads(session: AsyncSession):
|
||||
.where(User.trial == 1)
|
||||
.where(Payment.amount > 0)
|
||||
.where(Payment.status == "success")
|
||||
.where(Payment.payment_system.notin_(["referral", "coupon", "cashback"]))
|
||||
.where(Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED))
|
||||
.where(~Payment.tg_id.in_(sub_active))
|
||||
)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from sqlalchemy import and_, exists, func, not_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database.models import Key, Payment, Referral, Tariff, User
|
||||
from core.constants import PAYMENT_SYSTEMS_EXCLUDED
|
||||
|
||||
|
||||
async def count_total_users(session: AsyncSession) -> int:
|
||||
@@ -116,7 +117,7 @@ async def sum_payments_since(session: AsyncSession, since: date) -> float:
|
||||
and_(
|
||||
Payment.created_at >= since,
|
||||
Payment.status == "success",
|
||||
Payment.payment_system.notin_(["referral", "coupon", "cashback"]),
|
||||
Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED),
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -130,7 +131,7 @@ async def sum_payments_between(session: AsyncSession, start: date, end: date) ->
|
||||
Payment.created_at >= start,
|
||||
Payment.created_at < end,
|
||||
Payment.status == "success",
|
||||
Payment.payment_system.notin_(["referral", "coupon", "cashback"]),
|
||||
Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED),
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -142,7 +143,7 @@ async def sum_total_payments(session: AsyncSession) -> float:
|
||||
select(func.coalesce(func.sum(Payment.amount), 0)).where(
|
||||
and_(
|
||||
Payment.status == "success",
|
||||
Payment.payment_system.notin_(["referral", "coupon", "cashback"]),
|
||||
Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED),
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -158,7 +159,7 @@ async def count_hot_leads(session: AsyncSession) -> int:
|
||||
select(Payment.tg_id)
|
||||
.where(Payment.amount > 0)
|
||||
.where(Payment.status == "success")
|
||||
.where(Payment.payment_system.notin_(["referral", "coupon", "cashback"]))
|
||||
.where(Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED))
|
||||
.where(not_(exists(subquery_active_keys.where(Key.tg_id == Payment.tg_id))))
|
||||
.distinct()
|
||||
)
|
||||
|
||||
@@ -4,9 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database.models import Payment, TrackingSource, User
|
||||
from logger import logger
|
||||
|
||||
|
||||
EXCLUDED_PAYMENT_MARKERS = ["coupon", "referral", "cashback"]
|
||||
from core.constants import PAYMENT_SYSTEMS_EXCLUDED
|
||||
|
||||
|
||||
async def create_tracking_source(session: AsyncSession, name: str, code: str, type_: str, created_by: int):
|
||||
@@ -43,7 +41,11 @@ async def get_all_tracking_sources(session: AsyncSession) -> list[dict]:
|
||||
payments_subq = (
|
||||
select(func.count(func.distinct(Payment.tg_id)))
|
||||
.join(User, Payment.tg_id == User.tg_id)
|
||||
.where((User.source_code == TrackingSource.code) & (Payment.status == "success"))
|
||||
.where(
|
||||
(User.source_code == TrackingSource.code)
|
||||
& (Payment.status == "success")
|
||||
& Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED)
|
||||
)
|
||||
.correlate(TrackingSource)
|
||||
.scalar_subquery()
|
||||
)
|
||||
@@ -103,7 +105,7 @@ async def get_tracking_source_stats(session: AsyncSession, code: str) -> dict |
|
||||
.where(
|
||||
(User.source_code == code)
|
||||
& (Payment.status == "success")
|
||||
& not_(Payment.payment_system.in_(EXCLUDED_PAYMENT_MARKERS))
|
||||
& Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED)
|
||||
& (Payment.created_at >= created_at)
|
||||
)
|
||||
.scalar_subquery()
|
||||
@@ -115,7 +117,7 @@ async def get_tracking_source_stats(session: AsyncSession, code: str) -> dict |
|
||||
.where(
|
||||
(User.source_code == code)
|
||||
& (Payment.status == "success")
|
||||
& not_(Payment.payment_system.in_(EXCLUDED_PAYMENT_MARKERS))
|
||||
& Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED)
|
||||
& (Payment.created_at >= created_at)
|
||||
)
|
||||
.scalar_subquery()
|
||||
@@ -146,7 +148,7 @@ async def get_tracking_source_stats(session: AsyncSession, code: str) -> dict |
|
||||
.where(
|
||||
(User.source_code == code)
|
||||
& (Payment.status == "success")
|
||||
& not_(Payment.payment_system.in_(EXCLUDED_PAYMENT_MARKERS))
|
||||
& Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED)
|
||||
& (Payment.created_at >= created_at)
|
||||
)
|
||||
.subquery()
|
||||
|
||||
@@ -16,6 +16,7 @@ from database import create_blocked_user
|
||||
from database.models import BlockedUser, Key, ManualBan, Payment, Server, Tariff, User
|
||||
from filters.admin import IsAdminFilter
|
||||
from logger import logger
|
||||
from core.constants import PAYMENT_SYSTEMS_EXCLUDED
|
||||
|
||||
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
|
||||
from .keyboard import AdminSenderCallback, build_clusters_kb, build_sender_kb
|
||||
@@ -113,7 +114,10 @@ async def get_recipients(session: AsyncSession, send_to: str, cluster_name: str
|
||||
query = None
|
||||
if send_to == "subscribed":
|
||||
query = (
|
||||
select(distinct(User.tg_id)).join(Key).where(Key.expiry_time > now_ms).where(~User.tg_id.in_(banned_tg_ids))
|
||||
select(distinct(User.tg_id))
|
||||
.join(Key)
|
||||
.where(Key.expiry_time > now_ms)
|
||||
.where(~User.tg_id.in_(banned_tg_ids))
|
||||
)
|
||||
elif send_to == "unsubscribed":
|
||||
subquery = (
|
||||
@@ -151,7 +155,7 @@ async def get_recipients(session: AsyncSession, send_to: str, cluster_name: str
|
||||
.join(Payment, User.tg_id == Payment.tg_id)
|
||||
.where(Payment.status == "success")
|
||||
.where(Payment.amount > 0)
|
||||
.where(Payment.payment_system.notin_(["referral", "coupon", "cashback"]))
|
||||
.where(Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED))
|
||||
.where(not_(exists(subquery_active_keys.where(Key.tg_id == User.tg_id))))
|
||||
.where(~User.tg_id.in_(banned_tg_ids))
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
@@ -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(),
|
||||
|
||||
+7
-2
@@ -8,6 +8,7 @@ from sqlalchemy import exists, func, join, not_, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database.models import Key, Payment, Referral, Tariff, User
|
||||
from core.constants import PAYMENT_SYSTEMS_EXCLUDED
|
||||
|
||||
|
||||
async def export_users_csv(session: AsyncSession) -> BufferedInputFile:
|
||||
@@ -61,6 +62,7 @@ async def export_payments_csv(session: AsyncSession) -> BufferedInputFile:
|
||||
Payment.created_at,
|
||||
)
|
||||
.select_from(j)
|
||||
.where(Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED))
|
||||
.order_by(Payment.created_at.asc())
|
||||
)
|
||||
|
||||
@@ -84,7 +86,10 @@ async def export_user_payments_csv(tg_id: int, session: AsyncSession) -> Buffere
|
||||
Payment.created_at,
|
||||
)
|
||||
.select_from(j)
|
||||
.where(User.tg_id == tg_id)
|
||||
.where(
|
||||
User.tg_id == tg_id,
|
||||
Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED),
|
||||
)
|
||||
.order_by(Payment.created_at.asc())
|
||||
)
|
||||
|
||||
@@ -169,7 +174,7 @@ async def export_hot_leads_csv(session: AsyncSession) -> BufferedInputFile:
|
||||
.where(Payment.tg_id == User.tg_id)
|
||||
.where(Payment.status == "success")
|
||||
.where(Payment.amount > 0)
|
||||
.where(Payment.payment_system.notin_(["referral", "coupon", "cashback"]))
|
||||
.where(Payment.payment_system.notin_(PAYMENT_SYSTEMS_EXCLUDED))
|
||||
),
|
||||
not_(exists(select(Key.tg_id).where(Key.tg_id == User.tg_id).where(Key.expiry_time > now_ts))),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user