fixed database issue subscriptions
This commit is contained in:
parent
350c699473
commit
ef39d01e16
4 changed files with 60 additions and 22 deletions
|
|
@ -88,12 +88,15 @@ class CSRFMiddleware(BaseHTTPMiddleware):
|
||||||
content={"detail": "Invalid CSRF token format"}
|
content={"detail": "Invalid CSRF token format"}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Additional CSRF validation could be added here:
|
try:
|
||||||
# - Check token against session
|
return await call_next(request)
|
||||||
# - Validate token expiration
|
except Exception as exc:
|
||||||
# - Verify token origin
|
logger.error("Unhandled exception in %s %s: %s", request.method, request.url.path, exc)
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
return await call_next(request)
|
return JSONResponse(
|
||||||
|
status_code=500,
|
||||||
|
content={"detail": "Internal server error"},
|
||||||
|
)
|
||||||
|
|
||||||
def _is_valid_csrf_token(self, token: str) -> bool:
|
def _is_valid_csrf_token(self, token: str) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1728,8 +1728,10 @@ class AppObjects:
|
||||||
self.db.recordDelete(UserMandate, um.get("id"))
|
self.db.recordDelete(UserMandate, um.get("id"))
|
||||||
logger.info(f"Cascade: deleted {len(memberships)} UserMandates for mandate {mandateId}")
|
logger.info(f"Cascade: deleted {len(memberships)} UserMandates for mandate {mandateId}")
|
||||||
|
|
||||||
# 3. Cancel Stripe subscriptions + delete MandateSubscription records
|
# 3. Cancel Stripe subscriptions + delete MandateSubscription records (poweron_billing)
|
||||||
subs = self.db.getRecordset(MandateSubscription, recordFilter={"mandateId": mandateId})
|
from modules.interfaces.interfaceDbSubscription import _getRootInterface as _getSubRoot
|
||||||
|
subInterface = _getSubRoot()
|
||||||
|
subs = subInterface.listForMandate(mandateId)
|
||||||
for sub in subs:
|
for sub in subs:
|
||||||
subId = sub.get("id")
|
subId = sub.get("id")
|
||||||
stripeSubId = sub.get("stripeSubscriptionId")
|
stripeSubId = sub.get("stripeSubscriptionId")
|
||||||
|
|
@ -1741,20 +1743,21 @@ class AppObjects:
|
||||||
logger.info(f"Cancelled Stripe subscription {stripeSubId} for mandate {mandateId}")
|
logger.info(f"Cancelled Stripe subscription {stripeSubId} for mandate {mandateId}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Failed to cancel Stripe sub {stripeSubId}: {e}")
|
logger.warning(f"Failed to cancel Stripe sub {stripeSubId}: {e}")
|
||||||
self.db.recordDelete(MandateSubscription, subId)
|
subInterface.db.recordDelete(MandateSubscription, subId)
|
||||||
logger.info(f"Cascade: deleted {len(subs)} subscriptions for mandate {mandateId}")
|
logger.info(f"Cascade: deleted {len(subs)} subscriptions for mandate {mandateId}")
|
||||||
|
|
||||||
# 3b. Delete Billing data
|
# 3b. Delete Billing data (poweron_billing)
|
||||||
billingTxs = self.db.getRecordset(BillingTransaction, recordFilter={"mandateId": mandateId}) if hasattr(BillingTransaction, '__table_name__') else []
|
from modules.interfaces.interfaceDbBilling import _getRootInterface as _getBillingRoot
|
||||||
billingAccounts = self.db.getRecordset(BillingAccount, recordFilter={"mandateId": mandateId})
|
billingDb = _getBillingRoot().db
|
||||||
|
billingAccounts = billingDb.getRecordset(BillingAccount, recordFilter={"mandateId": mandateId})
|
||||||
for acc in billingAccounts:
|
for acc in billingAccounts:
|
||||||
accTxs = self.db.getRecordset(BillingTransaction, recordFilter={"accountId": acc.get("id")})
|
accTxs = billingDb.getRecordset(BillingTransaction, recordFilter={"accountId": acc.get("id")})
|
||||||
for tx in accTxs:
|
for tx in accTxs:
|
||||||
self.db.recordDelete(BillingTransaction, tx.get("id"))
|
billingDb.recordDelete(BillingTransaction, tx.get("id"))
|
||||||
self.db.recordDelete(BillingAccount, acc.get("id"))
|
billingDb.recordDelete(BillingAccount, acc.get("id"))
|
||||||
billingSettings = self.db.getRecordset(BillingSettings, recordFilter={"mandateId": mandateId})
|
billingSettings = billingDb.getRecordset(BillingSettings, recordFilter={"mandateId": mandateId})
|
||||||
for bs in billingSettings:
|
for bs in billingSettings:
|
||||||
self.db.recordDelete(BillingSettings, bs.get("id"))
|
billingDb.recordDelete(BillingSettings, bs.get("id"))
|
||||||
if billingAccounts or billingSettings:
|
if billingAccounts or billingSettings:
|
||||||
logger.info(f"Cascade: deleted billing data for mandate {mandateId}")
|
logger.info(f"Cascade: deleted billing data for mandate {mandateId}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,36 @@ def create_mandate(
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Could not create default billing settings for mandate {newMandate.id}: {billingErr}"
|
f"Could not create default billing settings for mandate {newMandate.id}: {billingErr}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from modules.datamodels.datamodelSubscription import (
|
||||||
|
MandateSubscription, SubscriptionStatusEnum, BUILTIN_PLANS,
|
||||||
|
)
|
||||||
|
from modules.interfaces.interfaceDbSubscription import _getRootInterface as _getSubRoot
|
||||||
|
from datetime import datetime, timezone, timedelta
|
||||||
|
|
||||||
|
planKey = mandateData.get("planKey", "TRIAL_7D")
|
||||||
|
plan = BUILTIN_PLANS.get(planKey)
|
||||||
|
if plan:
|
||||||
|
now = datetime.now(timezone.utc)
|
||||||
|
targetStatus = SubscriptionStatusEnum.TRIALING if plan.trialDays else SubscriptionStatusEnum.ACTIVE
|
||||||
|
sub = MandateSubscription(
|
||||||
|
mandateId=str(newMandate.id),
|
||||||
|
planKey=planKey,
|
||||||
|
status=targetStatus,
|
||||||
|
recurring=plan.autoRenew and not plan.trialDays,
|
||||||
|
startedAt=now,
|
||||||
|
currentPeriodStart=now,
|
||||||
|
)
|
||||||
|
if plan.trialDays:
|
||||||
|
sub.trialEndsAt = now + timedelta(days=plan.trialDays)
|
||||||
|
sub.currentPeriodEnd = now + timedelta(days=plan.trialDays)
|
||||||
|
subInterface = _getSubRoot()
|
||||||
|
subInterface.createSubscription(sub)
|
||||||
|
logger.info(f"Created {targetStatus.value} subscription ({planKey}) for mandate {newMandate.id}")
|
||||||
|
except Exception as subErr:
|
||||||
|
logger.error(f"Failed to create subscription for mandate {newMandate.id}: {subErr}")
|
||||||
|
|
||||||
logger.info(f"Mandate {newMandate.id} created by SysAdmin {currentUser.id}")
|
logger.info(f"Mandate {newMandate.id} created by SysAdmin {currentUser.id}")
|
||||||
|
|
||||||
return newMandate
|
return newMandate
|
||||||
|
|
|
||||||
|
|
@ -187,9 +187,12 @@ def getSubscriptionInfo(
|
||||||
"budgetAiCHF": None,
|
"budgetAiCHF": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
from modules.datamodels.datamodelSubscription import MandateSubscription, BUILTIN_PLANS
|
from modules.datamodels.datamodelSubscription import BUILTIN_PLANS
|
||||||
subs = db.getRecordset(MandateSubscription, recordFilter={"mandateId": mandateId})
|
from modules.interfaces.interfaceDbSubscription import _getRootInterface as _getSubRoot
|
||||||
if not subs:
|
|
||||||
|
subInterface = _getSubRoot()
|
||||||
|
allSubs = subInterface.listForMandate(mandateId)
|
||||||
|
if not allSubs:
|
||||||
return {
|
return {
|
||||||
"plan": None,
|
"plan": None,
|
||||||
"maxDataVolumeMB": None,
|
"maxDataVolumeMB": None,
|
||||||
|
|
@ -197,7 +200,7 @@ def getSubscriptionInfo(
|
||||||
"budgetAiCHF": None,
|
"budgetAiCHF": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
sub = subs[0]
|
sub = allSubs[0]
|
||||||
plan = BUILTIN_PLANS.get(sub.get("planKey"))
|
plan = BUILTIN_PLANS.get(sub.get("planKey"))
|
||||||
currentInstances = db.getRecordset(FeatureInstance, recordFilter={"mandateId": mandateId})
|
currentInstances = db.getRecordset(FeatureInstance, recordFilter={"mandateId": mandateId})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue