chore: run lint and prettifier

This commit is contained in:
3252a8
2026-05-12 21:54:12 +03:00
parent f31540afdb
commit 11187487b4
174 changed files with 12383 additions and 6688 deletions
+132 -133
View File
@@ -1,52 +1,51 @@
import logging
from datetime import datetime, timedelta, timezone
from typing import Any, Dict, Optional
from aiogram import Bot
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import text
from typing import Optional, Dict, Any
from aiogram import Bot
from datetime import datetime, timezone, timedelta
from config.settings import Settings
from db.dal import user_dal
from db.dal import payment_dal
from db.models import User
from db.dal import subscription_dal
from bot.middlewares.i18n import JsonI18n
from config.settings import Settings
from db.dal import payment_dal, subscription_dal, user_dal
from .subscription_service import SubscriptionService
class ReferralService:
def __init__(self, settings: Settings,
subscription_service: SubscriptionService, bot: Bot,
i18n: JsonI18n):
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_referral_bonuses_for_payment(
self,
session: AsyncSession,
referee_user_id: int,
purchased_subscription_months: int,
current_payment_db_id: Optional[int] = None,
skip_if_active_before_payment: bool = True) -> Dict[str, Any]:
self,
session: AsyncSession,
referee_user_id: int,
purchased_subscription_months: int,
current_payment_db_id: Optional[int] = None,
skip_if_active_before_payment: bool = True,
) -> Dict[str, Any]:
referee_final_end_date: Optional[datetime] = None
referee_bonus_applied_days: Optional[int] = None
inviter_bonus_successfully_applied = False
try:
referee_user_model = await user_dal.get_user_by_id(
session, referee_user_id)
referee_user_model = await user_dal.get_user_by_id(session, referee_user_id)
if not referee_user_model or referee_user_model.referred_by_id is None:
logging.debug(
f"User {referee_user_id} not referred or inviter ID missing. No referral bonuses."
)
return {
"referee_bonus_applied_days": None,
"referee_new_end_date": None
}
return {"referee_bonus_applied_days": None, "referee_new_end_date": None}
# If configured to apply referral bonuses only once per invited user,
# check if the referee already has succeeded payments.
@@ -59,55 +58,63 @@ class ReferralService:
)
if succeeded_count and succeeded_count > 0:
logging.info(
f"Referral bonuses skipped for user {referee_user_id}: already has {succeeded_count} succeeded payments.")
return {
"referee_bonus_applied_days": None,
"referee_new_end_date": None
}
f"Referral bonuses skipped for user {referee_user_id}: already has {succeeded_count} succeeded payments."
)
return {"referee_bonus_applied_days": None, "referee_new_end_date": None}
except Exception as e_cnt:
logging.error(f"Failed counting succeeded payments for user {referee_user_id}: {e_cnt}")
logging.error(
f"Failed counting succeeded payments for user {referee_user_id}: {e_cnt}"
)
# Additionally, do not award referral bonuses if the user was active at payment time
# (has an active subscription now). This avoids giving bonuses to already active users.
if skip_if_active_before_payment:
try:
if await self.subscription_service.has_active_subscription(session, referee_user_id):
if await self.subscription_service.has_active_subscription(
session, referee_user_id
):
logging.info(
f"Referral bonuses skipped for user {referee_user_id}: user currently has an active subscription.")
return {
"referee_bonus_applied_days": None,
"referee_new_end_date": None
}
f"Referral bonuses skipped for user {referee_user_id}: user currently has an active subscription."
)
return {"referee_bonus_applied_days": None, "referee_new_end_date": None}
except Exception as e_sub:
logging.error(f"Failed to check active subscription for {referee_user_id}: {e_sub}")
logging.error(
f"Failed to check active subscription for {referee_user_id}: {e_sub}"
)
inviter_user_id = referee_user_model.referred_by_id
inviter_user_model = await user_dal.get_user_by_id(
session, inviter_user_id)
inviter_user_model = await user_dal.get_user_by_id(session, inviter_user_id)
referee_name_for_msg = referee_user_model.first_name or f"User {referee_user_id}"
default_lang_for_placeholder = self.settings.DEFAULT_LANGUAGE
inviter_name_for_referee_msg = (
inviter_user_model.first_name if inviter_user_model
and inviter_user_model.first_name else self.i18n.gettext(
default_lang_for_placeholder, "friend_placeholder"))
inviter_user_model.first_name
if inviter_user_model and inviter_user_model.first_name
else self.i18n.gettext(default_lang_for_placeholder, "friend_placeholder")
)
inviter_bonus_days = self.settings.referral_bonus_inviter.get(
purchased_subscription_months)
purchased_subscription_months
)
referee_bonus_days = self.settings.referral_bonus_referee.get(
purchased_subscription_months)
purchased_subscription_months
)
if inviter_bonus_days and inviter_bonus_days > 0:
if not inviter_user_model:
logging.warning(
f"Inviter user {inviter_user_id} not found in local DB. Cannot apply inviter bonus."
)
else:
inviter_panel_uuid, inviter_panel_sub_link_id, _, _ = await self.subscription_service._get_or_create_panel_user_link_details(
session, inviter_user_id, inviter_user_model)
(
inviter_panel_uuid,
inviter_panel_sub_link_id,
_,
_,
) = await self.subscription_service._get_or_create_panel_user_link_details(
session, inviter_user_id, inviter_user_model
)
if not inviter_panel_uuid:
logging.warning(
@@ -115,11 +122,13 @@ class ReferralService:
)
else:
new_end_date_inviter = await self.subscription_service.extend_active_subscription_days(
session=session,
user_id=inviter_user_id,
bonus_days=inviter_bonus_days,
reason=f"referral bonus from {referee_name_for_msg}"
new_end_date_inviter = (
await self.subscription_service.extend_active_subscription_days(
session=session,
user_id=inviter_user_id,
bonus_days=inviter_bonus_days,
reason=f"referral bonus from {referee_name_for_msg}",
)
)
if new_end_date_inviter:
@@ -129,29 +138,30 @@ class ReferralService:
)
try:
inviter_lang = inviter_user_model.language_code or default_lang_for_placeholder
_i = lambda k, **kw: self.i18n.gettext(
inviter_lang, k, **kw)
inviter_lang = (
inviter_user_model.language_code or default_lang_for_placeholder
)
_i = lambda k, **kw: self.i18n.gettext(inviter_lang, k, **kw)
await self.bot.send_message(
inviter_user_id,
_i("referral_bonus_inviter_notification_extended",
days=inviter_bonus_days,
referee_name=referee_name_for_msg,
new_end_date=new_end_date_inviter.
strftime('%Y-%m-%d')))
_i(
"referral_bonus_inviter_notification_extended",
days=inviter_bonus_days,
referee_name=referee_name_for_msg,
new_end_date=new_end_date_inviter.strftime("%Y-%m-%d"),
),
)
except Exception as e_notify_inviter:
logging.error(
f"Failed to send bonus notification to inviter {inviter_user_id}: {e_notify_inviter}"
)
else:
logging.info(
f"Inviter {inviter_user_id} has no active sub to extend. Creating new bonus subscription for {inviter_bonus_days} days."
)
bonus_start_date = datetime.now(timezone.utc)
bonus_end_date = bonus_start_date + timedelta(
days=inviter_bonus_days)
bonus_end_date = bonus_start_date + timedelta(days=inviter_bonus_days)
if not inviter_panel_sub_link_id:
logging.error(
@@ -159,60 +169,56 @@ class ReferralService:
)
else:
bonus_sub_payload = {
"user_id":
inviter_user_id,
"panel_user_uuid":
inviter_panel_uuid,
"panel_subscription_uuid":
inviter_panel_sub_link_id,
"start_date":
bonus_start_date,
"end_date":
bonus_end_date,
"duration_months":
0,
"is_active":
True,
"status_from_panel":
"ACTIVE_BONUS",
"traffic_limit_bytes":
self.settings.user_traffic_limit_bytes,
"auto_renew_enabled":
False,
"user_id": inviter_user_id,
"panel_user_uuid": inviter_panel_uuid,
"panel_subscription_uuid": inviter_panel_sub_link_id,
"start_date": bonus_start_date,
"end_date": bonus_end_date,
"duration_months": 0,
"is_active": True,
"status_from_panel": "ACTIVE_BONUS",
"traffic_limit_bytes": self.settings.user_traffic_limit_bytes,
"auto_renew_enabled": False,
}
try:
await subscription_dal.deactivate_other_active_subscriptions(
session, inviter_panel_uuid,
inviter_panel_sub_link_id)
session, inviter_panel_uuid, inviter_panel_sub_link_id
)
bonus_sub = await subscription_dal.upsert_subscription(
session, bonus_sub_payload)
session, bonus_sub_payload
)
panel_update_success = await self.subscription_service.panel_service.update_user_details_on_panel(
inviter_panel_uuid, {
"expireAt":
bonus_end_date.isoformat(
timespec='milliseconds').
replace('+00:00', 'Z'),
"status":
"ACTIVE",
})
inviter_panel_uuid,
{
"expireAt": bonus_end_date.isoformat(
timespec="milliseconds"
).replace("+00:00", "Z"),
"status": "ACTIVE",
},
)
if panel_update_success:
inviter_bonus_successfully_applied = True
logging.info(
f"New bonus subscription for {inviter_bonus_days} days created for inviter {inviter_user_id}."
)
inviter_lang = inviter_user_model.language_code or default_lang_for_placeholder
inviter_lang = (
inviter_user_model.language_code
or default_lang_for_placeholder
)
_i = lambda k, **kw: self.i18n.gettext(
inviter_lang, k, **kw)
inviter_lang, k, **kw
)
await self.bot.send_message(
inviter_user_id,
_i("referral_bonus_inviter_notification_new_sub",
days=inviter_bonus_days,
referee_name=
referee_name_for_msg,
new_end_date=bonus_end_date.
strftime('%Y-%m-%d')))
_i(
"referral_bonus_inviter_notification_new_sub",
days=inviter_bonus_days,
referee_name=referee_name_for_msg,
new_end_date=bonus_end_date.strftime("%Y-%m-%d"),
),
)
else:
logging.warning(
f"Failed to update panel for new bonus subscription for inviter {inviter_user_id}. Local bonus sub created (ID: {bonus_sub.subscription_id}) but may not be active on panel."
@@ -221,16 +227,17 @@ class ReferralService:
except Exception as e_create_bonus_sub:
logging.error(
f"Failed to create new bonus subscription for inviter {inviter_user_id}: {e_create_bonus_sub}",
exc_info=True)
exc_info=True,
)
if referee_bonus_days and referee_bonus_days > 0:
new_end_date_referee = await self.subscription_service.extend_active_subscription_days(
session=session,
user_id=referee_user_id,
bonus_days=referee_bonus_days,
reason=
f"referee bonus (invited by {inviter_name_for_referee_msg})"
new_end_date_referee = (
await self.subscription_service.extend_active_subscription_days(
session=session,
user_id=referee_user_id,
bonus_days=referee_bonus_days,
reason=f"referee bonus (invited by {inviter_name_for_referee_msg})",
)
)
if new_end_date_referee:
referee_final_end_date = new_end_date_referee
@@ -239,7 +246,6 @@ class ReferralService:
f"Bonus of {referee_bonus_days} days successfully applied to referee {referee_user_id}."
)
else:
logging.warning(
f"Failed to apply referee bonus for {referee_user_id} (could not extend their new subscription)."
)
@@ -247,19 +253,19 @@ class ReferralService:
return {
"referee_bonus_applied_days": referee_bonus_applied_days,
"referee_new_end_date": referee_final_end_date,
"inviter_bonus_applied_flag":
inviter_bonus_successfully_applied
"inviter_bonus_applied_flag": inviter_bonus_successfully_applied,
}
except Exception as e:
logging.error(
f"Error in apply_referral_bonuses_for_payment for referee {referee_user_id}: {e}",
exc_info=True)
exc_info=True,
)
raise
async def generate_referral_link(self, session: AsyncSession,
bot_username: str,
inviter_user_id: int) -> Optional[str]:
async def generate_referral_link(
self, session: AsyncSession, bot_username: str, inviter_user_id: int
) -> Optional[str]:
try:
user = await user_dal.get_user_by_id(session, inviter_user_id)
if not user:
@@ -289,16 +295,15 @@ class ReferralService:
async def get_referral_stats(self, session: AsyncSession, user_id: int) -> dict:
"""Get referral statistics for a user"""
from db.dal import user_dal, payment_dal
try:
# Count total invited users (referrals)
invited_count_result = await session.execute(
text("SELECT COUNT(*) FROM users WHERE referred_by_id = :user_id"),
{"user_id": user_id}
{"user_id": user_id},
)
invited_count = invited_count_result.scalar() or 0
# Count users who made successful payments (purchased subscription)
purchased_count_result = await session.execute(
text("""
@@ -308,17 +313,11 @@ class ReferralService:
WHERE u.referred_by_id = :user_id
AND p.status = 'succeeded'
"""),
{"user_id": user_id}
{"user_id": user_id},
)
purchased_count = purchased_count_result.scalar() or 0
return {
"invited_count": invited_count,
"purchased_count": purchased_count
}
return {"invited_count": invited_count, "purchased_count": purchased_count}
except Exception as e:
logging.error(f"Error getting referral stats for user {user_id}: {e}")
return {
"invited_count": 0,
"purchased_count": 0
}
return {"invited_count": 0, "purchased_count": 0}