diff --git a/app/handlers/admin/referrals.py b/app/handlers/admin/referrals.py
index acad0aac..60ed5bd6 100644
--- a/app/handlers/admin/referrals.py
+++ b/app/handlers/admin/referrals.py
@@ -19,54 +19,167 @@ async def show_referral_statistics(
db_user: User,
db: AsyncSession
):
- stats = await get_referral_statistics(db)
-
- avg_per_referrer = 0
- if stats['active_referrers'] > 0:
- avg_per_referrer = stats['total_paid_kopeks'] / stats['active_referrers']
-
- text = f"""
+ try:
+ stats = await get_referral_statistics(db)
+
+ avg_per_referrer = 0
+ if stats.get('active_referrers', 0) > 0:
+ avg_per_referrer = stats.get('total_paid_kopeks', 0) / stats['active_referrers']
+
+ text = f"""
🤝 Реферальная статистика
Общие показатели:
-- Пользователей с рефералами: {stats['users_with_referrals']}
-- Активных рефереров: {stats['active_referrers']}
-- Выплачено всего: {settings.format_price(stats['total_paid_kopeks'])}
+- Пользователей с рефералами: {stats.get('users_with_referrals', 0)}
+- Активных рефереров: {stats.get('active_referrers', 0)}
+- Выплачено всего: {settings.format_price(stats.get('total_paid_kopeks', 0))}
За период:
-- Сегодня: {settings.format_price(stats['today_earnings_kopeks'])}
-- За неделю: {settings.format_price(stats['week_earnings_kopeks'])}
-- За месяц: {settings.format_price(stats['month_earnings_kopeks'])}
+- Сегодня: {settings.format_price(stats.get('today_earnings_kopeks', 0))}
+- За неделю: {settings.format_price(stats.get('week_earnings_kopeks', 0))}
+- За месяц: {settings.format_price(stats.get('month_earnings_kopeks', 0))}
Средние показатели:
- На одного реферера: {settings.format_price(int(avg_per_referrer))}
Топ-5 рефереров:
"""
-
- for i, referrer in enumerate(stats['top_referrers'][:5], 1):
- text += f"{i}. ID {referrer['user_id']}: {settings.format_price(referrer['total_earned_kopeks'])} ({referrer['referrals_count']} реф.)\n"
-
- if not stats['top_referrers']:
- text += "Нет данных\n"
-
- text += f"""
+
+ top_referrers = stats.get('top_referrers', [])
+ if top_referrers:
+ for i, referrer in enumerate(top_referrers[:5], 1):
+ earned = referrer.get('total_earned_kopeks', 0)
+ count = referrer.get('referrals_count', 0)
+ user_id = referrer.get('user_id', 'N/A')
+ text += f"{i}. ID {user_id}: {settings.format_price(earned)} ({count} реф.)\n"
+ else:
+ text += "Нет данных\n"
+
+ text += f"""
-Настройки:
-- Бонус за регистрацию: {settings.format_price(settings.REFERRAL_REGISTRATION_REWARD)}
+Настройки реферальной системы:
+- Минимальное пополнение: {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)}
+- Бонус за первое пополнение: {settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}
+- Бонус пригласившему: {settings.format_price(settings.REFERRAL_INVITER_BONUS_KOPEKS)}
- Бонус новому пользователю: {settings.format_price(settings.REFERRED_USER_REWARD)}
-- Комиссия: {settings.REFERRAL_COMMISSION_PERCENT}%
+- Комиссия с покупок: {settings.REFERRAL_COMMISSION_PERCENT}%
+- Уведомления: {'✅ Включены' if settings.REFERRAL_NOTIFICATIONS_ENABLED else '❌ Отключены'}
"""
-
- await callback.message.edit_text(
- text,
- reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
+
+ keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text="🔄 Обновить", callback_data="admin_referrals")],
+ [types.InlineKeyboardButton(text="👥 Топ рефереров", callback_data="admin_referrals_top")],
+ [types.InlineKeyboardButton(text="⚙️ Настройки", callback_data="admin_referrals_settings")],
[types.InlineKeyboardButton(text="⬅️ Назад", callback_data="admin_panel")]
])
- )
+
+ await callback.message.edit_text(text, reply_markup=keyboard)
+ await callback.answer()
+
+ except Exception as e:
+ logger.error(f"Ошибка в show_referral_statistics: {e}", exc_info=True)
+
+ text = f"""
+🤝 Реферальная статистика
+
+❌ Ошибка загрузки данных
+
+Текущие настройки:
+- Минимальное пополнение: {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)}
+- Бонус за первое пополнение: {settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}
+- Бонус пригласившему: {settings.format_price(settings.REFERRAL_INVITER_BONUS_KOPEKS)}
+- Бонус новому пользователю: {settings.format_price(settings.REFERRED_USER_REWARD)}
+- Комиссия с покупок: {settings.REFERRAL_COMMISSION_PERCENT}%
+"""
+
+ keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
+ [types.InlineKeyboardButton(text="🔄 Повторить", callback_data="admin_referrals")],
+ [types.InlineKeyboardButton(text="⬅️ Назад", callback_data="admin_panel")]
+ ])
+
+ await callback.message.edit_text(text, reply_markup=keyboard)
+ await callback.answer("Произошла ошибка при загрузке статистики")
+
+
+@admin_required
+@error_handler
+async def show_top_referrers(
+ callback: types.CallbackQuery,
+ db_user: User,
+ db: AsyncSession
+):
+ try:
+ stats = await get_referral_statistics(db)
+ top_referrers = stats.get('top_referrers', [])
+
+ text = "🏆 Топ рефереров\n\n"
+
+ if top_referrers:
+ for i, referrer in enumerate(top_referrers[:20], 1):
+ earned = referrer.get('total_earned_kopeks', 0)
+ count = referrer.get('referrals_count', 0)
+ user_id = referrer.get('user_id', 'N/A')
+
+ emoji = ""
+ if i == 1:
+ emoji = "🥇 "
+ elif i == 2:
+ emoji = "🥈 "
+ elif i == 3:
+ emoji = "🥉 "
+
+ text += f"{emoji}{i}. ID {user_id}\n"
+ text += f" 💰 {settings.format_price(earned)} | 👥 {count} реф.\n\n"
+ else:
+ text += "Нет данных о рефererах\n"
+
+ keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
+ [types.InlineKeyboardButton(text="⬅️ К статистике", callback_data="admin_referrals")]
+ ])
+
+ await callback.message.edit_text(text, reply_markup=keyboard)
+ await callback.answer()
+
+ except Exception as e:
+ logger.error(f"Ошибка в show_top_referrers: {e}", exc_info=True)
+ await callback.answer("Ошибка загрузки топа рефереров")
+
+
+@admin_required
+@error_handler
+async def show_referral_settings(
+ callback: types.CallbackQuery,
+ db_user: User,
+ db: AsyncSession
+):
+ text = f"""
+⚙️ Настройки реферальной системы
+
+Бонусы и награды:
+• Минимальная сумма пополнения для участия: {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)}
+• Бонус за первое пополнение реферала: {settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}
+• Бонус пригласившему за первое пополнение: {settings.format_price(settings.REFERRAL_INVITER_BONUS_KOPEKS)}
+• Бонус новому пользователю при регистрации: {settings.format_price(settings.REFERRED_USER_REWARD)}
+
+Комиссионные:
+• Процент с каждой покупки реферала: {settings.REFERRAL_COMMISSION_PERCENT}%
+
+Уведомления:
+• Статус: {'✅ Включены' if settings.REFERRAL_NOTIFICATIONS_ENABLED else '❌ Отключены'}
+• Попытки отправки: {getattr(settings, 'REFERRAL_NOTIFICATION_RETRY_ATTEMPTS', 3)}
+
+💡 Для изменения настроек отредактируйте файл .env и перезапустите бота
+"""
+
+ keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
+ [types.InlineKeyboardButton(text="⬅️ К статистике", callback_data="admin_referrals")]
+ ])
+
+ await callback.message.edit_text(text, reply_markup=keyboard)
await callback.answer()
def register_handlers(dp: Dispatcher):
- dp.callback_query.register(show_referral_statistics, F.data == "admin_referrals")
\ No newline at end of file
+ dp.callback_query.register(show_referral_statistics, F.data == "admin_referrals")
+ dp.callback_query.register(show_top_referrers, F.data == "admin_referrals_top")
+ dp.callback_query.register(show_referral_settings, F.data == "admin_referrals_settings")