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)