diff --git a/app/database/crud/subscription.py b/app/database/crud/subscription.py index 13594e43..cb5b8582 100644 --- a/app/database/crud/subscription.py +++ b/app/database/crud/subscription.py @@ -486,14 +486,50 @@ async def add_subscription_traffic( subscription: Subscription, gb: int ) -> Subscription: - + subscription.add_traffic(gb) subscription.updated_at = datetime.utcnow() - + + # Создаём новую запись докупки с индивидуальной датой истечения (30 дней) + from app.database.models import TrafficPurchase + from sqlalchemy import select as sql_select + from datetime import timedelta + + new_expires_at = datetime.utcnow() + timedelta(days=30) + new_purchase = TrafficPurchase( + subscription_id=subscription.id, + traffic_gb=gb, + expires_at=new_expires_at + ) + db.add(new_purchase) + + # Обновляем общий счетчик докупленного трафика + current_purchased = getattr(subscription, 'purchased_traffic_gb', 0) or 0 + subscription.purchased_traffic_gb = current_purchased + gb + + # Устанавливаем traffic_reset_at на ближайшую дату истечения из всех активных докупок + now = datetime.utcnow() + active_purchases_query = ( + sql_select(TrafficPurchase) + .where(TrafficPurchase.subscription_id == subscription.id) + .where(TrafficPurchase.expires_at > now) + ) + active_purchases_result = await db.execute(active_purchases_query) + active_purchases = active_purchases_result.scalars().all() + + if active_purchases: + # Добавляем только что созданную покупку к списку + all_active = list(active_purchases) + [new_purchase] + earliest_expiry = min(p.expires_at for p in all_active) + subscription.traffic_reset_at = earliest_expiry + else: + # Первая докупка + subscription.traffic_reset_at = new_expires_at + await db.commit() await db.refresh(subscription) - - logger.info(f"📈 К подписке пользователя {subscription.user_id} добавлено {gb} ГБ трафика") + + logger.info(f"📈 К подписке пользователя {subscription.user_id} добавлено {gb} ГБ трафика (истекает {new_expires_at.strftime('%d.%m.%Y')})") return subscription diff --git a/app/handlers/subscription/traffic.py b/app/handlers/subscription/traffic.py index fec735da..23833f3b 100644 --- a/app/handlers/subscription/traffic.py +++ b/app/handlers/subscription/traffic.py @@ -608,42 +608,8 @@ async def add_traffic( subscription.purchased_traffic_gb = 0 subscription.traffic_reset_at = None else: + # add_subscription_traffic уже создаёт TrafficPurchase и обновляет все необходимые поля await add_subscription_traffic(db, subscription, traffic_gb) - # Создаём новую запись докупки с индивидуальной датой истечения - from app.database.models import TrafficPurchase - from sqlalchemy import select as sql_select - from datetime import timedelta - - new_expires_at = datetime.utcnow() + timedelta(days=30) - new_purchase = TrafficPurchase( - subscription_id=subscription.id, - traffic_gb=traffic_gb, - expires_at=new_expires_at - ) - db.add(new_purchase) - - # Обновляем общий счетчик докупленного трафика - current_purchased = getattr(subscription, 'purchased_traffic_gb', 0) or 0 - subscription.purchased_traffic_gb = current_purchased + traffic_gb - - # Устанавливаем traffic_reset_at на ближайшую дату истечения из всех активных докупок - now = datetime.utcnow() - active_purchases_query = ( - sql_select(TrafficPurchase) - .where(TrafficPurchase.subscription_id == subscription.id) - .where(TrafficPurchase.expires_at > now) - ) - active_purchases_result = await db.execute(active_purchases_query) - active_purchases = active_purchases_result.scalars().all() - - if active_purchases: - # Добавляем только что созданную покупку к списку - all_active = list(active_purchases) + [new_purchase] - earliest_expiry = min(p.expires_at for p in all_active) - subscription.traffic_reset_at = earliest_expiry - else: - # Первая докупка - subscription.traffic_reset_at = new_expires_at subscription_service = SubscriptionService() await subscription_service.update_remnawave_user(db, subscription) diff --git a/app/webapi/routes/miniapp.py b/app/webapi/routes/miniapp.py index 43ebcfe5..1a4e73c3 100644 --- a/app/webapi/routes/miniapp.py +++ b/app/webapi/routes/miniapp.py @@ -7269,14 +7269,9 @@ async def purchase_traffic_topup_endpoint( }, ) - # Добавляем трафик + # Добавляем трафик (add_subscription_traffic уже создаёт TrafficPurchase и обновляет все необходимые поля) await add_subscription_traffic(db, subscription, payload.gb) - # Обновляем purchased_traffic_gb - current_purchased = getattr(subscription, 'purchased_traffic_gb', 0) or 0 - subscription.purchased_traffic_gb = current_purchased + payload.gb - await db.commit() - # Синхронизируем с RemnaWave try: service = SubscriptionService()