88 lines
3.2 KiB
Python
88 lines
3.2 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") |