sammy786 commited on
Commit
36b34e0
·
verified ·
1 Parent(s): 516797e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +234 -9
app.py CHANGED
@@ -188,7 +188,7 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
188
 
189
  print(f"🔍 KEYS: {list(result.keys())}")
190
 
191
- # FIX: Data is at top level, not nested
192
  card_id = result.get('recommended_card', 'Unknown')
193
  rewards_earned = float(result.get('rewards_earned', 0))
194
  rewards_rate = result.get('rewards_rate', 'N/A')
@@ -207,8 +207,183 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
207
  }
208
  card_name = card_name_map.get(card_id, card_id.replace('c_', '').replace('_', ' ').title())
209
 
 
 
 
 
 
 
 
 
210
  print(f"✅ PARSED: {card_name}, ${rewards_earned}, {rewards_rate}, {confidence}")
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  output = f"""## 🤖 AI Agent Recommendation
213
 
214
  ### 💳 Recommended Card: **{card_name}**
@@ -225,6 +400,7 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
225
  ---
226
  """
227
 
 
228
  if alternatives:
229
  output += "\n### 🔄 Alternative Options:\n\n"
230
  for alt in alternatives[:3]:
@@ -233,25 +409,74 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
233
  alt_reason = alt.get('reason', '')
234
  output += f"**{alt_card_name}:**\n{alt_reason}\n\n"
235
 
 
236
  if warnings:
237
  output += "\n### ⚠️ Important Warnings:\n\n"
238
  for warning in warnings:
239
  output += f"- {warning}\n"
240
 
 
241
  if annual_impact:
242
- potential_savings = annual_impact.get('potential_savings', 0)
243
- optimization_score = annual_impact.get('optimization_score', 0)
244
- output += f"\n### 💰 Annual Impact:\n"
245
- output += f"- **Potential Savings:** ${potential_savings:.2f}/year\n"
246
- output += f"- **Optimization Score:** {optimization_score}/100\n"
247
-
248
- output += f"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  ---
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  ### 📊 Transaction Details:
252
- - **Amount:** ${amount:.2f}
 
253
  - **Merchant:** {merchant}
254
  - **Category:** {category}
 
