Spaces:
Running
Running
| 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 | |
| ) | |
| 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 | |
| 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) | |