Files
vpn-control-panel/app/scheduler/tasks/expire_subscriptions.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

62 lines
2.1 KiB
Python

from loguru import logger
from app.database import async_session_factory
from app.models.payment import PaymentStatus
from app.repositories.notification import NotificationRepository
from app.repositories.payment import PaymentRepository
from app.repositories.tariff import TariffRepository
from app.repositories.user import UserRepository
from app.services.billing import BillingService
from app.services.notification import NotificationService
from app.services.user import UserService
async def expire_subscriptions() -> None:
logger.info("[Scheduler] Starting subscription expiry check")
async with async_session_factory() as session:
payment_repo = PaymentRepository(session)
tariff_repo = TariffRepository(session)
user_repo = UserRepository(session)
billing = BillingService(payment_repo, tariff_repo, user_repo)
user_service = UserService(user_repo)
notification_service = NotificationService(
NotificationRepository(session), user_repo
)
expired_ids = await billing.expire_subscriptions()
if not expired_ids:
logger.info("[Scheduler] No expired subscriptions found")
return
for user_id in set(expired_ids):
user = await user_service.get_by_id(user_id)
if user is None:
continue
tariff = None
expired_payments = await payment_repo.get_by_user_and_status(
user_id=user_id, status=PaymentStatus.CONFIRMED
)
if expired_payments:
tariff = await tariff_repo.get(expired_payments[0].tariff_id)
await user_service.deactivate(user_id)
await notification_service.send_subscription_expired(
user_id=user_id,
tariff_name=tariff.name if tariff else None,
)
logger.info(
"[Scheduler] User {} deactivated, expired notification sent",
user_id,
)
logger.info(
"[Scheduler] Expired {} subscriptions, deactivated {} users",
len(expired_ids),
len(set(expired_ids)),
)