Files
vpn-control-panel/app/bot/handlers/stats.py
smolkik-code 7c7c88621d Initial commit: VPN Control Panel
- FastAPI REST API with JWT auth
- aiogram 3 Telegram bot with admin middleware
- APScheduler daily tasks (expiry, reminders, revoke, sync)
- SQLAlchemy 2 async ORM with Alembic migrations
- Jinja2 admin panel (Dashboard, Users, Payments, Servers, Tariffs)
- VPN provider abstraction with MockProvider
- Stats service with revenue/subscription analytics
- Docker Compose (PostgreSQL + Redis + app)
- Healthcheck endpoint
2026-07-05 17:50:11 +07:00

56 lines
1.8 KiB
Python

from sqlalchemy import func, select
from aiogram import Router
from aiogram.filters import Command
from aiogram.types import Message
from app.bot.texts import stats_text
from app.database import async_session_factory
from app.models.payment import Payment, PaymentStatus
from app.models.server import Server
from app.models.tariff import Tariff
from app.models.user import User
router = Router(name="stats")
@router.message(Command("stats"))
async def cmd_stats(message: Message) -> None:
async with async_session_factory() as session:
async def _count(model, *filters) -> int:
stmt = select(func.count(model.id))
for f in filters:
stmt = stmt.where(f)
return (await session.execute(stmt)).scalar_one()
total_users = await _count(User)
active_users = await _count(User, User.is_active.is_(True))
total_tariffs = await _count(Tariff)
total_servers = await _count(Server)
active_servers = await _count(Server, Server.is_active.is_(True))
total_payments = await _count(Payment)
confirmed_payments = await _count(
Payment, Payment.status == PaymentStatus.CONFIRMED
)
rev_stmt = (
select(func.coalesce(func.sum(Payment.amount), 0))
.where(Payment.status == PaymentStatus.CONFIRMED)
)
total_revenue = float((await session.execute(rev_stmt)).scalar_one())
await message.answer(
stats_text(
total_users=total_users,
active_users=active_users,
total_tariffs=total_tariffs,
total_servers=total_servers,
active_servers=active_servers,
total_payments=total_payments,
confirmed_payments=confirmed_payments,
total_revenue=total_revenue,
),
parse_mode="HTML",
)