diff --git a/app/handlers/admin/users.py b/app/handlers/admin/users.py
index d0e858e4..9b7a9c2a 100644
--- a/app/handlers/admin/users.py
+++ b/app/handlers/admin/users.py
@@ -685,7 +685,8 @@ async def process_balance_edit(
description = f"Списание администратором: {int(amount_rubles)} ₽"
success = await user_service.update_user_balance(
- db, user_id, amount_kopeks, description, db_user.id
+ db, user_id, amount_kopeks, description, db_user.id,
+ bot=message.bot, admin_name=db_user.full_name
)
if success:
diff --git a/app/services/user_service.py b/app/services/user_service.py
index 0c65fde0..f26e14b2 100644
--- a/app/services/user_service.py
+++ b/app/services/user_service.py
@@ -3,6 +3,8 @@ from datetime import datetime, timedelta
from typing import Optional, List, Dict, Any
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import delete, select, update
+from aiogram import Bot
+from aiogram.exceptions import TelegramBadRequest, TelegramForbiddenError
from app.database.crud.user import (
get_user_by_id, get_user_by_telegram_id, get_users_list,
get_users_count, get_users_statistics, get_inactive_users,
@@ -23,6 +25,59 @@ logger = logging.getLogger(__name__)
class UserService:
+ async def _send_balance_notification(
+ self,
+ bot: Bot,
+ user: User,
+ amount_kopeks: int,
+ admin_name: str
+ ) -> bool:
+ """Отправляет уведомление пользователю о пополнении/списании баланса"""
+ try:
+ if amount_kopeks > 0:
+ # Пополнение
+ emoji = "💰"
+ action = "пополнен"
+ amount_text = f"+{settings.format_price(amount_kopeks)}"
+ message = (
+ f"{emoji} Баланс пополнен!\n\n"
+ f"💵 Сумма: {amount_text}\n"
+ f"👤 Администратор: {admin_name}\n"
+ f"💳 Текущий баланс: {settings.format_price(user.balance_kopeks)}\n\n"
+ f"Спасибо за использование нашего сервиса! 🎉"
+ )
+ else:
+ # Списание
+ emoji = "💸"
+ action = "списан"
+ amount_text = f"-{settings.format_price(abs(amount_kopeks))}"
+ message = (
+ f"{emoji} Средства списаны с баланса\n\n"
+ f"💵 Сумма: {amount_text}\n"
+ f"👤 Администратор: {admin_name}\n"
+ f"💳 Текущий баланс: {settings.format_price(user.balance_kopeks)}\n\n"
+ f"Если у вас есть вопросы, обратитесь в поддержку."
+ )
+
+ await bot.send_message(
+ chat_id=user.telegram_id,
+ text=message,
+ parse_mode="HTML"
+ )
+
+ logger.info(f"✅ Уведомление о изменении баланса отправлено пользователю {user.telegram_id}")
+ return True
+
+ except TelegramForbiddenError:
+ logger.warning(f"⚠️ Пользователь {user.telegram_id} заблокировал бота")
+ return False
+ except TelegramBadRequest as e:
+ logger.error(f"❌ Ошибка Telegram API при отправке уведомления пользователю {user.telegram_id}: {e}")
+ return False
+ except Exception as e:
+ logger.error(f"❌ Неожиданная ошибка при отправке уведомления пользователю {user.telegram_id}: {e}")
+ return False
+
async def get_user_profile(
self,
db: AsyncSession,
@@ -128,22 +183,41 @@ class UserService:
user_id: int,
amount_kopeks: int,
description: str,
- admin_id: int
+ admin_id: int,
+ bot: Optional[Bot] = None,
+ admin_name: Optional[str] = None
) -> bool:
try:
user = await get_user_by_id(db, user_id)
if not user:
return False
+ # Сохраняем старый баланс для уведомления
+ old_balance = user.balance_kopeks
+
if amount_kopeks > 0:
await add_user_balance(db, user, amount_kopeks, description=description)
logger.info(f"Админ {admin_id} пополнил баланс пользователя {user_id} на {amount_kopeks/100}₽")
- return True
+ success = True
else:
success = await subtract_user_balance(db, user, abs(amount_kopeks), description)
if success:
logger.info(f"Админ {admin_id} списал с баланса пользователя {user_id} {abs(amount_kopeks)/100}₽")
- return success
+
+ # Отправляем уведомление пользователю, если операция прошла успешно
+ if success and bot:
+ # Обновляем пользователя для получения нового баланса
+ await db.refresh(user)
+
+ # Получаем имя администратора
+ if not admin_name:
+ admin_user = await get_user_by_id(db, admin_id)
+ admin_name = admin_user.full_name if admin_user else f"Админ #{admin_id}"
+
+ # Отправляем уведомление (не блокируем операцию если не удалось отправить)
+ await self._send_balance_notification(bot, user, amount_kopeks, admin_name)
+
+ return success
except Exception as e:
logger.error(f"Ошибка изменения баланса пользователя: {e}")