mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-01-20 03:40:26 +00:00
Allow referral commissions on any top-up amount
This commit is contained in:
@@ -89,16 +89,64 @@ async def process_referral_topup(
|
||||
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
|
||||
|
||||
|
||||
qualifies_for_first_bonus = (
|
||||
topup_amount_kopeks >= settings.REFERRAL_MINIMUM_TOPUP_KOPEKS
|
||||
)
|
||||
commission_amount = 0
|
||||
if settings.REFERRAL_COMMISSION_PERCENT > 0:
|
||||
commission_amount = int(
|
||||
topup_amount_kopeks * settings.REFERRAL_COMMISSION_PERCENT / 100
|
||||
)
|
||||
|
||||
if not user.has_made_first_topup:
|
||||
if not qualifies_for_first_bonus:
|
||||
logger.info(
|
||||
"Пополнение %s на %s₽ меньше минимума для первого бонуса, но комиссия будет начислена",
|
||||
user_id,
|
||||
topup_amount_kopeks / 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(
|
||||
"💰 Комиссия с пополнения: %s получил %s₽ (до первого бонуса)",
|
||||
referrer.telegram_id,
|
||||
commission_amount / 100,
|
||||
)
|
||||
|
||||
if bot:
|
||||
commission_notification = (
|
||||
f"💰 <b>Реферальная комиссия!</b>\n\n"
|
||||
f"Ваш реферал <b>{user.full_name}</b> пополнил баланс на "
|
||||
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
|
||||
|
||||
user.has_made_first_topup = True
|
||||
await db.commit()
|
||||
|
||||
@@ -161,36 +209,33 @@ async def process_referral_topup(
|
||||
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
|
||||
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"💰 <b>Реферальная комиссия!</b>\n\n"
|
||||
f"Ваш реферал <b>{user.full_name}</b> пополнил баланс на "
|
||||
f"{settings.format_price(topup_amount_kopeks)}\n\n"
|
||||
f"🎁 Ваша комиссия ({settings.REFERRAL_COMMISSION_PERCENT}%): "
|
||||
f"{settings.format_price(commission_amount)}\n\n"
|
||||
f"💎 Средства зачислены на ваш баланс."
|
||||
)
|
||||
|
||||
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"💰 <b>Реферальная комиссия!</b>\n\n"
|
||||
f"Ваш реферал <b>{user.full_name}</b> пополнил баланс на "
|
||||
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)
|
||||
await send_referral_notification(bot, referrer.telegram_id, commission_notification)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
67
tests/services/test_referral_service.py
Normal file
67
tests/services/test_referral_service.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from pathlib import Path
|
||||
import sys
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT_DIR = Path(__file__).resolve().parents[2]
|
||||
if str(ROOT_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT_DIR))
|
||||
|
||||
from app.services import referral_service # noqa: E402
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_commission_accrues_before_minimum_first_topup(monkeypatch):
|
||||
user = SimpleNamespace(
|
||||
id=1,
|
||||
telegram_id=101,
|
||||
full_name="Test User",
|
||||
referred_by_id=2,
|
||||
has_made_first_topup=False,
|
||||
)
|
||||
referrer = SimpleNamespace(
|
||||
id=2,
|
||||
telegram_id=202,
|
||||
full_name="Referrer",
|
||||
)
|
||||
|
||||
db = SimpleNamespace(
|
||||
commit=AsyncMock(),
|
||||
execute=AsyncMock(),
|
||||
)
|
||||
|
||||
get_user_mock = AsyncMock(side_effect=[user, referrer])
|
||||
monkeypatch.setattr(referral_service, "get_user_by_id", get_user_mock)
|
||||
add_user_balance_mock = AsyncMock()
|
||||
monkeypatch.setattr(referral_service, "add_user_balance", add_user_balance_mock)
|
||||
create_referral_earning_mock = AsyncMock()
|
||||
monkeypatch.setattr(referral_service, "create_referral_earning", create_referral_earning_mock)
|
||||
|
||||
monkeypatch.setattr(referral_service.settings, "REFERRAL_MINIMUM_TOPUP_KOPEKS", 20000)
|
||||
monkeypatch.setattr(referral_service.settings, "REFERRAL_FIRST_TOPUP_BONUS_KOPEKS", 5000)
|
||||
monkeypatch.setattr(referral_service.settings, "REFERRAL_INVITER_BONUS_KOPEKS", 10000)
|
||||
monkeypatch.setattr(referral_service.settings, "REFERRAL_COMMISSION_PERCENT", 25)
|
||||
|
||||
topup_amount = 15000
|
||||
|
||||
result = await referral_service.process_referral_topup(db, user.id, topup_amount)
|
||||
|
||||
assert result is True
|
||||
assert user.has_made_first_topup is False
|
||||
|
||||
add_user_balance_mock.assert_awaited_once()
|
||||
add_call = add_user_balance_mock.await_args
|
||||
assert add_call.args[1] is referrer
|
||||
assert add_call.args[2] == 3750
|
||||
assert "Комиссия" in add_call.args[3]
|
||||
assert add_call.kwargs.get("bot") is None
|
||||
|
||||
create_referral_earning_mock.assert_awaited_once()
|
||||
earning_call = create_referral_earning_mock.await_args
|
||||
assert earning_call.kwargs["amount_kopeks"] == 3750
|
||||
assert earning_call.kwargs["reason"] == "referral_commission_topup"
|
||||
|
||||
db.commit.assert_not_awaited()
|
||||
db.execute.assert_not_awaited()
|
||||
Reference in New Issue
Block a user