restore hot leads export and stats section
This commit is contained in:
+19
-1
@@ -1,6 +1,6 @@
|
||||
from datetime import date, datetime
|
||||
|
||||
from sqlalchemy import and_, func, not_, select
|
||||
from sqlalchemy import and_, func, not_, select, exists
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database.models import Key, Payment, Referral, Tariff, User
|
||||
@@ -125,3 +125,21 @@ async def sum_total_payments(session: AsyncSession) -> float:
|
||||
)
|
||||
)
|
||||
return round(float(result), 2)
|
||||
|
||||
|
||||
async def count_hot_leads(session: AsyncSession) -> int:
|
||||
subquery_active_keys = (
|
||||
select(Key.tg_id)
|
||||
.where(Key.expiry_time > int(datetime.utcnow().timestamp() * 1000))
|
||||
.distinct()
|
||||
)
|
||||
|
||||
stmt = (
|
||||
select(Payment.tg_id)
|
||||
.where(Payment.status == "success")
|
||||
.where(not_(exists(subquery_active_keys.where(Key.tg_id == Payment.tg_id))))
|
||||
.distinct()
|
||||
)
|
||||
|
||||
result = await session.execute(select(func.count()).select_from(stmt.subquery()))
|
||||
return result.scalar()
|
||||
@@ -24,6 +24,7 @@ from database import (
|
||||
sum_payments_between,
|
||||
sum_payments_since,
|
||||
sum_total_payments,
|
||||
count_hot_leads
|
||||
)
|
||||
from filters.admin import IsAdminFilter
|
||||
from logger import logger
|
||||
@@ -117,6 +118,7 @@ async def handle_stats(callback_query: CallbackQuery, session: AsyncSession):
|
||||
session, last_month_start, today.replace(day=1)
|
||||
)
|
||||
total_payments_all_time = await sum_total_payments(session)
|
||||
hot_leads_count = await count_hot_leads(session)
|
||||
|
||||
update_time = datetime.now(moscow_tz).strftime("%d.%m.%y %H:%M:%S")
|
||||
|
||||
@@ -152,6 +154,7 @@ async def handle_stats(callback_query: CallbackQuery, session: AsyncSession):
|
||||
f"├ 📆 Прошлый месяц: <b>{total_payments_last_month} ₽</b>\n"
|
||||
f"└ 🏦 Всего: <b>{total_payments_all_time} ₽</b>\n"
|
||||
f"</blockquote>\n"
|
||||
f"🔥 <b>Горячие лиды: {hot_leads_count}</b>\n"
|
||||
f"⏱️ <i>Последнее обновление:</i> <code>{update_time}</code>"
|
||||
)
|
||||
|
||||
|
||||
+26
-21
@@ -3,7 +3,7 @@ from datetime import datetime
|
||||
from io import StringIO
|
||||
|
||||
from aiogram.types import BufferedInputFile
|
||||
from sqlalchemy import func, join, select
|
||||
from sqlalchemy import func, join, select, exists, not_
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database.models import Key, Payment, Referral, Tariff, User
|
||||
@@ -164,41 +164,46 @@ async def export_referrals_csv(
|
||||
|
||||
|
||||
async def export_hot_leads_csv(session: AsyncSession) -> BufferedInputFile:
|
||||
users_alias = User.__table__.alias("u")
|
||||
payments_alias = Payment.__table__.alias("p")
|
||||
keys_alias = Key.__table__.alias("k")
|
||||
now_ts = int(datetime.utcnow().timestamp() * 1000)
|
||||
|
||||
j = users_alias.join(
|
||||
payments_alias, users_alias.c.tg_id == payments_alias.c.tg_id
|
||||
).outerjoin(keys_alias, users_alias.c.tg_id == keys_alias.c.tg_id)
|
||||
|
||||
query = (
|
||||
stmt = (
|
||||
select(
|
||||
users_alias.c.tg_id,
|
||||
users_alias.c.username,
|
||||
users_alias.c.first_name,
|
||||
users_alias.c.last_name,
|
||||
users_alias.c.updated_at,
|
||||
User.tg_id,
|
||||
User.username,
|
||||
User.first_name,
|
||||
User.last_name,
|
||||
User.updated_at,
|
||||
)
|
||||
.select_from(j)
|
||||
.where(payments_alias.c.status == "success", keys_alias.c.tg_id is None)
|
||||
.distinct()
|
||||
.order_by(users_alias.c.updated_at.desc())
|
||||
.where(
|
||||
exists(
|
||||
select(Payment.tg_id)
|
||||
.where(Payment.tg_id == User.tg_id)
|
||||
.where(Payment.status == "success")
|
||||
),
|
||||
not_(
|
||||
exists(
|
||||
select(Key.client_id)
|
||||
.where(Key.tg_id == User.tg_id)
|
||||
.where(Key.expiry_time > now_ts)
|
||||
)
|
||||
)
|
||||
)
|
||||
.order_by(User.updated_at.desc())
|
||||
)
|
||||
|
||||
result = await session.execute(query)
|
||||
result = await session.execute(stmt)
|
||||
users = result.all()
|
||||
|
||||
buffer = StringIO()
|
||||
writer = csv.writer(buffer)
|
||||
writer.writerow(["tg_id", "username", "first_name", "last_name", "updated_at"])
|
||||
|
||||
for user in users:
|
||||
writer.writerow(user)
|
||||
|
||||
buffer.seek(0)
|
||||
return BufferedInputFile(
|
||||
file=buffer.getvalue().encode("utf-8-sig"), filename="hot_leads_export.csv"
|
||||
file=buffer.getvalue().encode("utf-8-sig"),
|
||||
filename="hot_leads_export.csv",
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user