BankBot-AI / backend /app /ai /subscriptions.py
mohsin-devs's picture
Deploy to HF
a282d4b
Raw
History Blame Contribute Delete
3.98 kB
from collections import defaultdict
from sqlalchemy.orm import Session
from app.database.models import Subscription
def analyze_subscriptions(db: Session, user_id: str):
"""
Analyzes subscriptions to detect duplicates, unused memberships, and cancellation opportunities.
"""
subs = db.query(Subscription).filter(
Subscription.user_id == user_id,
Subscription.active == True
).all()
if not subs:
return {
"subscriptions": [],
"duplicates": [],
"unused_subscriptions": [],
"yearly_savings_potential": 0.0,
"risk_analysis": []
}
merchant_map = defaultdict(list)
unused_list = []
cancellation_suggestions = []
yearly_savings = 0.0
risk_analysis = []
for s in subs:
# Standardize merchant name to detect duplicates
clean_merchant = s.merchant.strip().lower()
merchant_map[clean_merchant].append(s)
# Determine cost
m_cost = s.amount if s.billing_cycle.lower() == "monthly" else (s.amount / 12)
y_cost = (s.amount * 12) if s.billing_cycle.lower() == "monthly" else s.amount
# Detect unused (if frequency is 'low' or 'none' in usage detection metadata)
usage = s.ai_usage_detection or {}
freq = str(usage.get("usage_frequency", "medium")).lower()
if freq in ["low", "none", "unused"]:
unused_list.append(s)
cancellation_suggestions.append({
"subscription_id": s.id,
"merchant": s.merchant,
"amount": s.amount,
"billing_cycle": s.billing_cycle,
"reason": f"Usage frequency is flagged as '{freq}'.",
"yearly_savings": round(y_cost, 2)
})
yearly_savings += y_cost
# Detect duplicates
duplicates = []
for merchant, items in merchant_map.items():
if len(items) > 1:
total_cost = sum(x.amount for x in items)
duplicates.append({
"merchant": items[0].merchant,
"count": len(items),
"items": [
{
"id": x.id,
"amount": x.amount,
"billing_cycle": x.billing_cycle
}
for x in items
],
"recommendation": f"You have {len(items)} active subscriptions for {items[0].merchant}. Consolidate to a single account to save."
})
# Risk Analysis (utilities vs entertainment)
essential_categories = ["electricity", "water", "gas", "internet", "phone", "insurance"]
for s in subs:
is_essential = any(k in s.merchant.lower() for k in essential_categories)
if is_essential:
risk_analysis.append({
"merchant": s.merchant,
"risk_level": "high",
"consequences": "Utility interruption, account reactivation fees, or legal service contract breaches."
})
else:
risk_analysis.append({
"merchant": s.merchant,
"risk_level": "low",
"consequences": "Loss of entertainment streaming access only. Service can be reactivated instantly."
})
return {
"subscriptions": [
{
"id": s.id,
"merchant": s.merchant,
"amount": s.amount,
"billing_cycle": s.billing_cycle,
"usage_frequency": s.ai_usage_detection.get("usage_frequency", "medium") if s.ai_usage_detection else "medium"
}
for s in subs
],
"duplicates": duplicates,
"unused_subscriptions": cancellation_suggestions,
"yearly_savings_potential": round(yearly_savings, 2),
"risk_analysis": risk_analysis
}