#!/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())