Update miniapp.py
This commit is contained in:
@@ -197,6 +197,8 @@ from ..schemas.miniapp import (
|
||||
MiniAppConnectedServer,
|
||||
MiniAppTrafficTopupRequest,
|
||||
MiniAppTrafficTopupResponse,
|
||||
MiniAppDailySubscriptionToggleRequest,
|
||||
MiniAppDailySubscriptionToggleResponse,
|
||||
)
|
||||
|
||||
|
||||
@@ -3414,6 +3416,26 @@ async def get_subscription_details(
|
||||
|
||||
devices_count, devices = await _load_devices_info(user)
|
||||
|
||||
# Загружаем данные суточного тарифа
|
||||
is_daily_tariff = False
|
||||
is_daily_paused = False
|
||||
daily_tariff_name = None
|
||||
daily_price_kopeks = None
|
||||
daily_price_label = None
|
||||
daily_next_charge_at = None
|
||||
|
||||
if subscription and getattr(subscription, "tariff_id", None):
|
||||
tariff = await get_tariff_by_id(db, subscription.tariff_id)
|
||||
if tariff and getattr(tariff, 'is_daily', False):
|
||||
is_daily_tariff = True
|
||||
is_daily_paused = getattr(subscription, 'is_daily_paused', False)
|
||||
daily_tariff_name = tariff.name
|
||||
daily_price_kopeks = getattr(tariff, 'daily_price_kopeks', 0)
|
||||
daily_price_label = settings.format_price(daily_price_kopeks) + "/день" if daily_price_kopeks > 0 else None
|
||||
# Следующее списание - через 24 часа от последнего обновления подписки или от start_date
|
||||
if subscription.end_date and not is_daily_paused:
|
||||
daily_next_charge_at = subscription.end_date
|
||||
|
||||
response_user = MiniAppSubscriptionUser(
|
||||
telegram_id=user.telegram_id,
|
||||
username=user.username,
|
||||
@@ -3443,6 +3465,12 @@ async def get_subscription_details(
|
||||
promo_offer_discount_percent=active_discount_percent,
|
||||
promo_offer_discount_expires_at=active_discount_expires_at,
|
||||
promo_offer_discount_source=promo_offer_source,
|
||||
is_daily_tariff=is_daily_tariff,
|
||||
is_daily_paused=is_daily_paused,
|
||||
daily_tariff_name=daily_tariff_name,
|
||||
daily_price_kopeks=daily_price_kopeks,
|
||||
daily_price_label=daily_price_label,
|
||||
daily_next_charge_at=daily_next_charge_at,
|
||||
)
|
||||
|
||||
referral_info = await _build_referral_info(db, user)
|
||||
@@ -6340,6 +6368,11 @@ async def _build_tariff_model(
|
||||
is_upgrade = upgrade
|
||||
is_switch_free = cost == 0
|
||||
|
||||
# Суточный тариф
|
||||
is_daily = getattr(tariff, 'is_daily', False)
|
||||
daily_price_kopeks = getattr(tariff, 'daily_price_kopeks', 0) if is_daily else 0
|
||||
daily_price_label = settings.format_price(daily_price_kopeks) + "/день" if is_daily and daily_price_kopeks > 0 else None
|
||||
|
||||
return MiniAppTariff(
|
||||
id=tariff.id,
|
||||
name=tariff.name,
|
||||
@@ -6358,6 +6391,9 @@ async def _build_tariff_model(
|
||||
switch_cost_label=switch_cost_label,
|
||||
is_upgrade=is_upgrade,
|
||||
is_switch_free=is_switch_free,
|
||||
is_daily=is_daily,
|
||||
daily_price_kopeks=daily_price_kopeks,
|
||||
daily_price_label=daily_price_label,
|
||||
)
|
||||
|
||||
|
||||
@@ -6378,6 +6414,11 @@ async def _build_current_tariff_model(db: AsyncSession, tariff, promo_group=None
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
# Суточный тариф
|
||||
is_daily = getattr(tariff, 'is_daily', False)
|
||||
daily_price_kopeks = getattr(tariff, 'daily_price_kopeks', 0) if is_daily else 0
|
||||
daily_price_label = settings.format_price(daily_price_kopeks) + "/день" if is_daily and daily_price_kopeks > 0 else None
|
||||
|
||||
return MiniAppCurrentTariff(
|
||||
id=tariff.id,
|
||||
name=tariff.name,
|
||||
@@ -6389,6 +6430,9 @@ async def _build_current_tariff_model(db: AsyncSession, tariff, promo_group=None
|
||||
device_limit=tariff.device_limit,
|
||||
servers_count=servers_count,
|
||||
monthly_price_kopeks=monthly_price,
|
||||
is_daily=is_daily,
|
||||
daily_price_kopeks=daily_price_kopeks,
|
||||
daily_price_label=daily_price_label,
|
||||
)
|
||||
|
||||
|
||||
@@ -7093,3 +7137,88 @@ async def purchase_traffic_topup_endpoint(
|
||||
new_balance_kopeks=user.balance_kopeks,
|
||||
charged_kopeks=final_price,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/subscription/daily/toggle-pause")
|
||||
async def toggle_daily_subscription_pause_endpoint(
|
||||
payload: MiniAppDailySubscriptionToggleRequest,
|
||||
db: AsyncSession = Depends(get_db_session),
|
||||
):
|
||||
"""Переключает паузу/активацию суточной подписки."""
|
||||
from app.webapi.schemas.miniapp import MiniAppDailySubscriptionToggleResponse
|
||||
from app.services.subscription_service import SubscriptionService
|
||||
|
||||
user = await _authorize_miniapp_user(payload.init_data, db)
|
||||
subscription = user.subscription
|
||||
|
||||
if not subscription:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail={"code": "no_subscription", "message": "No subscription found"},
|
||||
)
|
||||
|
||||
# Проверяем наличие тарифа
|
||||
tariff_id = getattr(subscription, 'tariff_id', None)
|
||||
if not tariff_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "no_tariff", "message": "Subscription has no tariff"},
|
||||
)
|
||||
|
||||
tariff = await get_tariff_by_id(db, tariff_id)
|
||||
if not tariff or not getattr(tariff, 'is_daily', False):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "not_daily_tariff", "message": "Subscription is not on a daily tariff"},
|
||||
)
|
||||
|
||||
# Переключаем состояние паузы
|
||||
is_currently_paused = getattr(subscription, 'is_daily_paused', False)
|
||||
new_paused_state = not is_currently_paused
|
||||
subscription.is_daily_paused = new_paused_state
|
||||
|
||||
# Если снимаем с паузы и подписка активна, нужно проверить баланс для активации
|
||||
if not new_paused_state:
|
||||
daily_price = getattr(tariff, 'daily_price_kopeks', 0)
|
||||
if daily_price > 0 and user.balance_kopeks < daily_price:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_402_PAYMENT_REQUIRED,
|
||||
detail={
|
||||
"code": "insufficient_balance",
|
||||
"message": "Insufficient balance to resume daily subscription",
|
||||
"required": daily_price,
|
||||
"balance": user.balance_kopeks,
|
||||
},
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(subscription)
|
||||
await db.refresh(user)
|
||||
|
||||
# Синхронизация с RemnaWave
|
||||
try:
|
||||
service = SubscriptionService()
|
||||
if new_paused_state:
|
||||
# При паузе отключаем пользователя в RemnaWave
|
||||
if user.remnawave_uuid:
|
||||
await service.disable_remnawave_user(user.remnawave_uuid)
|
||||
else:
|
||||
# При возобновлении включаем пользователя в RemnaWave
|
||||
if user.remnawave_uuid:
|
||||
await service.enable_remnawave_user(user.remnawave_uuid)
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка синхронизации с RemnaWave при паузе/возобновлении: {e}")
|
||||
|
||||
lang = getattr(user, "language", settings.DEFAULT_LANGUAGE)
|
||||
if new_paused_state:
|
||||
message = "Суточная подписка приостановлена" if lang == "ru" else "Daily subscription paused"
|
||||
else:
|
||||
message = "Суточная подписка возобновлена" if lang == "ru" else "Daily subscription resumed"
|
||||
|
||||
return MiniAppDailySubscriptionToggleResponse(
|
||||
success=True,
|
||||
message=message,
|
||||
is_paused=new_paused_state,
|
||||
balance_kopeks=user.balance_kopeks,
|
||||
balance_label=settings.format_price(user.balance_kopeks),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user