RABAC felépítése megtörtént ill hirdetési portál alapok lerakva
This commit is contained in:
@@ -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}"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user