refakotorálás előtti állapot
This commit is contained in:
@@ -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"]
|
||||
|
||||
Reference in New Issue
Block a user