125 lines
4.4 KiB
Python
Executable File
125 lines
4.4 KiB
Python
Executable File
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import text
|
|
from app.api.deps import get_db, get_current_user
|
|
from typing import List, Dict
|
|
import secrets
|
|
|
|
router = APIRouter()
|
|
|
|
# 1. EGYENLEG LEKÉRDEZÉSE (A felhasználó Széfjéhez kötve)
|
|
@router.get("/balance")
|
|
async def get_balance(db: AsyncSession = Depends(get_db), current_user = Depends(get_current_user)):
|
|
"""
|
|
Visszaadja a felhasználó aktuális kreditegyenlegét és a Széfje (Cége) nevét.
|
|
"""
|
|
query = text("""
|
|
SELECT
|
|
uc.balance,
|
|
c.name as company_name
|
|
FROM data.user_credits uc
|
|
JOIN data.companies c ON uc.user_id = c.owner_id
|
|
WHERE uc.user_id = :user_id
|
|
LIMIT 1
|
|
""")
|
|
result = await db.execute(query, {"user_id": current_user.id})
|
|
row = result.fetchone()
|
|
|
|
if not row:
|
|
return {
|
|
"company_name": "Privát Széf",
|
|
"balance": 0.0,
|
|
"currency": "Credit"
|
|
}
|
|
|
|
return {
|
|
"company_name": row.company_name,
|
|
"balance": float(row.balance),
|
|
"currency": "Credit"
|
|
}
|
|
|
|
# 2. TRANZAKCIÓS ELŐZMÉNYEK
|
|
@router.get("/history")
|
|
async def get_history(db: AsyncSession = Depends(get_db), current_user = Depends(get_current_user)):
|
|
"""
|
|
Kilistázza a kreditmozgásokat (bevételek, költések, voucherek).
|
|
"""
|
|
query = text("""
|
|
SELECT amount, reason, created_at
|
|
FROM data.credit_transactions
|
|
WHERE user_id = :user_id
|
|
ORDER BY created_at DESC
|
|
""")
|
|
result = await db.execute(query, {"user_id": current_user.id})
|
|
return [dict(row._mapping) for row in result.fetchall()]
|
|
|
|
# 3. VOUCHER BEVÁLTÁS (A rendszer gazdaságának motorja)
|
|
@router.post("/vouchers/redeem")
|
|
async def redeem_voucher(code: str, db: AsyncSession = Depends(get_db), current_user = Depends(get_current_user)):
|
|
"""
|
|
Bevált egy kódot, és jóváírja az értékét a felhasználó egyenlegén.
|
|
"""
|
|
# 1. Voucher ellenőrzése
|
|
check_query = text("""
|
|
SELECT id, value, is_used, expires_at
|
|
FROM data.vouchers
|
|
WHERE code = :code AND is_used = False AND (expires_at > now() OR expires_at IS NULL)
|
|
""")
|
|
res = await db.execute(check_query, {"code": code.strip().upper()})
|
|
voucher = res.fetchone()
|
|
|
|
if not voucher:
|
|
raise HTTPException(status_code=400, detail="Érvénytelen, lejárt vagy már felhasznált kód.")
|
|
|
|
# 2. Egyenleg frissítése (vagy létrehozása, ha még nincs sor a user_credits-ben)
|
|
update_balance = text("""
|
|
INSERT INTO data.user_credits (user_id, balance)
|
|
VALUES (:u, :v)
|
|
ON CONFLICT (user_id) DO UPDATE SET balance = data.user_credits.balance + :v
|
|
""")
|
|
await db.execute(update_balance, {"u": current_user.id, "v": voucher.value})
|
|
|
|
# 3. Tranzakció naplózása
|
|
log_transaction = text("""
|
|
INSERT INTO data.credit_transactions (user_id, amount, reason)
|
|
VALUES (:u, :v, :r)
|
|
""")
|
|
await db.execute(log_transaction, {
|
|
"u": current_user.id,
|
|
"v": voucher.value,
|
|
"r": f"Voucher beváltva: {code}"
|
|
})
|
|
|
|
# 4. Voucher megjelölése felhasználtként
|
|
await db.execute(text("""
|
|
UPDATE data.vouchers
|
|
SET is_used = True, used_by = :u, used_at = now()
|
|
WHERE id = :vid
|
|
"""), {"u": current_user.id, "vid": voucher.id})
|
|
|
|
await db.commit()
|
|
return {"status": "success", "added_value": float(voucher.value), "message": "Kredit jóváírva!"}
|
|
|
|
# 4. ADMIN: VOUCHER GENERÁLÁS (Csak Neked)
|
|
@router.post("/vouchers/generate", include_in_schema=True)
|
|
async def generate_vouchers(
|
|
count: int = 1,
|
|
value: float = 500.0,
|
|
batch_name: str = "ADMIN_GEN",
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""
|
|
Tömeges voucher generálás az admin felületről.
|
|
"""
|
|
generated_codes = []
|
|
for _ in range(count):
|
|
# Generálunk egy SF-XXXX-XXXX formátumú kódot
|
|
code = f"SF-{secrets.token_hex(3).upper()}-{secrets.token_hex(3).upper()}"
|
|
await db.execute(text("""
|
|
INSERT INTO data.vouchers (code, value, batch_id, expires_at)
|
|
VALUES (:c, :v, :b, now() + interval '90 days')
|
|
"""), {"c": code, "v": value, "b": batch_name})
|
|
generated_codes.append(code)
|
|
|
|
await db.commit()
|
|
return {"batch": batch_name, "count": count, "codes": generated_codes} |