255
  """
256
 
257
  chart = create_agent_recommendation_chart_enhanced(result)
 
188
 
189
  print(f"🔍 KEYS: {list(result.keys())}")
190
 
191
+ # Extract data
192
  card_id = result.get('recommended_card', 'Unknown')
193
  rewards_earned = float(result.get('rewards_earned', 0))
194
  rewards_rate = result.get('rewards_rate', 'N/A')
 
207
  }
208
  card_name = card_name_map.get(card_id, card_id.replace('c_', '').replace('_', ' ').title())
209
 
210
+ # Extract card-specific details from API
211
+ card_details = result.get('card_details', {})
212
+ reward_rate_value = card_details.get('reward_rate', 0) # e.g., 5 for 5%
213
+ monthly_cap = card_details.get('monthly_cap', None) # e.g., 500
214
+ annual_cap = card_details.get('annual_cap', None)
215
+ base_rate = card_details.get('base_rate', 1) # Fallback rate after cap
216
+ annual_fee = card_details.get('annual_fee', 0)
217
+
218
  print(f"✅ PARSED: {card_name}, ${rewards_earned}, {rewards_rate}, {confidence}")
219
 
220
+ # ========== DYNAMIC CALCULATION ==========
221
+
222
+ # Get actual potential savings and score from API
223
+ potential_savings = annual_impact.get('potential_savings', 0)
224
+ optimization_score = annual_impact.get('optimization_score', 0)
225
+
226
+ # Calculate annual projection dynamically
227
+ amount_float = float(amount)
228
+
229
+ # Determine frequency assumption (you can make this smarter based on category)
230
+ frequency_map = {
231
+ 'Groceries': 52, # Weekly
232
+ 'Restaurants': 52, # Weekly
233
+ 'Gas Stations': 52, # Weekly
234
+ 'Fast Food': 52, # Weekly
235
+ 'Airlines': 4, # Quarterly
236
+ 'Hotels': 12, # Monthly
237
+ 'Online Shopping': 24, # Bi-weekly
238
+ 'Entertainment': 24, # Bi-weekly
239
+ }
240
+ frequency = frequency_map.get(category, 26) # Default: bi-weekly
241
+ frequency_label = {
242
+ 52: 'weekly',
243
+ 26: 'bi-weekly',
244
+ 24: 'bi-weekly',
245
+ 12: 'monthly',
246
+ 4: 'quarterly'
247
+ }.get(frequency, f'{frequency}x per year')
248
+
249
+ annual_spend = amount_float * frequency
250
+
251
+ # Calculate rewards based on card structure
252
+ if monthly_cap:
253
+ # Card has monthly cap (e.g., Citi Custom Cash: $500/month at 5%)
254
+ monthly_cap_annual = monthly_cap * 12
255
+
256
+ if annual_spend <= monthly_cap_annual:
257
+ # All spending is within cap
258
+ high_rate_spend = annual_spend
259
+ low_rate_spend = 0
260
+ else:
261
+ # Some spending exceeds cap
262
+ high_rate_spend = monthly_cap_annual
263
+ low_rate_spend = annual_spend - monthly_cap_annual
264
+
265
+ high_rate_rewards = high_rate_spend * (reward_rate_value / 100)
266
+ low_rate_rewards = low_rate_spend * (base_rate / 100)
267
+ total_rewards = high_rate_rewards + low_rate_rewards
268
+
269
+ # Baseline comparison (1% card)
270
+ baseline_rewards = annual_spend * 0.01
271
+ net_benefit = total_rewards - baseline_rewards - annual_fee
272
+
273
+ # Build calculation table
274
+ calc_table = f"""
275
+ | Spending Tier | Annual Amount | Rate | Rewards |
276
+ |---------------|---------------|------|---------|
277
+ | First ${monthly_cap}/month | ${high_rate_spend:.2f} | {reward_rate_value}% | ${high_rate_rewards:.2f} |
278
+ | Remaining spend | ${low_rate_spend:.2f} | {base_rate}% | ${low_rate_rewards:.2f} |
279
+ | **Subtotal** | **${annual_spend:.2f}** | - | **${total_rewards:.2f}** |
280
+ | Annual fee | - | - | -${annual_fee:.2f} |
281
+ | **Net Rewards** | - | - | **${total_rewards - annual_fee:.2f}** |
282
+ """
283
+
284
+ comparison_text = f"""
285
+ **With {card_name}:**
286
+ - High rate earnings: ${high_rate_rewards:.2f}
287
+ - Base rate earnings: ${low_rate_rewards:.2f}
288
+ - Annual fee: -${annual_fee:.2f}
289
+ - **Net total: ${total_rewards - annual_fee:.2f}/year**
290
+
291
+ **With Baseline 1% Card:**
292
+ - All spending at 1%: ${baseline_rewards:.2f}/year
293
+
294
+ **Net Benefit: ${net_benefit:.2f}/year**
295
+ """
296
+
297
+ elif annual_cap:
298
+ # Card has annual cap (e.g., Amex Gold: $25,000/year at 4x)
299
+ if annual_spend <= annual_cap:
300
+ high_rate_spend = annual_spend
301
+ low_rate_spend = 0
302
+ else:
303
+ high_rate_spend = annual_cap
304
+ low_rate_spend = annual_spend - annual_cap
305
+
306
+ high_rate_rewards = high_rate_spend * (reward_rate_value / 100)
307
+ low_rate_rewards = low_rate_spend * (base_rate / 100)
308
+ total_rewards = high_rate_rewards + low_rate_rewards
309
+
310
+ baseline_rewards = annual_spend * 0.01
311
+ net_benefit = total_rewards - baseline_rewards - annual_fee
312
+
313
+ calc_table = f"""
314
+ | Spending Tier | Annual Amount | Rate | Rewards |
315
+ |---------------|---------------|------|---------|
316
+ | Up to ${annual_cap:,.0f}/year | ${high_rate_spend:.2f} | {reward_rate_value}% | ${high_rate_rewards:.2f} |
317
+ | Above cap | ${low_rate_spend:.2f} | {base_rate}% | ${low_rate_rewards:.2f} |
318
+ | **Subtotal** | **${annual_spend:.2f}** | - | **${total_rewards:.2f}** |
319
+ | Annual fee | - | - | -${annual_fee:.2f} |
320
+ | **Net Rewards** | - | - | **${total_rewards - annual_fee:.2f}** |
321
+ """
322
+
323
+ comparison_text = f"""
324
+ **With {card_name}:**
325
+ - High rate earnings: ${high_rate_rewards:.2f}
326
+ - Base rate earnings: ${low_rate_rewards:.2f}
327
+ - Annual fee: -${annual_fee:.2f}
328
+ - **Net total: ${total_rewards - annual_fee:.2f}/year**
329
+
330
+ **With Baseline 1% Card:**
331
+ - All spending at 1%: ${baseline_rewards:.2f}/year
332
+
333
+ **Net Benefit: ${net_benefit:.2f}/year**
334
+ """
335
+
336
+ else:
337
+ # No cap - flat rate on all spending
338
+ total_rewards = annual_spend * (reward_rate_value / 100)
339
+ baseline_rewards = annual_spend * 0.01
340
+ net_benefit = total_rewards - baseline_rewards - annual_fee
341
+
342
+ calc_table = f"""
343
+ | Spending Tier | Annual Amount | Rate | Rewards |
344
+ |---------------|---------------|------|---------|
345
+ | All spending | ${annual_spend:.2f} | {reward_rate_value}% | ${total_rewards:.2f} |
346
+ | Annual fee | - | - | -${annual_fee:.2f} |
347
+ | **Net Rewards** | - | - | **${total_rewards - annual_fee:.2f}** |
348
+ """
349
+
350
+ comparison_text = f"""
351
+ **With {card_name}:**
352
+ - Earnings at {reward_rate_value}%: ${total_rewards:.2f}
353
+ - Annual fee: -${annual_fee:.2f}
354
+ - **Net total: ${total_rewards - annual_fee:.2f}/year**
355
+
356
+ **With Baseline 1% Card:**
357
+ - All spending at 1%: ${baseline_rewards:.2f}/year
358
+
359
+ **Net Benefit: ${net_benefit:.2f}/year**
360
+ """
361
+
362
+ # Dynamic optimization score breakdown
363
+ score_breakdown = annual_impact.get('score_breakdown', {})
364
+ if not score_breakdown:
365
+ # Generate based on optimization_score
366
+ score_breakdown = {
367
+ 'reward_rate': min(30, int(optimization_score * 0.3)),
368
+ 'cap_availability': min(25, int(optimization_score * 0.25)),
369
+ 'annual_fee': min(20, int(optimization_score * 0.2)),
370
+ 'category_match': min(20, int(optimization_score * 0.2)),
371
+ 'penalties': max(-5, int((optimization_score - 100) * 0.05))
372
+ }
373
+
374
+ score_details = f"""
375
+ **Score Components:**
376
+ - {"✅" if score_breakdown.get('reward_rate', 0) > 20 else "⚠️"} Reward rate: **+{score_breakdown.get('reward_rate', 0)} points**
377
+ - {"✅" if score_breakdown.get('cap_availability', 0) > 15 else "⚠️"} Cap availability: **+{score_breakdown.get('cap_availability', 0)} points**
378
+ - {"✅" if score_breakdown.get('annual_fee', 0) > 15 else "⚠️"} Annual fee value: **+{score_breakdown.get('annual_fee', 0)} points**
379
+ - {"✅" if score_breakdown.get('category_match', 0) > 15 else "⚠️"} Category match: **+{score_breakdown.get('category_match', 0)} points**
380
+ - {"⚠️" if score_breakdown.get('penalties', 0) < 0 else "✅"} Limitations: **{score_breakdown.get('penalties', 0)} points**
381
+
382
+ **Total: {optimization_score}/100**
383
+ """
384
+
385
+ # ========== FORMAT OUTPUT ==========
386
+
387
  output = f"""## 🤖 AI Agent Recommendation
