Skip to content

Commit f9fcfe5

Browse files
committed
fixed inconsistencies
1 parent f5c2b6c commit f9fcfe5

16 files changed

Lines changed: 1032 additions & 95 deletions

File tree

app.py

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -852,24 +852,59 @@ def extract_insurance_hybrid(text):
852852
if key not in data:
853853
data[key] = "N/A"
854854

855+
# Helper to convert Lakhs/Crores to actual numbers
856+
def _parse_indian_amount(num_str, suffix_str=""):
857+
"""Convert amount with optional Lakhs/Crore suffix to actual number."""
858+
try:
859+
base_val = clean_and_convert_to_float(num_str)
860+
if base_val is None:
861+
return None
862+
suffix_lower = suffix_str.lower().strip() if suffix_str else ""
863+
if suffix_lower in ("lakh", "lakhs", "lac", "lacs"):
864+
return base_val * 100000
865+
elif suffix_lower in ("crore", "crores", "cr"):
866+
return base_val * 10000000
867+
return base_val
868+
except Exception:
869+
return None
870+
871+
# Patterns that capture amount AND optional Lakhs/Crore suffix
872+
# Priority order: Annual Sum Insured (most specific for health) > Sum Insured/Assured > Cover Amount
855873
sum_patterns = (
856874
[
857-
r"(?i)Sum\s*(?:Assured|Insured)[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+)",
858-
r"(?i)Life\s*Cover[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+)",
859-
r"(?i)Death\s*Benefit[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+)"
875+
r"(?i)Sum\s*(?:Assured|Insured)[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+(?:\.\d+)?)\s*(Lakhs?|Lacs?|Crores?|Cr)?",
876+
r"(?i)Life\s*Cover[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+(?:\.\d+)?)\s*(Lakhs?|Lacs?|Crores?|Cr)?",
877+
r"(?i)Death\s*Benefit[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+(?:\.\d+)?)\s*(Lakhs?|Lacs?|Crores?|Cr)?"
860878
] if is_life_insurance else [
861-
r"(?i)Sum\s*(?:Insured|Assured)[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+)",
862-
r"(?i)Cover(?:age)?\s*Amount[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+)",
863-
r"(?i)Policy\s*Coverage[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+)"
879+
# Highest priority: "Annual Sum Insured" - this is the actual policy value
880+
r"(?i)Annual\s+Sum\s+Insured[\s:\-\|]*(?:Rs\.?|₹)?\s*([\d,]+(?:\.\d+)?)\s*(Lakhs?|Lacs?|Crores?|Cr)?",
881+
# Next: general Sum Insured/Assured patterns
882+
r"(?i)Sum\s*(?:Insured|Assured)[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+(?:\.\d+)?)\s*(Lakhs?|Lacs?|Crores?|Cr)?",
883+
r"(?i)Cover(?:age)?\s*Amount[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+(?:\.\d+)?)\s*(Lakhs?|Lacs?|Crores?|Cr)?",
884+
r"(?i)Policy\s*Coverage[\s:\-]*(?:Rs\.?|₹)?\s*([\d,]+(?:\.\d+)?)\s*(Lakhs?|Lacs?|Crores?|Cr)?"
864885
]
865886
)
866887

888+
# Try patterns in priority order; for general patterns, find all matches and pick the largest
889+
sum_value = None
867890
for pattern in sum_patterns:
868-
match = re.search(pattern, text, re.IGNORECASE)
869-
if match:
870-
data["sum_assured_or_insured"] = clean_and_convert_to_float(match.group(1))
871-
break
872-
if "sum_assured_or_insured" not in data:
891+
matches = list(re.finditer(pattern, text, re.IGNORECASE))
892+
if matches:
893+
# Parse all matches and pick the largest value (to avoid partial matches like "₹5 Lakhs" from descriptions)
894+
best_val = None
895+
for m in matches:
896+
num_part = m.group(1) if m.lastindex >= 1 else None
897+
suffix_part = m.group(2) if m.lastindex >= 2 else ""
898+
parsed = _parse_indian_amount(num_part, suffix_part)
899+
if parsed is not None and (best_val is None or parsed > best_val):
900+
best_val = parsed
901+
if best_val is not None:
902+
sum_value = best_val
903+
break
904+
905+
if sum_value is not None:
906+
data["sum_assured_or_insured"] = sum_value
907+
else:
873908
data["sum_assured_or_insured"] = "N/A"
874909

875910
premium_patterns = [
@@ -3996,9 +4031,15 @@ def generate_financial_plan_pdf(q: dict, analysis: dict, output_path: str, doc_i
39964031
term_gap = max(0, required_term_cover - life_cover)
39974032
health_gap = max(0, required_health_cover - health_cover)
39984033

3999-
# Estimate monthly premiums (rough estimates)
4000-
term_premium_yearly = (term_gap / 100000) * 700 if term_gap > 0 else 0 # ~Rs.700/lakh/year
4001-
health_premium_yearly = (health_gap / 100000) * 3000 if health_gap > 0 else 0 # ~Rs.3000/lakh/year
4034+
# Use age-adjusted premium rates (matching llm_sections.py PriorityAllocationEngine)
4035+
# Term insurance: Rs. 500/lakh (age < 35), Rs. 700/lakh (age < 45), Rs. 1200/lakh (age >= 45)
4036+
# Health insurance: Rs. 2500/lakh (age < 35), Rs. 3500/lakh (age < 45), Rs. 5000/lakh (age >= 45)
4037+
client_age = _safe_float(age, 35) # Default to 35 if age not available
4038+
term_rate_per_lakh = 500 if client_age < 35 else (700 if client_age < 45 else 1200)
4039+
health_rate_per_lakh = 2500 if client_age < 35 else (3500 if client_age < 45 else 5000)
4040+
4041+
term_premium_yearly = (term_gap / 100000) * term_rate_per_lakh if term_gap > 0 else 0
4042+
health_premium_yearly = (health_gap / 100000) * health_rate_per_lakh if health_gap > 0 else 0
40024043
total_insurance_yearly = term_premium_yearly + health_premium_yearly
40034044
monthly_insurance_equivalent = total_insurance_yearly / 12
40044045

0 commit comments

Comments
 (0)