refakotorálás előtti állapot

This commit is contained in:
Roo
2026-03-10 07:34:01 +00:00
parent 4e40af8a08
commit 0304cb8142
39 changed files with 1552 additions and 125 deletions

View File

@@ -682,3 +682,199 @@ async def get_wallet_info(
Segédfüggvény pénztárca információk lekérdezéséhez.
"""
return await AtomicTransactionManager.get_wallet_summary(db, user_id)
# ==================== Billing Engine Service Functions ====================
async def charge_user(
db: AsyncSession,
user_id: int,
amount: float,
currency: str = "EUR",
transaction_type: str = "service_payment",
description: Optional[str] = None
) -> Dict[str, Any]:
"""
Kredit levonás a felhasználótól intelligens levonási sorrendben.
Args:
db: Database session
user_id: Felhasználó ID
amount: Levonandó összeg
currency: Pénznem (jelenleg csak EUR támogatott)
transaction_type: Tranzakció típusa (pl. "service_payment", "subscription")
description: Opcionális leírás
Returns:
Dict: Tranzakció részletei (AtomicTransactionManager.atomic_billing_transaction eredménye)
"""
if currency != "EUR":
raise ValueError("Only EUR currency is currently supported")
desc = description or f"Charge for {transaction_type}"
return await AtomicTransactionManager.atomic_billing_transaction(
db=db,
user_id=user_id,
amount=amount,
description=desc,
reference_type=transaction_type,
reference_id=None
)
async def upgrade_subscription(
db: AsyncSession,
user_id: int,
target_package: str
) -> Dict[str, Any]:
"""
Felhasználó előfizetésének frissítése (csomagváltás).
Args:
db: Database session
user_id: Felhasználó ID
target_package: Cél csomag neve (pl. "premium", "vip")
Returns:
Dict: Tranzakció részletei és az új előfizetés információi
"""
from app.models.core_logic import SubscriptionTier
from app.models.identity import User
# 1. Ellenőrizze, hogy a cél csomag létezik-e
stmt = select(SubscriptionTier).where(SubscriptionTier.name == target_package)
result = await db.execute(stmt)
tier = result.scalar_one_or_none()
if not tier:
raise ValueError(f"Subscription tier '{target_package}' not found")
# 2. Számítsa ki az árát a csomagnak (egyszerűsítve: fix ár a tier.rules-ból)
price = tier.rules.get("price", 0.0) if tier.rules else 0.0
if price <= 0:
# Ingyenes csomag, nincs levonás
logger.info(f"Upgrading user {user_id} to free tier {target_package}")
# Frissítse a felhasználó subscription_plan mezőjét
user_stmt = select(User).where(User.id == user_id)
user_result = await db.execute(user_stmt)
user = user_result.scalar_one()
user.subscription_plan = target_package
user.subscription_expires_at = datetime.utcnow() + timedelta(days=30) # 30 nap
return {
"success": True,
"message": f"Upgraded to {target_package} (free)",
"new_plan": target_package,
"price_paid": 0.0
}
# 3. Ár kiszámítása a PricingCalculator segítségével
user_stmt = select(User).where(User.id == user_id)
user_result = await db.execute(user_stmt)
user = user_result.scalar_one()
final_price = await PricingCalculator.calculate_final_price(
db=db,
base_amount=price,
country_code=user.region_code,
user_role=user.role
)
# 4. Levonás a felhasználótól
transaction = await charge_user(
db=db,
user_id=user_id,
amount=final_price,
currency="EUR",
transaction_type="subscription_upgrade",
description=f"Upgrade to {target_package} subscription"
)
# 5. Frissítse a felhasználó előfizetési adatait
user.subscription_plan = target_package
user.subscription_expires_at = datetime.utcnow() + timedelta(days=30) # 30 nap
logger.info(f"User {user_id} upgraded to {target_package} for {final_price} EUR")
return {
"success": True,
"transaction": transaction,
"new_plan": target_package,
"price_paid": final_price,
"expires_at": user.subscription_expires_at.isoformat()
}
async def record_ledger_entry(
db: AsyncSession,
user_id: int,
amount: float,
entry_type: LedgerEntryType,
wallet_type: WalletType,
transaction_type: str,
description: str,
reference_type: Optional[str] = None,
reference_id: Optional[int] = None
) -> FinancialLedger:
"""
Közvetlen főkönyvbejegyzés létrehozása (pl. manuális korrekciók).
Megjegyzés: Ez a függvény NEM végez levonást a pénztárcából, csak naplóbejegyzést készít.
A pénztárca egyenleg frissítéséhez használd a charge_user vagy atomic_billing_transaction függvényeket.
Args:
db: Database session
user_id: Felhasználó ID
amount: Összeg
entry_type: DEBIT vagy CREDIT
wallet_type: Pénztárca típus
transaction_type: Tranzakció típusa
description: Leírás
reference_type: Referencia típus
reference_id: Referencia ID
Returns:
FinancialLedger: Létrehozott főkönyvbejegyzés
"""
ledger_entry = FinancialLedger(
user_id=user_id,
amount=Decimal(str(amount)),
entry_type=entry_type,
wallet_type=wallet_type,
transaction_type=transaction_type,
details={
"description": description,
"reference_type": reference_type,
"reference_id": reference_id,
"wallet_type": wallet_type.value
},
transaction_id=uuid.uuid4(),
balance_after=None, # Később számolható
currency="EUR"
)
db.add(ledger_entry)
await db.flush()
logger.info(f"Ledger entry recorded: user={user_id}, amount={amount}, type={entry_type.value}")
return ledger_entry
async def get_user_balance(
db: AsyncSession,
user_id: int
) -> Dict[str, float]:
"""
Felhasználó pénztárca egyenlegének lekérdezése.
Args:
db: Database session
user_id: Felhasználó ID
Returns:
Dict: Pénztárca típusonkénti egyenlegek
"""
wallet_summary = await AtomicTransactionManager.get_wallet_summary(db, user_id)
return wallet_summary["balances"]