Refactor promo code handling in admin panel and clean up unused methods
- Replaced the promo_codes module with a new promo management structure, enhancing organization and clarity in the admin panel. - Updated admin panel handlers to utilize the new promo management methods, improving the flow of promo code creation and management. - Removed deprecated methods from payment and subscription data access layers, streamlining the codebase and improving maintainability. - Ensured localization files are updated to reflect changes in promo management messaging, enhancing user experience.
This commit is contained in:
@@ -38,14 +38,6 @@ async def create_payment_record(session: AsyncSession,
|
||||
return new_payment
|
||||
|
||||
|
||||
async def get_payment_by_yookassa_id(
|
||||
session: AsyncSession, yookassa_payment_id: str) -> Optional[Payment]:
|
||||
stmt = select(Payment).where(
|
||||
Payment.yookassa_payment_id == yookassa_payment_id)
|
||||
result = await session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def get_payment_by_provider_payment_id(
|
||||
session: AsyncSession, provider_payment_id: str) -> Optional[Payment]:
|
||||
"""Fetch a payment by provider-specific identifier."""
|
||||
@@ -64,15 +56,6 @@ async def get_payment_by_db_id(session: AsyncSession,
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def get_payment_by_db_id_with_promo(
|
||||
session: AsyncSession, payment_db_id: int) -> Optional[Payment]:
|
||||
|
||||
stmt = select(Payment).where(Payment.payment_id == payment_db_id).options(
|
||||
selectinload(Payment.promo_code_used))
|
||||
result = await session.execute(stmt)
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def update_payment_status_by_db_id(
|
||||
session: AsyncSession,
|
||||
payment_db_id: int,
|
||||
@@ -96,38 +79,6 @@ async def update_payment_status_by_db_id(
|
||||
return payment
|
||||
|
||||
|
||||
async def user_has_successful_payment_for_provider(
|
||||
session: AsyncSession, user_id: int, provider: str) -> bool:
|
||||
"""Check if a user has at least one successful payment for the provider."""
|
||||
|
||||
stmt = (select(Payment.payment_id)
|
||||
.where(Payment.user_id == user_id,
|
||||
Payment.provider == provider,
|
||||
Payment.status == 'succeeded')
|
||||
.limit(1))
|
||||
result = await session.execute(stmt)
|
||||
return result.scalar_one_or_none() is not None
|
||||
|
||||
|
||||
async def update_payment_status_by_yk_id(session: AsyncSession,
|
||||
yookassa_payment_id: str,
|
||||
new_status: str) -> Optional[Payment]:
|
||||
payment = await get_payment_by_yookassa_id(session, yookassa_payment_id)
|
||||
if payment:
|
||||
payment.status = new_status
|
||||
payment.updated_at = func.now()
|
||||
await session.flush()
|
||||
await session.refresh(payment)
|
||||
logging.info(
|
||||
f"Payment record with YK ID {yookassa_payment_id} status updated to {new_status}."
|
||||
)
|
||||
else:
|
||||
logging.warning(
|
||||
f"Payment record with YK ID {yookassa_payment_id} not found for status update."
|
||||
)
|
||||
return payment
|
||||
|
||||
|
||||
async def get_recent_payment_logs_with_user(session: AsyncSession,
|
||||
limit: int = 20,
|
||||
offset: int = 0) -> List[Payment]:
|
||||
|
||||
@@ -31,29 +31,6 @@ async def get_subscription_by_panel_subscription_uuid(
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def create_subscription(session: AsyncSession,
|
||||
sub_data: Dict[str, Any]) -> Subscription:
|
||||
from .user_dal import get_user_by_id
|
||||
|
||||
if "user_id" not in sub_data or sub_data["user_id"] is None:
|
||||
raise ValueError(
|
||||
"user_id is required to create a subscription directly.")
|
||||
user = await get_user_by_id(session, sub_data["user_id"])
|
||||
if not user:
|
||||
raise ValueError(
|
||||
f"User with id {sub_data['user_id']} not found for creating subscription."
|
||||
)
|
||||
|
||||
new_sub = Subscription(**sub_data)
|
||||
session.add(new_sub)
|
||||
await session.flush()
|
||||
await session.refresh(new_sub)
|
||||
logging.info(
|
||||
f"Subscription {new_sub.subscription_id} created for user {new_sub.user_id}"
|
||||
)
|
||||
return new_sub
|
||||
|
||||
|
||||
async def update_subscription(
|
||||
session: AsyncSession, subscription_id: int,
|
||||
update_data: Dict[str, Any]) -> Optional[Subscription]:
|
||||
@@ -205,17 +182,6 @@ async def update_subscription_notification_time(
|
||||
{"last_notification_sent": notification_time})
|
||||
|
||||
|
||||
async def get_user_active_subscription_end_date_str(
|
||||
session: AsyncSession, user_id: int) -> Optional[str]:
|
||||
stmt = (select(Subscription.end_date).where(
|
||||
Subscription.user_id == user_id, Subscription.is_active == True,
|
||||
Subscription.end_date > datetime.now(timezone.utc)).order_by(
|
||||
Subscription.end_date.desc()).limit(1))
|
||||
result = await session.execute(stmt)
|
||||
end_date_obj = result.scalar_one_or_none()
|
||||
return end_date_obj.strftime('%Y-%m-%d') if end_date_obj else None
|
||||
|
||||
|
||||
async def find_subscription_for_notification_update(
|
||||
session: AsyncSession, user_id: int,
|
||||
subscription_end_date_to_match: datetime) -> Optional[Subscription]:
|
||||
@@ -234,34 +200,4 @@ async def find_subscription_for_notification_update(
|
||||
return result.scalar_one_or_none()
|
||||
|
||||
|
||||
async def set_skip_notifications_for_provider(
|
||||
session: AsyncSession, user_id: int, provider: str,
|
||||
skip: bool) -> int:
|
||||
stmt = (update(Subscription).where(
|
||||
Subscription.user_id == user_id,
|
||||
Subscription.is_active == True,
|
||||
Subscription.provider == provider).values(skip_notifications=skip))
|
||||
result = await session.execute(stmt)
|
||||
return result.rowcount
|
||||
|
||||
|
||||
async def get_active_subscriptions_for_autorenew(
|
||||
session: AsyncSession, provider: str,
|
||||
days_threshold: int = 1,
|
||||
require_skip_flag: bool = True) -> List[Subscription]:
|
||||
"""Fetch active subscriptions nearing expiration for auto-renew logic."""
|
||||
|
||||
now_utc = datetime.now(timezone.utc)
|
||||
threshold_date = now_utc + timedelta(days=days_threshold)
|
||||
|
||||
conditions = [
|
||||
Subscription.provider == provider,
|
||||
Subscription.is_active == True,
|
||||
Subscription.end_date <= threshold_date,
|
||||
]
|
||||
if require_skip_flag:
|
||||
conditions.append(Subscription.skip_notifications == True)
|
||||
|
||||
stmt = select(Subscription).where(*conditions)
|
||||
result = await session.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
@@ -81,18 +81,6 @@ async def update_user_language(
|
||||
return result.rowcount > 0
|
||||
|
||||
|
||||
async def set_user_ban_status(
|
||||
session: AsyncSession, user_id: int, is_banned: bool
|
||||
) -> bool:
|
||||
user = await get_user_by_id(session, user_id)
|
||||
if user:
|
||||
user.is_banned = is_banned
|
||||
await session.flush()
|
||||
await session.refresh(user)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
async def get_banned_users(session: AsyncSession) -> List[User]:
|
||||
"""Get all banned users"""
|
||||
stmt = (
|
||||
@@ -104,58 +92,12 @@ async def get_banned_users(session: AsyncSession) -> List[User]:
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
async def get_banned_users_paginated(
|
||||
session: AsyncSession, limit: int, offset: int
|
||||
) -> Tuple[List[User], int]:
|
||||
stmt_users = (
|
||||
select(User)
|
||||
.where(User.is_banned == True)
|
||||
.order_by(User.registration_date.desc())
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
)
|
||||
result_users = await session.execute(stmt_users)
|
||||
users_list = result_users.scalars().all()
|
||||
|
||||
stmt_count = select(func.count()).select_from(User).where(User.is_banned == True)
|
||||
result_count = await session.execute(stmt_count)
|
||||
total_banned = result_count.scalar_one()
|
||||
|
||||
return users_list, total_banned
|
||||
|
||||
|
||||
async def get_all_active_user_ids_for_broadcast(session: AsyncSession) -> List[int]:
|
||||
stmt = select(User.user_id).where(User.is_banned == False)
|
||||
result = await session.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
async def get_user_count_stats_dal(session: AsyncSession) -> Dict[str, int]:
|
||||
total_users_stmt = select(func.count(User.user_id)).select_from(User)
|
||||
banned_users_stmt = (
|
||||
select(func.count(User.user_id)).select_from(User).where(User.is_banned == True)
|
||||
)
|
||||
|
||||
active_subs_stmt = (
|
||||
select(func.count(func.distinct(Subscription.user_id)))
|
||||
.join(User, Subscription.user_id == User.user_id)
|
||||
.where(Subscription.is_active == True)
|
||||
.where(Subscription.end_date > datetime.now())
|
||||
)
|
||||
|
||||
total_users = (await session.execute(total_users_stmt)).scalar_one_or_none() or 0
|
||||
banned_users = (await session.execute(banned_users_stmt)).scalar_one_or_none() or 0
|
||||
active_subs_users = (
|
||||
await session.execute(active_subs_stmt)
|
||||
).scalar_one_or_none() or 0
|
||||
|
||||
return {
|
||||
"total_users": total_users,
|
||||
"banned_users": banned_users,
|
||||
"users_with_active_subscriptions": active_subs_users,
|
||||
}
|
||||
|
||||
|
||||
async def get_all_users_with_panel_uuid(session: AsyncSession) -> List[User]:
|
||||
stmt = select(User).where(User.panel_user_uuid.is_not(None))
|
||||
result = await session.execute(stmt)
|
||||
|
||||
Reference in New Issue
Block a user