diff --git a/database/hot_leads.py b/database/hot_leads.py index 0a14c612..1b5c0bc6 100644 --- a/database/hot_leads.py +++ b/database/hot_leads.py @@ -18,6 +18,8 @@ async def get_hot_leads(session: AsyncSession): select(Payment.tg_id) .distinct() .where(Payment.amount > 0) + .where(Payment.status == "success") + .where(Payment.payment_system.notin_(["referral", "coupon", "cashback"])) .where(~Payment.tg_id.in_(subquery)) ) diff --git a/database/statistics.py b/database/statistics.py index dfa1f561..f58aa429 100644 --- a/database/statistics.py +++ b/database/statistics.py @@ -160,7 +160,9 @@ async def count_hot_leads(session: AsyncSession) -> int: stmt = ( select(Payment.tg_id) + .where(Payment.amount > 0) .where(Payment.status == "success") + .where(Payment.payment_system.notin_(["referral", "coupon", "cashback"])) .where(not_(exists(subquery_active_keys.where(Key.tg_id == Payment.tg_id)))) .distinct() ) diff --git a/handlers/admin/users/users_handler.py b/handlers/admin/users/users_handler.py index 3aac019f..f21941c2 100644 --- a/handlers/admin/users/users_handler.py +++ b/handlers/admin/users/users_handler.py @@ -965,6 +965,33 @@ async def confirm_admin_key_reissue( servers = await get_servers(session) cluster_servers = servers.get(cluster_id, []) + tariffs = await get_tariffs_for_cluster(session, cluster_id) + if not tariffs: + builder = InlineKeyboardBuilder() + builder.row( + InlineKeyboardButton( + text="🔗 Привязать тариф", + callback_data=AdminPanelCallback(action="clusters").pack() + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data=AdminUserEditorCallback( + action="users_key_edit", tg_id=tg_id, data=email + ).pack() + ) + ) + await callback_query.message.edit_text( + f"🚫 Невозможно пересоздать подписку\n\n" + f"📊 Информация о кластере:\n
"
+ f"🌐 Кластер: {cluster_id}\n"
+ f"⚠️ Статус: Нет привязанного тарифа\n"
+ f"💡 Привяжите тариф к кластеру",
+ reply_markup=builder.as_markup()
+ )
+ return
+
if USE_COUNTRY_SELECTION:
unique_countries = {srv["server_name"] for srv in cluster_servers}
await state.update_data(tg_id=tg_id, email=email, cluster_id=cluster_id)
@@ -1005,11 +1032,42 @@ async def confirm_admin_key_reissue(
@router.callback_query(F.data.startswith("admin_reissue_country|"), IsAdminFilter())
-async def admin_reissue_country(callback_query: CallbackQuery, session: AsyncSession):
+async def admin_reissue_country(callback_query: CallbackQuery, session: AsyncSession, state: FSMContext):
_, tg_id, email, country = callback_query.data.split("|")
tg_id = int(tg_id)
try:
+ data = await state.get_data()
+ cluster_id = data.get("cluster_id")
+
+ if cluster_id:
+ tariffs = await get_tariffs_for_cluster(session, cluster_id)
+ if not tariffs:
+ builder = InlineKeyboardBuilder()
+ builder.row(
+ InlineKeyboardButton(
+ text="🔗 Привязать тариф",
+ callback_data=AdminPanelCallback(action="clusters").pack()
+ )
+ )
+ builder.row(
+ InlineKeyboardButton(
+ text="🔙 Назад",
+ callback_data=AdminUserEditorCallback(
+ action="users_key_edit", tg_id=tg_id, data=email
+ ).pack()
+ )
+ )
+ await callback_query.message.edit_text(
+ f"🚫 Невозможно пересоздать подписку\n\n"
+ f"📊 Информация о кластере:\n"
+ f"🌐 Кластер: {cluster_id}\n"
+ f"⚠️ Статус: Нет привязанного тарифа\n"
+ f"💡 Привяжите тариф к кластеру",
+ reply_markup=builder.as_markup()
+ )
+ return
+
result = await session.execute(
select(Key.remnawave_link, Key.tariff_id).where(Key.email == email)
)
diff --git a/handlers/keys/key_mode/key_create.py b/handlers/keys/key_mode/key_create.py
index 40cd9046..c39fe424 100644
--- a/handlers/keys/key_mode/key_create.py
+++ b/handlers/keys/key_mode/key_create.py
@@ -2,6 +2,7 @@ from datetime import datetime, timedelta
from typing import Any
from collections import defaultdict
from sqlalchemy.ext.asyncio import AsyncSession
+from sqlalchemy import select
import pytz
from aiogram import F, Router
@@ -26,7 +27,9 @@ from database import (
get_tariffs_for_cluster,
get_trial,
)
+from database.models import Admin
from database.tariffs import create_subgroup_hash, find_subgroup_by_hash
+from handlers.admin.panel.keyboard import AdminPanelCallback
from handlers.buttons import MAIN_MENU, PAYMENT
from handlers.payments.robokassa_pay import handle_custom_amount_input
from handlers.payments.stars_pay import process_custom_amount_input_stars
@@ -103,14 +106,39 @@ async def handle_key_creation(
tariffs = await get_tariffs_for_cluster(session, cluster_name)
if not tariffs:
+ result = await session.execute(select(Admin).where(Admin.tg_id == tg_id))
+ is_admin = result.scalar_one_or_none() is not None
+
+ if is_admin:
+ builder = InlineKeyboardBuilder()
+ builder.row(
+ InlineKeyboardButton(
+ text="🔗 Привязать тариф",
+ callback_data=AdminPanelCallback(action="clusters").pack()
+ )
+ )
+ builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile"))
+
+ text = (
+ f"🚫 Невозможно создать подписку\n\n"
+ f"📊 Информация о кластере:\n"
+ f"🌐 Кластер: {cluster_name}\n"
+ f"⚠️ Статус: Нет привязанного тарифа\n"
+ f"💡 Привяжите тариф к кластеру"
+ )
+ else:
+ builder = InlineKeyboardBuilder()
+ builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile"))
+ text = "❌ Нет доступных тарифов для выбора."
+
await edit_or_send_message(
target_message=(
message_or_query.message
if isinstance(message_or_query, CallbackQuery)
else message_or_query
),
- text="❌ Нет доступных тарифов для выбора.",
- reply_markup=None,
+ text=text,
+ reply_markup=builder.as_markup(),
)
return