Files
remnawave-minishop/bot/services/promo_code_service.py
T

78 lines
2.8 KiB
Python

import logging
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Optional, Tuple, Dict
from aiogram import Bot
from config.settings import Settings
from db.dal import promo_code_dal, user_dal, subscription_dal
from db.models import PromoCode, User
from .subscription_service import SubscriptionService
from bot.middlewares.i18n import JsonI18n
class PromoCodeService:
def __init__(self, settings: Settings,
subscription_service: SubscriptionService, bot: Bot,
i18n: JsonI18n):
self.settings = settings
self.subscription_service = subscription_service
self.bot = bot
self.i18n = i18n
async def apply_promo_code(self, session: AsyncSession, user_id: int,
code_input: str,
user_lang: str) -> Tuple[bool, str]:
_ = lambda k, **kw: self.i18n.gettext(user_lang, k, **kw)
code_input_upper = code_input.strip().upper()
promo_data = await promo_code_dal.get_active_promo_code_by_code_str(
session, code_input_upper)
if not promo_data:
return False, _("promo_code_not_found", code=code_input_upper)
existing_activation = await promo_code_dal.get_user_activation_for_promo(
session, promo_data.promo_code_id, user_id)
if existing_activation:
return False, _("promo_code_already_used_by_user",
code=code_input_upper)
active_sub = await subscription_dal.get_active_subscription_by_user_id(
session, 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(
session=session,
user_id=user_id,
bonus_days=bonus_days,
reason=f"promo code {code_input_upper}")
if new_end_date:
activation_recorded = await promo_code_dal.record_promo_activation(
session, promo_data.promo_code_id, user_id, payment_id=None)
promo_incremented = await promo_code_dal.increment_promo_code_usage(
session, promo_data.promo_code_id)
if activation_recorded and promo_incremented:
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:
logging.error(
f"Failed to record activation or increment usage for promo {promo_data.code} by user {user_id}"
)
return False, _("error_applying_promo_bonus")
else:
return False, _("error_applying_promo_bonus")