Files
service-finder/backend/app/scripts/test_mlm_payout.py
2026-06-04 07:26:22 +00:00

321 lines
12 KiB
Python

#!/usr/bin/env python3
"""
MLM Payout E2E teszt script.
Szimulál egy előfizetési fizetést (10,000 HUF) és ellenőrzi a CREDIT Wallet jóváírásokat L1, L2, L3 usereknek.
Futtatás: docker compose exec sf_api python3 /app/backend/test_mlm_payout.py
"""
import asyncio
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select, update, func
from decimal import Decimal
from app.models.identity import User, Person
from app.models.finance.wallet import Wallet, Ledger, WalletType, TransactionType
from app.models.system.system import SystemParameter
from app.core.config import settings
async def test_mlm_payout():
engine = create_async_engine(settings.DATABASE_URL, echo=True)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async with async_session() as session:
print("=== MLM Payout E2E Teszt ===")
# 1. Teszt adatok létrehozása (ha nincsenek)
# Létrehozunk egy L1, L2, L3, L4 (fizető) usert láncolatban
print("1. Teszt userek létrehozása...")
# Ellenőrizzük, hogy van-e már teszt user
existing = await session.execute(select(User).where(User.email == "test_l1@example.com"))
l1_user = existing.scalar_one_or_none()
if not l1_user:
# L1 user (root meghívó)
l1_person = Person(
first_name="L1",
last_name="Referrer",
is_active=True,
identity_docs={},
ice_contact={},
lifetime_xp=0,
penalty_points=0,
social_reputation=1.0,
is_sales_agent=False,
is_ghost=False,
)
session.add(l1_person)
await session.flush()
l1_user = User(
email="test_l1@example.com",
hashed_password="$2b$12$...", # dummy
person_id=l1_person.id,
role="user",
is_active=True,
is_deleted=False,
region_code="HU",
preferred_language="hu",
subscription_plan="FREE",
is_vip=True,
preferred_currency="HUF",
scope_level="individual",
custom_permissions={},
referral_code="L1REF123",
referred_by_id=None,
)
session.add(l1_user)
await session.flush()
print(f" L1 user létrehozva: ID={l1_user.id}, kód={l1_user.referral_code}")
# L2 user (L1 meghívja)
existing = await session.execute(select(User).where(User.email == "test_l2@example.com"))
l2_user = existing.scalar_one_or_none()
if not l2_user:
l2_person = Person(
first_name="L2",
last_name="Referral",
is_active=True,
identity_docs={},
ice_contact={},
lifetime_xp=0,
penalty_points=0,
social_reputation=1.0,
is_sales_agent=False,
is_ghost=False,
)
session.add(l2_person)
await session.flush()
l2_user = User(
email="test_l2@example.com",
hashed_password="$2b$12$...",
person_id=l2_person.id,
role="user",
is_active=True,
is_deleted=False,
region_code="HU",
preferred_language="hu",
subscription_plan="FREE",
is_vip=True,
preferred_currency="HUF",
scope_level="individual",
custom_permissions={},
referral_code="L2REF456",
referred_by_id=l1_user.id,
)
session.add(l2_user)
await session.flush()
print(f" L2 user létrehozva: ID={l2_user.id}, kód={l2_user.referral_code}, referred_by={l2_user.referred_by_id}")
# L3 user (L2 meghívja)
existing = await session.execute(select(User).where(User.email == "test_l3@example.com"))
l3_user = existing.scalar_one_or_none()
if not l3_user:
l3_person = Person(
first_name="L3",
last_name="Referral",
is_active=True,
identity_docs={},
ice_contact={},
lifetime_xp=0,
penalty_points=0,
social_reputation=1.0,
is_sales_agent=False,
is_ghost=False,
)
session.add(l3_person)
await session.flush()
l3_user = User(
email="test_l3@example.com",
hashed_password="$2b$12$...",
person_id=l3_person.id,
role="user",
is_active=True,
is_deleted=False,
region_code="HU",
preferred_language="hu",
subscription_plan="FREE",
is_vip=True,
preferred_currency="HUF",
scope_level="individual",
custom_permissions={},
referral_code="L3REF789",
referred_by_id=l2_user.id,
)
session.add(l3_user)
await session.flush()
print(f" L3 user létrehozva: ID={l3_user.id}, kód={l3_user.referral_code}, referred_by={l3_user.referred_by_id}")
# L4 user (fizető, L3 meghívja)
existing = await session.execute(select(User).where(User.email == "test_l4_payer@example.com"))
l4_user = existing.scalar_one_or_none()
if not l4_user:
l4_person = Person(
first_name="L4",
last_name="Payer",
is_active=True,
identity_docs={},
ice_contact={},
lifetime_xp=0,
penalty_points=0,
social_reputation=1.0,
is_sales_agent=False,
is_ghost=False,
)
session.add(l4_person)
await session.flush()
l4_user = User(
email="test_l4_payer@example.com",
hashed_password="$2b$12$...",
person_id=l4_person.id,
role="user",
is_active=True,
is_deleted=False,
region_code="HU",
preferred_language="hu",
subscription_plan="FREE",
is_vip=True,
preferred_currency="HUF",
scope_level="individual",
custom_permissions={},
referral_code="L4REF999",
referred_by_id=l3_user.id,
)
session.add(l4_user)
await session.flush()
print(f" L4 (fizető) user létrehozva: ID={l4_user.id}, referred_by={l4_user.referred_by_id}")
await session.commit()
# 2. MLM paraméterek lekérése
print("\n2. MLM paraméterek lekérése...")
params = {}
for key in ["mlm_level1_percent", "mlm_level2_percent", "mlm_level3_percent"]:
stmt = select(SystemParameter).where(SystemParameter.key == key)
param = (await session.execute(stmt)).scalar_one_or_none()
if param:
params[key] = int(param.value.get("value", 0))
print(f" {key}: {params[key]}%")
else:
params[key] = 0
print(f" {key}: NINCS BEÁLLÍTVA!")
# 3. Szimulált fizetés (10,000 HUF)
payment_amount = Decimal("10000.00")
print(f"\n3. Szimulált fizetés: {payment_amount} HUF (L4 user fizet)")
# 4. MLM lánc felépítése
print("\n4. MLM lánc felépítése...")
chain = []
current = l4_user
for i in range(3):
if current.referred_by_id:
stmt = select(User).where(User.id == current.referred_by_id)
referrer = (await session.execute(stmt)).scalar_one_or_none()
if referrer:
chain.append(referrer)
current = referrer
else:
break
else:
break
print(f" Lánc hossza: {len(chain)}")
for idx, user in enumerate(chain):
print(f" L{idx+1}: {user.email} (ID: {user.id})")
# 5. Jutalékok kiszámítása és CREDIT Wallet jóváírás
print("\n5. Jutalékok kiszámítása és CREDIT Wallet jóváírás...")
levels = ["mlm_level1_percent", "mlm_level2_percent", "mlm_level3_percent"]
for idx, referrer in enumerate(chain):
if idx >= 3:
break
percent = params[levels[idx]]
commission = (payment_amount * Decimal(percent) / Decimal(100)).quantize(Decimal("0.01"))
print(f" L{idx+1} ({referrer.email}): {percent}% -> {commission} HUF")
# CREDIT Wallet keresése vagy létrehozása
wallet_stmt = select(Wallet).where(
Wallet.user_id == referrer.id,
Wallet.wallet_type == WalletType.CREDIT
)
wallet = (await session.execute(wallet_stmt)).scalar_one_or_none()
if not wallet:
wallet = Wallet(
user_id=referrer.id,
currency="HUF",
wallet_type=WalletType.CREDIT,
balance=Decimal("0.00"),
is_active=True
)
session.add(wallet)
await session.flush()
# Balance frissítése
wallet.balance += commission
# Ledger bejegyzés
ledger = Ledger(
wallet_id=wallet.id,
amount=commission,
transaction_type=TransactionType.MLM_CREDIT,
description=f"MLM jutalék L{idx+1} a(z) {l4_user.email} fizetéséből",
reference_id=l4_user.id,
reference_type="user_payment",
metadata={
"payer_id": l4_user.id,
"payer_email": l4_user.email,
"level": idx+1,
"percent": percent,
"original_amount": float(payment_amount)
}
)
session.add(ledger)
await session.commit()
# 6. Ellenőrzés
print("\n6. Ellenőrzés - CREDIT Wallet egyenlegek:")
for idx, referrer in enumerate(chain):
if idx >= 3:
break
wallet_stmt = select(Wallet).where(
Wallet.user_id == referrer.id,
Wallet.wallet_type == WalletType.CREDIT
)
wallet = (await session.execute(wallet_stmt)).scalar_one_or_none()
if wallet:
print(f" L{idx+1} ({referrer.email}): {wallet.balance} HUF")
else:
print(f" L{idx+1} ({referrer.email}): NINCS CREDIT Wallet!")
# 7. Ledger bejegyzések listázása
print("\n7. Ledger bejegyzések:")
for referrer in chain[:3]:
wallet_stmt = select(Wallet).where(
Wallet.user_id == referrer.id,
Wallet.wallet_type == WalletType.CREDIT
)
wallet = (await session.execute(wallet_stmt)).scalar_one_or_none()
if wallet:
ledger_stmt = select(Ledger).where(Ledger.wallet_id == wallet.id).order_by(Ledger.created_at.desc()).limit(2)
ledgers = (await session.execute(ledger_stmt)).scalars().all()
for l in ledgers:
print(f" - {referrer.email}: {l.amount} HUF ({l.transaction_type}) - {l.description}")
print("\n✅ MLM Payout teszt sikeresen lefutott!")
print("=== TESZT VÉGE ===")
if __name__ == "__main__":
asyncio.run(test_mlm_payout())