import logging from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, delete from aiogram import Bot from app.config import settings from app.database.crud.user import add_user_balance, get_user_by_id from app.database.crud.referral import create_referral_earning from app.database.models import TransactionType, ReferralEarning logger = logging.getLogger(__name__) async def send_referral_notification( bot: Bot, user_id: int, message: str ): try: await bot.send_message(user_id, message, parse_mode="HTML") logger.info(f"✅ Уведомление отправлено пользователю {user_id}") except Exception as e: logger.error(f"❌ Ошибка отправки уведомления пользователю {user_id}: {e}") async def process_referral_registration( db: AsyncSession, new_user_id: int, referrer_id: int, bot: Bot = None ): try: new_user = await get_user_by_id(db, new_user_id) referrer = await get_user_by_id(db, referrer_id) if not new_user or not referrer: logger.error(f"Пользователи не найдены: new_user_id={new_user_id}, referrer_id={referrer_id}") return False if new_user.referred_by_id != referrer_id: logger.error(f"Пользователь {new_user_id} не привязан к рефереру {referrer_id}") return False await create_referral_earning( db=db, user_id=referrer_id, referral_id=new_user_id, amount_kopeks=0, reason="referral_registration_pending" ) if bot: referral_notification = ( f"🎉 Добро пожаловать!\n\n" f"Вы перешли по реферальной ссылке пользователя {referrer.full_name}!\n\n" f"💰 При первом пополнении от {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)} " f"вы получите бонус {settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}!\n\n" # f"🎁 Ваш реферер также получит награду за ваше первое пополнение." ) await send_referral_notification(bot, new_user.telegram_id, referral_notification) inviter_notification = ( f"👥 Новый реферал!\n\n" f"По вашей ссылке зарегистрировался пользователь {new_user.full_name}!\n\n" f"💰 Когда он пополнит баланс от {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)}, " f"вы получите минимум {settings.format_price(settings.REFERRAL_INVITER_BONUS_KOPEKS)} или " f"{settings.REFERRAL_COMMISSION_PERCENT}% от суммы (что больше).\n\n" f"📈 С каждого последующего пополнения вы будете получать {settings.REFERRAL_COMMISSION_PERCENT}% комиссии." ) await send_referral_notification(bot, referrer.telegram_id, inviter_notification) logger.info(f"✅ Зарегистрирован реферал {new_user_id} для {referrer_id}. Бонусы будут выданы после пополнения.") return True except Exception as e: logger.error(f"Ошибка обработки реферальной регистрации: {e}") return False async def process_referral_topup( db: AsyncSession, user_id: int, topup_amount_kopeks: int, bot: Bot = None ): try: user = await get_user_by_id(db, user_id) if not user or not user.referred_by_id: logger.info(f"Пользователь {user_id} не является рефералом") return True if topup_amount_kopeks < settings.REFERRAL_MINIMUM_TOPUP_KOPEKS: logger.info(f"Пополнение {user_id} на {topup_amount_kopeks/100}₽ меньше минимума") return True referrer = await get_user_by_id(db, user.referred_by_id) if not referrer: logger.error(f"Реферер {user.referred_by_id} не найден") return False if not user.has_made_first_topup: user.has_made_first_topup = True await db.commit() try: await db.execute( delete(ReferralEarning).where( ReferralEarning.user_id == referrer.id, ReferralEarning.referral_id == user.id, ReferralEarning.reason == "referral_registration_pending" ) ) await db.commit() logger.info(f"🗑️ Удалена запись 'ожидание пополнения' для реферала {user.id}") except Exception as e: logger.error(f"Ошибка удаления записи ожидания: {e}") if settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS > 0: await add_user_balance( db, user, settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS, f"Бонус за первое пополнение по реферальной программе", bot=bot ) logger.info(f"💰 Реферал {user.id} получил бонус {settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS/100}₽") if bot: bonus_notification = ( f"🎉 Бонус получен!\n\n" f"За первое пополнение вы получили бонус " f"{settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}!\n\n" f"💎 Средства зачислены на ваш баланс." ) await send_referral_notification(bot, user.telegram_id, bonus_notification) commission_amount = int(topup_amount_kopeks * settings.REFERRAL_COMMISSION_PERCENT / 100) inviter_bonus = max(settings.REFERRAL_INVITER_BONUS_KOPEKS, commission_amount) if inviter_bonus > 0: await add_user_balance( db, referrer, inviter_bonus, f"Бонус за первое пополнение реферала {user.full_name}", bot=bot ) await create_referral_earning( db=db, user_id=referrer.id, referral_id=user.id, amount_kopeks=inviter_bonus, reason="referral_first_topup" ) logger.info(f"💰 Реферер {referrer.telegram_id} получил бонус {inviter_bonus/100}₽") if bot: inviter_bonus_notification = ( f"💰 Реферальная награда!\n\n" f"Ваш реферал {user.full_name} сделал первое пополнение!\n\n" f"🎁 Вы получили награду: {settings.format_price(inviter_bonus)}\n\n" f"📈 Теперь с каждого его пополнения вы будете получать {settings.REFERRAL_COMMISSION_PERCENT}% комиссии." ) await send_referral_notification(bot, referrer.telegram_id, inviter_bonus_notification) else: if settings.REFERRAL_COMMISSION_PERCENT > 0: commission_amount = int(topup_amount_kopeks * settings.REFERRAL_COMMISSION_PERCENT / 100) if commission_amount > 0: await add_user_balance( db, referrer, commission_amount, f"Комиссия {settings.REFERRAL_COMMISSION_PERCENT}% с пополнения {user.full_name}", bot=bot ) await create_referral_earning( db=db, user_id=referrer.id, referral_id=user.id, amount_kopeks=commission_amount, reason="referral_commission_topup" ) logger.info(f"💰 Комиссия с пополнения: {referrer.telegram_id} получил {commission_amount/100}₽") if bot: commission_notification = ( f"💰 Реферальная комиссия!\n\n" f"Ваш реферал {user.full_name} пополнил баланс на " f"{settings.format_price(topup_amount_kopeks)}\n\n" f"🎁 Ваша комиссия ({settings.REFERRAL_COMMISSION_PERCENT}%): " f"{settings.format_price(commission_amount)}\n\n" f"💎 Средства зачислены на ваш баланс." ) await send_referral_notification(bot, referrer.telegram_id, commission_notification) return True except Exception as e: logger.error(f"Ошибка обработки пополнения реферала: {e}") return False async def process_referral_purchase( db: AsyncSession, user_id: int, purchase_amount_kopeks: int, transaction_id: int = None, bot: Bot = None ): try: user = await get_user_by_id(db, user_id) if not user or not user.referred_by_id: return True referrer = await get_user_by_id(db, user.referred_by_id) if not referrer: logger.error(f"Реферер {user.referred_by_id} не найден") return False if not (0 <= settings.REFERRAL_COMMISSION_PERCENT <= 100): logger.error(f"❌ КРИТИЧЕСКАЯ ОШИБКА: REFERRAL_COMMISSION_PERCENT = {settings.REFERRAL_COMMISSION_PERCENT} некорректный!") commission_percent = 10 else: commission_percent = settings.REFERRAL_COMMISSION_PERCENT commission_amount = int(purchase_amount_kopeks * commission_percent / 100) if commission_amount > 0: await add_user_balance( db, referrer, commission_amount, f"Комиссия {commission_percent}% с покупки {user.full_name}", bot=bot ) await create_referral_earning( db=db, user_id=referrer.id, referral_id=user.id, amount_kopeks=commission_amount, reason="referral_commission", referral_transaction_id=transaction_id ) logger.info(f"💰 Комиссия с покупки: {referrer.telegram_id} получил {commission_amount/100}₽") if bot: purchase_commission_notification = ( f"💰 Комиссия с покупки!\n\n" f"Ваш реферал {user.full_name} совершил покупку на " f"{settings.format_price(purchase_amount_kopeks)}\n\n" f"🎁 Ваша комиссия ({commission_percent}%): " f"{settings.format_price(commission_amount)}\n\n" f"💎 Средства зачислены на ваш баланс." ) await send_referral_notification(bot, referrer.telegram_id, purchase_commission_notification) if not user.has_had_paid_subscription: user.has_had_paid_subscription = True await db.commit() logger.info(f"✅ Пользователь {user_id} отмечен как имевший платную подписку") return True except Exception as e: logger.error(f"Ошибка обработки покупки реферала: {e}") import traceback logger.error(f"Полный traceback: {traceback.format_exc()}") return False