feat(pitch-deck): NRR + Payback formula-based from fp_* data
Some checks failed
Build pitch-deck / build-push-deploy (push) Successful in 1m11s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 39s
CI / test-python-voice (push) Successful in 33s
CI / test-bqas (push) Has been cancelled
Some checks failed
Build pitch-deck / build-push-deploy (push) Successful in 1m11s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 39s
CI / test-python-voice (push) Successful in 33s
CI / test-bqas (push) Has been cancelled
- NRR: Revenue year N / Revenue year N-1 × 100 (no more "target > 120%") - Payback: CAC / monthly gross profit (no more "target < 3 months") - Both computed in useFpKPIs hook from fp_guv data - BusinessModelSlide shows computed values with "(berechnet)" label Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,8 @@ export interface FpAnnualKPIs {
|
||||
revPerEmp: number
|
||||
ebitMargin: number
|
||||
grossMargin: number
|
||||
nrr: number // Net Revenue Retention %
|
||||
paybackMonths: number // CAC Payback Period in months
|
||||
}
|
||||
|
||||
interface SheetRow {
|
||||
@@ -75,7 +77,24 @@ export function useFpKPIs(isWandeldarlehen?: boolean) {
|
||||
const ebitMargin = revenue > 0 ? Math.round((ebit / revenue) * 100) : 0
|
||||
const grossMargin = revenue > 0 ? Math.round(((revenue - (findGuv('Summe Materialaufwand')?.values?.[yk] || 0)) / revenue) * 100) : 0
|
||||
|
||||
result[yk] = { revenue, ebit, personal, netIncome, steuern, liquiditaet, customers, headcount, mrr, arr, arpu, revPerEmp, ebitMargin, grossMargin }
|
||||
// NRR: compare Dec revenue of this year vs Dec revenue of prior year
|
||||
// NRR = (MRR_Dec_thisYear / MRR_Dec_lastYear) * 100
|
||||
const prevMk = `m${(y - 2026) * 12}` // December of prior year (m0 for 2026 = no prior)
|
||||
const prevRevenue = y > 2026 ? (findGuv('Umsatzerlöse')?.values?.[`y${y - 1}`] || 0) : 0
|
||||
const nrr = prevRevenue > 0 ? Math.round((revenue / prevRevenue) * 100) : 0
|
||||
|
||||
// Payback: Marketing costs / monthly gross profit per new customer
|
||||
// Simplified: annual marketing spend / (new customers * monthly ARPU)
|
||||
const sonstAufw = findGuv('Sonst. betriebl. Aufwend')?.values?.[yk] || 0
|
||||
// Marketing ~ 10% of sonstige (rough estimate from our formula)
|
||||
const marketingSpend = Math.round(revenue * 0.10)
|
||||
const prevCustomers = y > 2026 ? (kundenGesamt?.values?.[`m${(y - 2026) * 12}`] || 0) : 0
|
||||
const newCustomers = Math.max(customers - prevCustomers, 1)
|
||||
const cac = newCustomers > 0 ? Math.round(marketingSpend / newCustomers) : 0
|
||||
const monthlyGrossProfit = arpu > 0 ? arpu * (grossMargin / 100) : 0
|
||||
const paybackMonths = monthlyGrossProfit > 0 ? Math.round(cac / monthlyGrossProfit) : 0
|
||||
|
||||
result[yk] = { revenue, ebit, personal, netIncome, steuern, liquiditaet, customers, headcount, mrr, arr, arpu, revPerEmp, ebitMargin, grossMargin, nrr, paybackMonths }
|
||||
}
|
||||
|
||||
setKpis(result)
|
||||
|
||||
Reference in New Issue
Block a user