Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67df164498 | ||
|
|
48e666f605 | ||
|
|
3cb15fa254 | ||
|
|
2100949470 |
@@ -15,6 +15,7 @@ from bot.states.admin_states import AdminStates
|
|||||||
from bot.keyboards.inline.admin_keyboards import get_back_to_admin_panel_keyboard
|
from bot.keyboards.inline.admin_keyboards import get_back_to_admin_panel_keyboard
|
||||||
from bot.services.subscription_service import SubscriptionService
|
from bot.services.subscription_service import SubscriptionService
|
||||||
from bot.services.panel_api_service import PanelApiService
|
from bot.services.panel_api_service import PanelApiService
|
||||||
|
from bot.services.referral_service import ReferralService
|
||||||
from bot.middlewares.i18n import JsonI18n
|
from bot.middlewares.i18n import JsonI18n
|
||||||
from bot.utils import get_message_content, send_direct_message
|
from bot.utils import get_message_content, send_direct_message
|
||||||
from aiogram.utils.keyboard import InlineKeyboardBuilder, InlineKeyboardButton
|
from aiogram.utils.keyboard import InlineKeyboardBuilder, InlineKeyboardButton
|
||||||
@@ -106,7 +107,8 @@ def get_user_card_keyboard(user_id: int, i18n_instance, lang: str) -> InlineKeyb
|
|||||||
|
|
||||||
async def format_user_card(user: User, session: AsyncSession,
|
async def format_user_card(user: User, session: AsyncSession,
|
||||||
subscription_service: SubscriptionService,
|
subscription_service: SubscriptionService,
|
||||||
i18n_instance, lang: str) -> str:
|
i18n_instance, lang: str,
|
||||||
|
referral_service: Optional[ReferralService] = None) -> str:
|
||||||
"""Format user information as a detailed card"""
|
"""Format user information as a detailed card"""
|
||||||
_ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs)
|
_ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs)
|
||||||
|
|
||||||
@@ -176,6 +178,17 @@ async def format_user_card(user: User, session: AsyncSession,
|
|||||||
had_subscriptions = await subscription_service.has_had_any_subscription(session, user.user_id)
|
had_subscriptions = await subscription_service.has_had_any_subscription(session, user.user_id)
|
||||||
trial_status = _("admin_user_trial_used", default="Использовал") if had_subscriptions else _("admin_user_trial_not_used", default="Не использовал")
|
trial_status = _("admin_user_trial_used", default="Использовал") if had_subscriptions else _("admin_user_trial_not_used", default="Не использовал")
|
||||||
card_parts.append(f"{_('admin_user_trial_label', default='🏡 <b>Триал:</b>')} {hcode(trial_status)}")
|
card_parts.append(f"{_('admin_user_trial_label', default='🏡 <b>Триал:</b>')} {hcode(trial_status)}")
|
||||||
|
|
||||||
|
# Referral stats
|
||||||
|
if referral_service is not None:
|
||||||
|
try:
|
||||||
|
stats = await referral_service.get_referral_stats(session, user.user_id)
|
||||||
|
invited_count = stats.get('invited_count', 0)
|
||||||
|
purchased_count = stats.get('purchased_count', 0)
|
||||||
|
card_parts.append(f"{_('admin_user_invited_friends_label', default='👥 <b>Приглашено друзей:</b>')} {hcode(str(invited_count))}")
|
||||||
|
card_parts.append(f"{_('admin_user_ref_purchased_label', default='💳 <b>Купили подписку:</b>')} {hcode(str(purchased_count))}")
|
||||||
|
except Exception as e_rs:
|
||||||
|
logging.error(f"Failed to build referral stats for admin card {user.user_id}: {e_rs}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Error getting user statistics for {user.user_id}: {e}")
|
logging.error(f"Error getting user statistics for {user.user_id}: {e}")
|
||||||
@@ -224,7 +237,8 @@ async def process_user_search_handler(message: types.Message, state: FSMContext,
|
|||||||
|
|
||||||
# Format and send user card
|
# Format and send user card
|
||||||
try:
|
try:
|
||||||
user_card_text = await format_user_card(user_model, session, subscription_service, i18n, current_lang)
|
referral_service = ReferralService(settings, subscription_service, message.bot, i18n)
|
||||||
|
user_card_text = await format_user_card(user_model, session, subscription_service, i18n, current_lang, referral_service)
|
||||||
keyboard = get_user_card_keyboard(user_model.user_id, i18n, current_lang)
|
keyboard = get_user_card_keyboard(user_model.user_id, i18n, current_lang)
|
||||||
|
|
||||||
await message.answer(
|
await message.answer(
|
||||||
@@ -482,7 +496,10 @@ async def handle_refresh_user_card(callback: types.CallbackQuery, user: User,
|
|||||||
await callback.answer("User not found", show_alert=True)
|
await callback.answer("User not found", show_alert=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
user_card_text = await format_user_card(fresh_user, session, subscription_service, i18n_instance, lang)
|
from config.settings import Settings as _Settings
|
||||||
|
_settings = _Settings()
|
||||||
|
referral_service = ReferralService(_settings, subscription_service, callback.message.bot, i18n_instance)
|
||||||
|
user_card_text = await format_user_card(fresh_user, session, subscription_service, i18n_instance, lang, referral_service)
|
||||||
keyboard = get_user_card_keyboard(fresh_user.user_id, i18n_instance, lang)
|
keyboard = get_user_card_keyboard(fresh_user.user_id, i18n_instance, lang)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -556,7 +573,8 @@ async def process_subscription_days_handler(message: types.Message, state: FSMCo
|
|||||||
# Show updated user card
|
# Show updated user card
|
||||||
user = await user_dal.get_user_by_id(session, target_user_id)
|
user = await user_dal.get_user_by_id(session, target_user_id)
|
||||||
if user:
|
if user:
|
||||||
user_card_text = await format_user_card(user, session, subscription_service, i18n, current_lang)
|
referral_service = ReferralService(settings, subscription_service, message.bot, i18n)
|
||||||
|
user_card_text = await format_user_card(user, session, subscription_service, i18n, current_lang, referral_service)
|
||||||
keyboard = get_user_card_keyboard(user.user_id, i18n, current_lang)
|
keyboard = get_user_card_keyboard(user.user_id, i18n, current_lang)
|
||||||
|
|
||||||
await message.answer(
|
await message.answer(
|
||||||
@@ -664,7 +682,8 @@ async def process_direct_message_handler(message: types.Message, state: FSMConte
|
|||||||
from bot.services.panel_api_service import PanelApiService
|
from bot.services.panel_api_service import PanelApiService
|
||||||
async with PanelApiService(settings) as panel_service:
|
async with PanelApiService(settings) as panel_service:
|
||||||
subscription_service = SubscriptionService(settings, panel_service)
|
subscription_service = SubscriptionService(settings, panel_service)
|
||||||
user_card_text = await format_user_card(target_user, session, subscription_service, i18n, current_lang)
|
referral_service = ReferralService(settings, subscription_service, bot, i18n)
|
||||||
|
user_card_text = await format_user_card(target_user, session, subscription_service, i18n, current_lang, referral_service)
|
||||||
keyboard = get_user_card_keyboard(target_user.user_id, i18n, current_lang)
|
keyboard = get_user_card_keyboard(target_user.user_id, i18n, current_lang)
|
||||||
|
|
||||||
await message.answer(
|
await message.answer(
|
||||||
|
|||||||
@@ -250,8 +250,39 @@ class TributeService:
|
|||||||
from bot.keyboards.inline.user_keyboards import get_subscribe_only_markup
|
from bot.keyboards.inline.user_keyboards import get_subscribe_only_markup
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Set all user's subscriptions to expire in 1 day (grace period)
|
grace_days = 1
|
||||||
await subscription_dal.set_user_subscriptions_cancelled_with_grace(session, user_id, grace_days=1)
|
grace_end = datetime.now(timezone.utc) + timedelta(days=grace_days)
|
||||||
|
|
||||||
|
active_subscriptions = await subscription_dal.get_active_subscriptions_for_user(session, user_id)
|
||||||
|
|
||||||
|
panel_users_updated: set[str] = set()
|
||||||
|
for sub in active_subscriptions:
|
||||||
|
updated_sub = await subscription_dal.update_subscription(
|
||||||
|
session,
|
||||||
|
sub.subscription_id,
|
||||||
|
{
|
||||||
|
"end_date": grace_end,
|
||||||
|
"status_from_panel": "CANCELLED",
|
||||||
|
"skip_notifications": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
panel_uuid = updated_sub.panel_user_uuid if updated_sub else None
|
||||||
|
if panel_uuid and panel_uuid not in panel_users_updated:
|
||||||
|
panel_users_updated.add(panel_uuid)
|
||||||
|
panel_payload = {
|
||||||
|
"expireAt": grace_end.isoformat(timespec="milliseconds").replace("+00:00", "Z"),
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
await self.panel_service.update_user_details_on_panel(
|
||||||
|
panel_uuid,
|
||||||
|
panel_payload,
|
||||||
|
log_response=False,
|
||||||
|
)
|
||||||
|
except Exception as panel_err:
|
||||||
|
logging.error(
|
||||||
|
f"Failed to update panel expiry for user {user_id} (panel_uuid {panel_uuid}) during Tribute cancellation: {panel_err}")
|
||||||
|
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
# Send notification about cancellation if enabled
|
# Send notification about cancellation if enabled
|
||||||
|
|||||||
@@ -228,6 +228,7 @@
|
|||||||
"admin_user_search_new_button": "🔍 Find Another",
|
"admin_user_search_new_button": "🔍 Find Another",
|
||||||
"admin_user_view_all_logs_button": "📋 All Actions",
|
"admin_user_view_all_logs_button": "📋 All Actions",
|
||||||
"admin_user_back_to_card_button": "🔙 Back to Card",
|
"admin_user_back_to_card_button": "🔙 Back to Card",
|
||||||
|
"admin_user_recent_actions_title": "📜 Recent actions of user {user_id}:",
|
||||||
"admin_user_not_found": "❌ User not found: {input}",
|
"admin_user_not_found": "❌ User not found: {input}",
|
||||||
"admin_user_not_found_action": "User not found",
|
"admin_user_not_found_action": "User not found",
|
||||||
"admin_user_card_error": "❌ Error displaying user card",
|
"admin_user_card_error": "❌ Error displaying user card",
|
||||||
@@ -316,6 +317,8 @@
|
|||||||
"admin_user_na_value": "N/A",
|
"admin_user_na_value": "N/A",
|
||||||
"admin_user_subscription_none": "No active subscription",
|
"admin_user_subscription_none": "No active subscription",
|
||||||
"admin_user_actions_count_label": "📜 <b>Total actions:</b>",
|
"admin_user_actions_count_label": "📜 <b>Total actions:</b>",
|
||||||
|
"admin_user_invited_friends_label": "👥 <b>Friends invited:</b>",
|
||||||
|
"admin_user_ref_purchased_label": "💳 <b>Purchased subscription:</b>",
|
||||||
"admin_user_subscription_active_until": "⏰ <b>Active until:</b>",
|
"admin_user_subscription_active_until": "⏰ <b>Active until:</b>",
|
||||||
"admin_user_subscription_error": "Loading error",
|
"admin_user_subscription_error": "Loading error",
|
||||||
"admin_promo_management_button": "🎟 Promo Management",
|
"admin_promo_management_button": "🎟 Promo Management",
|
||||||
|
|||||||
@@ -227,6 +227,7 @@
|
|||||||
"admin_user_search_new_button": "🔍 Новый поиск",
|
"admin_user_search_new_button": "🔍 Новый поиск",
|
||||||
"admin_user_view_all_logs_button": "📋 Все логи",
|
"admin_user_view_all_logs_button": "📋 Все логи",
|
||||||
"admin_user_back_to_card_button": "🔙 К карточке",
|
"admin_user_back_to_card_button": "🔙 К карточке",
|
||||||
|
"admin_user_recent_actions_title": "📜 Последние действия пользователя {user_id}:",
|
||||||
"admin_user_not_found": "❌ Пользователь не найден: {input}",
|
"admin_user_not_found": "❌ Пользователь не найден: {input}",
|
||||||
"admin_user_not_found_action": "Пользователь не найден",
|
"admin_user_not_found_action": "Пользователь не найден",
|
||||||
"admin_user_card_error": "❌ Ошибка отображения карточки пользователя",
|
"admin_user_card_error": "❌ Ошибка отображения карточки пользователя",
|
||||||
@@ -315,6 +316,8 @@
|
|||||||
"admin_user_na_value": "N/A",
|
"admin_user_na_value": "N/A",
|
||||||
"admin_user_subscription_none": "Нет активной подписки",
|
"admin_user_subscription_none": "Нет активной подписки",
|
||||||
"admin_user_actions_count_label": "📜 <b>Всего действий:</b>",
|
"admin_user_actions_count_label": "📜 <b>Всего действий:</b>",
|
||||||
|
"admin_user_invited_friends_label": "👥 <b>Приглашено друзей:</b>",
|
||||||
|
"admin_user_ref_purchased_label": "💳 <b>Купили подписку:</b>",
|
||||||
"admin_user_subscription_active_until": "⏰ <b>Действует до:</b>",
|
"admin_user_subscription_active_until": "⏰ <b>Действует до:</b>",
|
||||||
"admin_user_subscription_error": "Ошибка загрузки",
|
"admin_user_subscription_error": "Ошибка загрузки",
|
||||||
"admin_promo_management_button": "🎟 Управление промокодами",
|
"admin_promo_management_button": "🎟 Управление промокодами",
|
||||||
|
|||||||
Reference in New Issue
Block a user