RABAC felépítése megtörtént ill hirdetési portál alapok lerakva

This commit is contained in:
Roo
2026-06-19 06:06:34 +00:00
parent fe3c32597d
commit 9ba2d9180d
30 changed files with 4336 additions and 76 deletions

View File

@@ -727,6 +727,9 @@ async def upgrade_subscription(
"""
Felhasználó előfizetésének frissítése (csomagváltás).
P0 Stacking Feature: A duration_days mezőt a tier.rules-ból olvassa ki,
és a valid_until számításánál időhalmozást (stacking) alkalmaz.
Args:
db: Database session
user_id: Felhasználó ID
@@ -735,7 +738,7 @@ async def upgrade_subscription(
Returns:
Dict: Tranzakció részletei és az új előfizetés információi
"""
from app.models.core_logic import SubscriptionTier
from app.models.core_logic import SubscriptionTier, UserSubscription
from app.models.identity import User
# 1. Ellenőrizze, hogy a cél csomag létezik-e
@@ -746,23 +749,67 @@ async def upgrade_subscription(
if not tier:
raise ValueError(f"Subscription tier '{target_package}' not found")
# ── P0 STACKING: duration_days kiolvasása a tier.rules-ból ──
duration_days = 30 # alapértelmezett 30 nap
allow_stacking = True
if tier.rules:
duration_config = tier.rules.get("duration", {})
if isinstance(duration_config, dict):
duration_days = duration_config.get("days", 30)
allow_stacking = duration_config.get("allow_stacking", True)
now = datetime.utcnow()
# 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
# ── P0 STACKING: user_subscriptions tábla kezelése ──
# Lekérdezzük a meglévő aktív user subscription-t
us_stmt = select(UserSubscription).where(
UserSubscription.user_id == user_id,
UserSubscription.is_active == True
)
us_result = await db.execute(us_stmt)
existing_us = us_result.scalar_one_or_none()
if existing_us:
existing_us.is_active = False
# Stacking számítás
if existing_us and allow_stacking and existing_us.valid_until and existing_us.valid_until > now:
new_valid_until = existing_us.valid_until + timedelta(days=duration_days)
else:
new_valid_until = now + timedelta(days=duration_days)
# Új UserSubscription rekord
new_us = UserSubscription(
user_id=user_id,
tier_id=tier.id,
valid_from=now,
valid_until=new_valid_until,
is_active=True
)
db.add(new_us)
user.subscription_expires_at = new_valid_until
return {
"success": True,
"message": f"Upgraded to {target_package} (free)",
"new_plan": target_package,
"price_paid": 0.0
"price_paid": 0.0,
"valid_until": new_valid_until.isoformat(),
"duration_days": duration_days,
"stacking_applied": allow_stacking and bool(existing_us and existing_us.valid_until and existing_us.valid_until > now)
}
# 3. Ár kiszámítása a PricingCalculator segítségével
@@ -789,15 +836,51 @@ async def upgrade_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")
# ── P0 STACKING: user_subscriptions tábla kezelése ──
us_stmt = select(UserSubscription).where(
UserSubscription.user_id == user_id,
UserSubscription.is_active == True
)
us_result = await db.execute(us_stmt)
existing_us = us_result.scalar_one_or_none()
if existing_us:
existing_us.is_active = False
# Stacking számítás
if existing_us and allow_stacking and existing_us.valid_until and existing_us.valid_until > now:
new_valid_until = existing_us.valid_until + timedelta(days=duration_days)
else:
new_valid_until = now + timedelta(days=duration_days)
# Új UserSubscription rekord
new_us = UserSubscription(
user_id=user_id,
tier_id=tier.id,
valid_from=now,
valid_until=new_valid_until,
is_active=True
)
db.add(new_us)
user.subscription_expires_at = new_valid_until
logger.info(
f"User {user_id} upgraded to {target_package} for {final_price} EUR, "
f"valid_until={new_valid_until.isoformat()}, "
f"duration_days={duration_days}, "
f"stacking={allow_stacking}"
)
return {
"success": True,
"transaction": transaction,
"new_plan": target_package,
"price_paid": final_price,
"valid_until": new_valid_until.isoformat(),
"duration_days": duration_days,
"stacking_applied": allow_stacking and bool(existing_us and existing_us.valid_until and existing_us.valid_until > now),
"expires_at": user.subscription_expires_at.isoformat()
}
@@ -816,6 +899,12 @@ async def upgrade_org_subscription(
subscription_tier_id FK on the Organization record, and also creates/
updates a record in finance.org_subscriptions for audit trail.
P0 Stacking Feature: A duration_days mezőt a tier.rules-ból olvassa ki,
és a valid_until számításánál időhalmozást (stacking) alkalmaz:
- Ha a meglévő előfizetés még aktív (valid_until > NOW):
új valid_until = régi valid_until + duration_days
- Ha lejárt vagy nincs: új valid_until = NOW + duration_days
Args:
db: Database session
org_id: Organization ID
@@ -860,24 +949,54 @@ async def upgrade_org_subscription(
sub_result = await db.execute(sub_stmt)
existing_sub = sub_result.scalar_one_or_none()
# ── P0 STACKING: duration_days kiolvasása a tier.rules-ból ──
duration_days = 30 # alapértelmezett 30 nap
allow_stacking = True
if tier.rules:
duration_config = tier.rules.get("duration", {})
if isinstance(duration_config, dict):
duration_days = duration_config.get("days", 30)
allow_stacking = duration_config.get("allow_stacking", True)
now = datetime.utcnow()
if existing_sub:
# Deaktiváljuk a régit
existing_sub.is_active = False
existing_sub.valid_until = datetime.utcnow()
existing_sub.valid_until = now
# Új aktív subscription rekord
# ── P0 STACKING: valid_until számítás időhalmozással ──
if existing_sub and allow_stacking and existing_sub.valid_until and existing_sub.valid_until > now:
# Stacking: a meglévő valid_until-hoz hozzáadjuk a duration_days-t
new_valid_until = existing_sub.valid_until + timedelta(days=duration_days)
logger.info(
f"STACKING: org_id={org_id} existing valid_until={existing_sub.valid_until} "
f"+ {duration_days} days = {new_valid_until}"
)
else:
# Nincs stacking: mostól számítva + duration_days
new_valid_until = now + timedelta(days=duration_days)
# Új aktív subscription rekord stackinggel számolt valid_until-lal
new_sub = OrganizationSubscription(
org_id=org_id,
tier_id=tier_id,
valid_from=datetime.utcnow(),
valid_from=now,
valid_until=new_valid_until,
is_active=True
)
db.add(new_sub)
# Frissítsük a szervezet denormalizált mezőit is
org.subscription_expires_at = new_valid_until
logger.info(
f"Org subscription upgraded: org_id={org_id}, "
f"tier={tier.name} (id={tier_id}), "
f"max_vehicles={max_vehicles}, "
f"valid_until={new_valid_until.isoformat()}, "
f"duration_days={duration_days}, "
f"stacking={allow_stacking}, "
f"actor={actor_user_id}"
)
@@ -887,6 +1006,9 @@ async def upgrade_org_subscription(
"tier_id": tier_id,
"tier_name": tier.name,
"max_vehicles": max_vehicles,
"valid_until": new_valid_until.isoformat(),
"duration_days": duration_days,
"stacking_applied": allow_stacking and bool(existing_sub and existing_sub.valid_until and existing_sub.valid_until > now),
"message": f"Organization {org_id} upgraded to {tier.name}"
}