from datetime import date, datetime from sqlalchemy import and_, func, not_, select from sqlalchemy.ext.asyncio import AsyncSession from database.models import Key, Payment, Referral, Tariff, User async def count_total_users(session: AsyncSession) -> int: return await session.scalar(select(func.count()).select_from(User)) async def count_users_updated_today(session: AsyncSession, today: date) -> int: return await session.scalar( select(func.count()).select_from(User).where(User.updated_at >= today) ) async def count_users_registered_since(session: AsyncSession, since: date) -> int: return await session.scalar( select(func.count()).select_from(User).where(User.created_at >= since) ) async def count_users_registered_between( session: AsyncSession, start: date, end: date ) -> int: return await session.scalar( select(func.count()) .select_from(User) .where(User.created_at >= start, User.created_at < end) ) async def count_total_keys(session: AsyncSession) -> int: return await session.scalar(select(func.count()).select_from(Key)) async def count_active_keys(session: AsyncSession) -> int: current_time_ms = int(datetime.utcnow().timestamp() * 1000) 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: subquery_success_payments = ( select(Payment.tg_id) .where(and_(Payment.tg_id == Key.tg_id, Payment.status == "success")) .exists() ) return await session.scalar( select(func.count()).select_from(Key).where(not_(subquery_success_payments)) ) async def get_tariff_distribution(session: AsyncSession) -> list[tuple[int, int]]: result = await session.execute( select(Key.tariff_id, func.count(Key.client_id)).group_by(Key.tariff_id) ) return result.all() async def get_tariff_names( session: AsyncSession, tariff_ids: list[int] ) -> dict[int, str]: if not tariff_ids: return {} result = await session.execute( select(Tariff.id, Tariff.name).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)) async def sum_payments_since(session: AsyncSession, since: date) -> float: return await session.scalar( select(func.coalesce(func.sum(Payment.amount), 0)).where( Payment.created_at >= since ) ) async def sum_payments_between(session: AsyncSession, start: date, end: date) -> float: return await session.scalar( select(func.coalesce(func.sum(Payment.amount), 0)).where( Payment.created_at >= start, Payment.created_at < end ) ) async def sum_total_payments(session: AsyncSession) -> float: return await session.scalar(select(func.coalesce(func.sum(Payment.amount), 0)))