Spaces:
Running
Running
File size: 8,025 Bytes
72bff80 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel
from typing import List, Dict, Optional, Any
import json
import re
from random import random
router = APIRouter(prefix="/plans", tags=["Plans"])
class PlanInfoRequest(BaseModel):
age: int
gender: str
premium_amount: float
goal: Optional[str] = "savings"
plan_id: Optional[int] = None
policy_term: Optional[str] = None
payment_term: Optional[str] = None
payment_mode: Optional[str] = None
class BenefitItem(BaseModel):
name: str
value: str
description: str
class PlanBenefitResponse(BaseModel):
plan_id: int
plan_name: str
eligibility_status: bool
reason: str
maturity_benefit: str
annual_income: str
sum_assured: str
income_start_point: str
income_duration: str
sad_multiple: str
payout_freq: str
recommendation_score: float
benefits: List[BenefitItem]
# Dummy Plan Data Store
PLANS_DATA = {
1: {
"name": "Edelweiss Life Guaranteed Income STAR",
"min_age": 3,
"max_age": 50,
"benefits_multiplier": 1.2,
"income_start": "5 years",
"income_duration": "20 years",
"payout_freq": "Yearly",
"sad_multiple": "10"
},
2: {
"name": "Edelweiss Life Bharat Savings STAR",
"min_age": 0,
"max_age": 60,
"benefits_multiplier": 1.1,
"income_start": "2nd year",
"income_duration": "15 years",
"payout_freq": "Monthly",
"sad_multiple": "7"
},
3: {
"name": "Edelweiss Life Premier Guaranteed STAR Pro",
"min_age": 5,
"max_age": 55,
"benefits_multiplier": 1.3,
"income_start": "15 years",
"income_duration": "20 years",
"payout_freq": "Yearly",
"sad_multiple": "11"
},
4: {
"name": "EdelweissLife Flexi Dream Plan",
"min_age": 18,
"max_age": 60,
"benefits_multiplier": 0.9,
"income_start": "2 years",
"income_duration": "10 years",
"payout_freq": "Yearly",
"sad_multiple": "8"
},
5: {
"name": "EdelweissLife Guaranteed Savings STAR",
"min_age": 0,
"max_age": 60,
"benefits_multiplier": 1.17,
"income_start": "3rd year",
"income_duration": "15 years",
"payout_freq": "Monthly",
"sad_multiple": "7"
},
6: {
"name": "EdelweissLife Flexi Savings STAR",
"min_age": 18,
"max_age": 65,
"benefits_multiplier": 1.42,
"income_start": "10 years",
"income_duration": "25 years",
"payout_freq": "Yearly",
"sad_multiple": "5"
}
}
# Plan Name to ID Mapping
PLAN_NAME_TO_ID = {
"guaranteed income star": 1,
"bharat savings star": 2,
"premier guaranteed star pro": 3,
"Flexi Dream Plan": 4,
"Flexi Savings STAR": 6,
"Guaranteed Savings STAR": 5
}
def resolve_plan_id(name: str) -> Optional[int]:
"""Resolves a plan name or substring to a Plan ID."""
name_lower = name.lower().strip()
for key, pid in PLAN_NAME_TO_ID.items():
if key in name_lower or name_lower in key:
return pid
return None
def calculate_dummy_benefits(plan_id: int, request: PlanInfoRequest) -> PlanBenefitResponse:
plan = PLANS_DATA.get(plan_id)
if not plan:
return None
is_eligible = plan["min_age"] <= request.age <= plan["max_age"]
reason = "Eligible based on age criteria." if is_eligible else f"Ineligible: Age must be between {plan['min_age']} and {plan['max_age']}"
# Dummy calculation logic influenced by PT/PPT
pt_val = 15
if request.policy_term:
try: pt_val = int(re.search(r'\d+', request.policy_term).group())
except: pass
mult_adj = (pt_val / 15.0) # PT adjustment
randval = random()
if randval < 0.5:
randval = 0.5
maturity_val = request.premium_amount * 10 * (1+randval)* plan["benefits_multiplier"] * mult_adj
income_val = request.premium_amount * (plan["benefits_multiplier"]/0.467)
# Calculate Sum Assured
sad_val = request.premium_amount * float(plan["sad_multiple"])
sum_assured = f"₹{sad_val:,.2f}"
maturity_benefit = f"₹{maturity_val:,.2f}"
annual_income = f"₹{income_val:,.2f}"
benefits = [
BenefitItem(name="Maturity Benefit", value=maturity_benefit, description="Guaranteed lump sum"),
BenefitItem(name="Annual Income Benefit", value=annual_income, description="Regular payouts"),
BenefitItem(name="Sum Assured", value=sum_assured, description="Life Cover"),
BenefitItem(name="Tax Benefit", value="Exempt", description="Sec 80C")
]
return PlanBenefitResponse(
plan_id=plan_id,
plan_name=plan["name"],
eligibility_status=is_eligible,
reason=reason,
maturity_benefit=maturity_benefit,
annual_income=annual_income,
sum_assured=sum_assured,
income_start_point=plan["income_start"],
income_duration=plan["income_duration"],
payout_freq=plan["payout_freq"],
sad_multiple=plan["sad_multiple"],
recommendation_score=0.9 if is_eligible else 0.1,
benefits=benefits
)
@router.get("/calculate", response_model=PlanBenefitResponse)
async def calculate_by_id(
plan_id: int = Query(..., alias="Planid"),
age: int = Query(...),
gender: str = Query(...),
premium_amount: float = Query(...),
goal: str = Query("savings")
):
"""
Calculates benefits for a specific Edelweiss plan using Plan ID.
Uses dummy logic for demonstration.
"""
request = PlanInfoRequest(age=age, gender=gender, premium_amount=premium_amount, goal=goal)
result = calculate_dummy_benefits(plan_id, request)
if not result:
raise HTTPException(status_code=404, detail="Plan not found")
return result
@router.post("/calculate", response_model=List[PlanBenefitResponse])
async def calculate_all_benefits(request: PlanInfoRequest):
"""
Calculates benefits for all Edelweiss Guaranteed Income plans.
"""
if request.plan_id:
result = calculate_dummy_benefits(request.plan_id, request)
if not result:
raise HTTPException(status_code=404, detail="Plan not found")
return [result]
results = []
for pid in PLANS_DATA:
results.append(calculate_dummy_benefits(pid, request))
return results
def get_plan_benefits_tool(age: int, gender: str, premium_amount: float, plan_id: Optional[int] = None,
policy_term: Optional[str] = None, payment_term: Optional[str] = None,
payment_mode: Optional[str] = None) -> str:
"""
Python function to be used as a tool by LangGraph.
Returns a combined string with a Markdown table and JSON.
"""
request = PlanInfoRequest(
age=age,
gender=gender,
premium_amount=premium_amount,
plan_id=plan_id,
policy_term=policy_term,
payment_term=payment_term,
payment_mode=payment_mode
)
data = []
if plan_id:
result = calculate_dummy_benefits(plan_id, request)
if result: data = [result.dict()]
else:
for pid in PLANS_DATA:
data.append(calculate_dummy_benefits(pid, request).dict())
if not data:
return "No plans found or ineligible."
# Create a nice Markdown Table for the LLM
table = "| Plan Name | Income Start | Duration | SAD Multi | Sum Assured | Maturity Benefit | Annual Income |\n"
table += "| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n"
for d in data:
table += f"| {d['plan_name']} | {d['income_start_point']} | {d['income_duration']} | {d['sad_multiple']} | {d['sum_assured']} | {d['maturity_benefit']} | {d['annual_income']} |\n"
output = {
"summary_table": table,
"raw_data": data
}
return json.dumps(output, indent=2)
|