Insurance-RAG / api /plans.py
DeltaVenom's picture
Update app code and initialize runtime databases
72bff80
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)