stepolan commited on
Commit
75ecc2d
Β·
1 Parent(s): 9c022b0

Add scenario detail view with full plan config, save commission tiers in scenario data

Browse files
Files changed (1) hide show
  1. app.py +88 -0
app.py CHANGED
@@ -457,6 +457,9 @@ if active_tab == "scenario":
457
  "draw_months": int(draw_months), "draw_recoverable": draw_recoverable,
458
  "ramp_pcts": ramp_pcts, "cogs_pct": cogs_pct,
459
  "other_cost_per_rep": other_cost_per_rep,
 
 
 
460
  },
461
  "inputs": {
462
  "months_employed": months_employed,
@@ -607,5 +610,90 @@ if active_tab == "compare":
607
  fig.update_layout(barmode="group", height=400,
608
  margin=dict(l=0, r=0, t=30, b=0))
609
  st.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
610
  else:
611
  st.info("No saved scenarios yet. Save one from the Scenario Calculator tab.")
 
457
  "draw_months": int(draw_months), "draw_recoverable": draw_recoverable,
458
  "ramp_pcts": ramp_pcts, "cogs_pct": cogs_pct,
459
  "other_cost_per_rep": other_cost_per_rep,
460
+ "commission_tiers": att_tiers if commission_mode == "Attainment-based rates" else None,
461
+ "deal_rate_tiers": deal_rate_tiers if commission_mode != "Attainment-based rates" else None,
462
+ "accel_tiers": accel_tiers if commission_mode != "Attainment-based rates" else None,
463
  },
464
  "inputs": {
465
  "months_employed": months_employed,
 
610
  fig.update_layout(barmode="group", height=400,
611
  margin=dict(l=0, r=0, t=30, b=0))
612
  st.plotly_chart(fig, use_container_width=True)
613
+
614
+ # --- Scenario detail view ---
615
+ st.divider()
616
+ st.markdown("**Scenario Details**")
617
+ st.caption("Click a scenario to see its full plan configuration.")
618
+ detail_name = st.selectbox("View details for", [""] + selected, key="detail_sel")
619
+ if detail_name and detail_name in scenarios:
620
+ s = scenarios[detail_name]
621
+ p = s.get("params", {})
622
+ inp = s.get("inputs", {})
623
+ r = s.get("results", {})
624
+
625
+ dc1, dc2 = st.columns(2)
626
+ with dc1:
627
+ st.markdown(f"**{detail_name}**")
628
+ st.markdown(f"- **Author:** {s.get('author', 'β€”')}")
629
+ st.markdown(f"- **Commission Model:** {s.get('commission_mode', 'β€”')}")
630
+ st.markdown(f"- **Base Salary:** ${p.get('base_salary', 0):,.0f}")
631
+ st.markdown(f"- **Annual Quota:** ${p.get('annual_quota', 0):,.0f}")
632
+ st.markdown(f"- **Effective Quota:** ${r.get('effective_quota', 0):,.0f}")
633
+
634
+ draw_amt = p.get("draw_amount", 0)
635
+ if draw_amt > 0:
636
+ rec = "Recoverable" if p.get("draw_recoverable", False) else "Non-recoverable"
637
+ st.markdown(f"- **Draw:** ${draw_amt:,.0f} over {p.get('draw_months', 0)} months ({rec})")
638
+ else:
639
+ st.markdown("- **Draw:** None")
640
+
641
+ ramp = p.get("ramp_pcts", [])
642
+ if ramp:
643
+ ramp_str = " β†’ ".join(f"{int(r)}%" for r in ramp) + " β†’ 100%"
644
+ st.markdown(f"- **Ramp:** {len(ramp)} months ({ramp_str})")
645
+ else:
646
+ st.markdown("- **Ramp:** None (full quota from month 1)")
647
+
648
+ with dc2:
649
+ # Commission tiers
650
+ comm_tiers = p.get("commission_tiers")
651
+ deal_tiers = p.get("deal_rate_tiers")
652
+ accel_t = p.get("accel_tiers")
653
+
654
+ if comm_tiers:
655
+ st.markdown("**Commission Tiers (attainment-based)**")
656
+ for i, tier in enumerate(comm_tiers):
657
+ upper, rate = tier[0], tier[1]
658
+ if upper is None:
659
+ st.markdown(f"- Above prior: **{rate}%**")
660
+ elif i == 0:
661
+ st.markdown(f"- 0–{int(upper)}%: **{rate}%**")
662
+ else:
663
+ prev_upper = int(comm_tiers[i-1][0])
664
+ st.markdown(f"- {prev_upper}–{int(upper)}%: **{rate}%**")
665
+ elif deal_tiers:
666
+ st.markdown("**Deal-Size Commission Rates**")
667
+ for tier in deal_tiers:
668
+ mn, mx, rt = tier[0], tier[1], tier[2]
669
+ if mx is None:
670
+ st.markdown(f"- ${mn:,.0f}+: **{rt}%**")
671
+ else:
672
+ st.markdown(f"- ${mn:,.0f}–${mx:,.0f}: **{rt}%**")
673
+ if accel_t:
674
+ st.markdown("**Accelerators**")
675
+ for i, tier in enumerate(accel_t):
676
+ upper, mult = tier[0], tier[1]
677
+ if upper is None:
678
+ st.markdown(f"- Above prior: **{mult}x**")
679
+ elif i == 0:
680
+ st.markdown(f"- 0–{int(upper)}%: **{mult}x**")
681
+ else:
682
+ prev_upper = int(accel_t[i-1][0])
683
+ st.markdown(f"- {prev_upper}–{int(upper)}%: **{mult}x**")
684
+
685
+ st.markdown("**Results**")
686
+ st.markdown(f"- **Revenue:** ${inp.get('actual_revenue', 0):,.0f}")
687
+ st.markdown(f"- **Attainment:** {r.get('attainment_pct', 0)}%")
688
+ st.markdown(f"- **Commission:** ${r.get('commission', 0):,.0f}")
689
+ st.markdown(f"- **Total Variable:** ${r.get('total_variable', 0):,.0f}")
690
+ st.markdown(f"- **Total Comp:** ${r.get('total_comp', 0):,.0f}")
691
+
692
+ st.markdown("**Company Side**")
693
+ st.markdown(f"- **COGS:** {p.get('cogs_pct', 0)}%")
694
+ st.markdown(f"- **Other Cost/Rep:** ${p.get('other_cost_per_rep', 0):,.0f}/yr")
695
+ st.markdown(f"- **Gross Profit:** ${r.get('gross_profit', 0):,.0f}")
696
+ st.markdown(f"- **Net After Rep:** ${r.get('net_after_rep', 0):,.0f}")
697
+ st.markdown(f"- **ROI:** {r.get('roi_on_rep', 0):.1f}x")
698
  else:
699
  st.info("No saved scenarios yet. Save one from the Scenario Calculator tab.")