388
 
389
  ### 💳 Recommended Card: **{card_name}**
 
400
  ---
401
  """
402
 
403
+ # Add alternatives
404
  if alternatives:
405
  output += "\n### 🔄 Alternative Options:\n\n"
406
  for alt in alternatives[:3]:
 
409
  alt_reason = alt.get('reason', '')
410
  output += f"**{alt_card_name}:**\n{alt_reason}\n\n"
411
 
412
+ # Add warnings
413
  if warnings:
414
  output += "\n### ⚠️ Important Warnings:\n\n"
415
  for warning in warnings:
416
  output += f"- {warning}\n"
417
 
418
+ # Add dynamic annual impact
419
  if annual_impact:
420
+ output += f"""
421
+ ### 💰 Annual Impact
422
+
423
+ - **Potential Savings:** ${potential_savings:.2f}/year
424
+ - **Optimization Score:** {optimization_score}/100
425
+
426
+ <details>
427
+ <summary>📊 <b>How is this calculated?</b> (Click to expand)</summary>
428
+
429
+ #### 💡 Calculation Assumptions:
430
+
431
+ **Step 1: Estimate Annual Spending**
432
+
433
+ Current transaction: amountfloat:.2fatmerchantCategory:categoryFrequencyassumption:frequencylabel.capitalize()Annualestimate:{amount_float:.2f} at {merchant}
434
+ Category: {category}
435
+ Frequency assumption: {frequency_label.capitalize()}
436
+ Annual estimate: amountf​loat:.2fatmerchantCategory:categoryFrequencyassumption:frequencyl​abel.capitalize()Annualestimate:{amount_float:.2f} × {frequency} = ${annual_spend:.2f}
437
+ **Step 2: Calculate Rewards with {card_name}**
438
+
439
+ {calc_table}
440
+
441
+ **Step 3: Compare to Baseline**
442
+
443
+ {comparison_text}
444
+
445
+ ---
446
+
447
+ #### 📈 Optimization Score: {optimization_score}/100
448
+
449
+ {score_details}
450
+
451
+ **Score Ranges:**
452
+ - 90-100: Optimal choice ✅
453
+ - 80-89: Great choice 👍
454
+ - 70-79: Good choice 👌
455
+ - 60-69: Acceptable ⚠️
456
+ - <60: Suboptimal ❌
457
+
458
  ---
459
 
460
+ #### 🔍 Card Details:
461
+ - **Reward Rate:** {reward_rate_value}% on {category}
462
+ - **Monthly Cap:** {"$" + str(monthly_cap) if monthly_cap else "None"}
463
+ - **Annual Cap:** {"$" + str(annual_cap) if annual_cap else "None"}
464
+ - **Base Rate:** {base_rate}% (after cap)
465
+ - **Annual Fee:** ${annual_fee}
466
+
467
+ </details>
468
+
469
+ ---
470
+ """
471
+
472
+ # Add transaction details
473
+ output += f"""
474
  ### 📊 Transaction Details:
475
+
476
+ - **Amount:** ${amount_float:.2f}
477
  - **Merchant:** {merchant}
478
  - **Category:** {category}
479
+ - **MCC Code:** {transaction['mcc']}
480
  """
481
 
482
  chart = create_agent_recommendation_chart_enhanced(result)