Files
remnawave-minishop/bot/services/promo_code_service.py
T
2025-05-14 08:43:23 +00:00

89 lines
3.5 KiB
Python

import logging
import aiosqlite
from datetime import datetime, timezone
from typing import Optional, Dict, Callable, Any, Tuple
from aiogram import Bot
from config.settings import Settings
from db.database import get_promo_code_by_code, increment_promo_activation, get_db_connection_manager, _setup_db_connection
from .subscription_service import SubscriptionService
from bot.middlewares.i18n import JsonI18n
class PromoCodeService:
def __init__(self, db_conn_provider: Callable[[], Any], settings: Settings,
subscription_service: SubscriptionService, bot: Bot,
i18n: JsonI18n):
self.db_conn_provider = db_conn_provider
self.settings = settings
self.subscription_service = subscription_service
self.bot = bot
self.i18n = i18n
async def apply_promo_code(self, user_id: int, code_input: str,
user_lang: str) -> Tuple[bool, str]:
"""
Applies a promo code for a user.
Returns: (success_status: bool, message_text_for_user: str)
"""
_ = lambda k, **kw: self.i18n.gettext(user_lang, k, **kw)
code_input_upper = code_input.strip().upper()
async with self.db_conn_provider() as db:
await _setup_db_connection(db)
try:
promo_data = await get_promo_code_by_code(code_input_upper,
db_conn=db)
if not promo_data:
return False, _("promo_code_not_found",
code=code_input_upper)
if promo_data['current_activations'] >= promo_data[
'max_activations']:
return False, _("promo_code_max_activations_reached",
code=code_input_upper)
active_sub = await self.subscription_service.get_active_subscription(
user_id)
if not active_sub:
return False, _("promo_code_no_active_subscription")
bonus_days = promo_data['bonus_days']
new_end_date = await self.subscription_service.extend_active_subscription_days(
user_id=user_id,
bonus_days=bonus_days,
db_conn=db,
reason=f"promo code {code_input_upper}")
if new_end_date:
activation_success = await increment_promo_activation(
promo_data['promo_code_id'],
user_id,
db_conn=db,
payment_id=None)
if activation_success:
await db.commit()
return True, _(
"promo_code_applied_success",
code=code_input_upper,
bonus_days=bonus_days,
new_end_date=new_end_date.strftime('%Y-%m-%d'))
else:
await db.rollback()
return False, _("promo_code_invalid_or_expired")
else:
await db.rollback()
return False, _("error_applying_promo_bonus")
except Exception as e:
logging.error(
f"Error applying promo code {code_input_upper} for user {user_id}: {e}",
exc_info=True)
await db.rollback()
return False, _("error_try_again")