refactor stats menu / fix subscription renewal

This commit is contained in:
Capybara-z
2025-11-04 23:55:48 +03:00
parent 532f066ffb
commit 617cdbad10
3 changed files with 95 additions and 13 deletions
+28 -2
View File
@@ -33,10 +33,28 @@ async def count_active_keys(session: AsyncSession) -> int:
return await session.scalar(select(func.count()).select_from(Key).where(Key.expiry_time > current_time_ms))
async def count_trial_keys(session: AsyncSession) -> int:
async def count_active_paid_keys(session: AsyncSession) -> int:
current_time_ms = int(datetime.utcnow().timestamp() * 1000)
trial_tariffs_subquery = select(Tariff.id).where(Tariff.group_code == "trial")
return await session.scalar(
select(func.count())
.select_from(Key)
.where(Key.expiry_time > current_time_ms)
.where(~Key.tariff_id.in_(trial_tariffs_subquery))
)
return await session.scalar(select(func.count()).select_from(Key).where(Key.tariff_id.in_(trial_tariffs_subquery)))
async def count_active_trial_keys(session: AsyncSession) -> int:
current_time_ms = int(datetime.utcnow().timestamp() * 1000)
trial_tariffs_subquery = select(Tariff.id).where(Tariff.group_code == "trial")
return await session.scalar(
select(func.count())
.select_from(Key)
.where(Key.expiry_time > current_time_ms)
.where(Key.tariff_id.in_(trial_tariffs_subquery))
)
async def get_tariff_distribution(
@@ -80,6 +98,14 @@ async def get_tariff_durations(session: AsyncSession, tariff_ids: list[int]) ->
return dict(result.all())
async def get_tariff_subgroups(session: AsyncSession, tariff_ids: list[int]) -> dict[int, str | None]:
if not tariff_ids:
return {}
result = await session.execute(select(Tariff.id, Tariff.subgroup_title).where(Tariff.id.in_(tariff_ids)))
return dict(result.all())
async def count_total_referrals(session: AsyncSession) -> int:
return await session.scalar(select(func.count()).select_from(Referral))
+47 -11
View File
@@ -12,11 +12,12 @@ from bot import bot
from config import ADMIN_ID
from database import (
count_active_keys,
count_active_paid_keys,
count_active_trial_keys,
count_hot_leads,
count_total_keys,
count_total_referrals,
count_total_users,
count_trial_keys,
count_users_registered_between,
count_users_registered_since,
count_users_updated_today,
@@ -24,6 +25,7 @@ from database import (
get_tariff_durations,
get_tariff_groups,
get_tariff_names,
get_tariff_subgroups,
sum_payments_between,
sum_payments_since,
sum_total_payments,
@@ -92,20 +94,25 @@ async def handle_stats(callback_query: CallbackQuery, session: AsyncSession):
total_keys = await count_total_keys(session)
active_keys = await count_active_keys(session)
active_paid_keys = await count_active_paid_keys(session)
active_trial_keys = await count_active_trial_keys(session)
expired_keys = total_keys - active_keys
trial_keys_count = await count_trial_keys(session)
tariff_counts, no_tariff_keys = await get_tariff_distribution(session, include_unbound=True)
tariff_names = await get_tariff_names(session, [tid for tid, _ in tariff_counts])
tariff_groups = await get_tariff_groups(session, [tid for tid, _ in tariff_counts])
tariff_subgroups = await get_tariff_subgroups(session, [tid for tid, _ in tariff_counts])
tariff_durations = await get_tariff_durations(session, [tid for tid, _ in tariff_counts])
grouped_tariffs = {}
for tid, count in tariff_counts:
group = tariff_groups.get(tid, "unknown")
subgroup = tariff_subgroups.get(tid)
if group not in grouped_tariffs:
grouped_tariffs[group] = []
grouped_tariffs[group].append((tid, count))
grouped_tariffs[group] = {}
if subgroup not in grouped_tariffs[group]:
grouped_tariffs[group][subgroup] = []
grouped_tariffs[group][subgroup].append((tid, count))
tariff_stats_text = ""
duration_buckets = Counter()
@@ -137,12 +144,40 @@ async def handle_stats(callback_query: CallbackQuery, session: AsyncSession):
for name, count in sorted_buckets:
tariff_stats_text += f"{name}: <b>{count}</b>\n"
for group, tariffs in grouped_tariffs.items():
tariff_stats_text += f"Тариф {group}\n"
sorted_tariffs = sorted(tariffs, key=lambda x: tariff_durations.get(x[0], 0))
for tid, count in sorted_tariffs:
name = tariff_names.get(tid, f"ID {tid}")
tariff_stats_text += f"{name}: <b>{count}</b>\n"
for group_idx, (group, subgroups_dict) in enumerate(grouped_tariffs.items()):
group_total = 0
for tariffs_list in subgroups_dict.values():
group_total += sum(count for _, count in tariffs_list)
tariff_stats_text += f"Тариф <b>{group}</b> (<b>{group_total}</b>)\n"
sorted_subgroups = sorted(
subgroups_dict.items(),
key=lambda x: (x[0] is None, x[0] or "")
)
for subgroup_idx, (subgroup, tariffs) in enumerate(sorted_subgroups):
sorted_tariffs = sorted(tariffs, key=lambda x: tariff_durations.get(x[0], 0))
subgroup_total = sum(count for _, count in sorted_tariffs)
is_last_subgroup = subgroup_idx == len(sorted_subgroups) - 1
if subgroup:
prefix = "└─" if is_last_subgroup else "├─"
tariff_stats_text += f" {prefix} Подгруппа: <b>{subgroup}</b> (<b>{subgroup_total}</b>)\n"
for tariff_idx, (tid, count) in enumerate(sorted_tariffs):
name = tariff_names.get(tid, f"ID {tid}")
is_last_tariff = tariff_idx == len(sorted_tariffs) - 1
if subgroup:
if is_last_tariff and is_last_subgroup:
prefix = " └─"
else:
prefix = " ├─"
else:
if is_last_tariff and is_last_subgroup:
prefix = " └─"
else:
prefix = " ├─"
tariff_stats_text += f"{prefix} {name}: <b>{count}</b>\n"
tariff_stats_text = (
"└ По тарифам и срокам:\n" + tariff_stats_text if tariff_stats_text else "└ Нет данных по тарифам\n"
@@ -183,8 +218,9 @@ async def handle_stats(callback_query: CallbackQuery, session: AsyncSession):
f"<blockquote>"
f"├ 📦 Всего сгенерировано: <b>{total_keys}</b>\n"
f"├ ✅ Активных: <b>{active_keys}</b>\n"
f"│ ├ 💰 Платных: <b>{active_paid_keys}</b>\n"
f"│ └ 🧪 Триальных: <b>{active_trial_keys}</b>\n"
f"├ ❌ Просроченных: <b>{expired_keys}</b>\n"
f"├ 🧪 Триальных: <b>{trial_keys_count}</b>\n"
f"{tariff_stats_text}"
f"</blockquote>\n"
f"💰 <b>Финансы:</b>\n"
+20
View File
@@ -277,6 +277,26 @@ async def show_tariffs_in_renew_subgroup(callback: CallbackQuery, state: FSMCont
group_code = row[0]
tariff_id = record.get("tariff_id")
if tariff_id:
if await check_tariff_exists(session, tariff_id):
current_tariff = await get_tariff_by_id(session, tariff_id)
forbidden_groups = ["discounts", "discounts_max", "gifts", "trial"]
try:
hook_results = await run_hooks(
"renewal_forbidden_groups", chat_id=callback.from_user.id, admin=False, session=session
)
for hook_result in hook_results:
additional_groups = hook_result.get("additional_groups", [])
forbidden_groups.extend(additional_groups)
except Exception as e:
logger.warning(f"[RENEW_SUBGROUP] Ошибка при получении дополнительных групп: {e}")
if current_tariff and current_tariff["group_code"] not in forbidden_groups:
group_code = current_tariff["group_code"]
tg_id = callback.from_user.id
language_code = callback.from_user.language_code
discount_info = await check_hot_lead_discount(session, tg_id)