import { FMResult } from '../types' export interface AnnualKPI { year: number mrr: number arr: number customers: number arpu: number employees: number revenuePerEmployee: number personnelCosts: number totalRevenue: number totalCosts: number ebit: number ebitMargin: number taxes: number netIncome: number serverCostPerCustomer: number grossMargin: number burnRate: number runway: number | null cashBalance: number } const TAX_RATE = 0.30 // ~30% Körperschaftsteuer + Gewerbesteuer + Soli /** * Aggregates 60 monthly FMResult entries into 5 annual KPI rows (2026–2030). * All values are derived — nothing is hardcoded. */ export function computeAnnualKPIs(results: FMResult[]): AnnualKPI[] { if (!results || results.length === 0) return [] const years = [2026, 2027, 2028, 2029, 2030] return years.map(year => { const yearResults = results.filter(r => r.year === year) if (yearResults.length === 0) { return emptyKPI(year) } const dec = yearResults[yearResults.length - 1] // December snapshot const totalRevenue = yearResults.reduce((s, r) => s + r.revenue_eur, 0) const personnelCosts = yearResults.reduce((s, r) => s + r.personnel_eur, 0) const totalCogs = yearResults.reduce((s, r) => s + r.cogs_eur, 0) const totalInfra = yearResults.reduce((s, r) => s + r.infra_eur, 0) const totalMarketing = yearResults.reduce((s, r) => s + r.marketing_eur, 0) const totalCosts = yearResults.reduce((s, r) => s + r.total_costs_eur, 0) const ebit = totalRevenue - totalCosts const ebitMargin = totalRevenue > 0 ? (ebit / totalRevenue) * 100 : 0 const taxes = ebit > 0 ? Math.round(ebit * TAX_RATE) : 0 const netIncome = ebit - taxes const serverCost = dec.total_customers > 0 ? Math.round((totalInfra / 12) / dec.total_customers) : 0 return { year, mrr: Math.round(dec.mrr_eur), arr: Math.round(dec.arr_eur), customers: Math.round(dec.total_customers), arpu: dec.total_customers > 0 ? Math.round(dec.mrr_eur / dec.total_customers) : 0, employees: Math.round(dec.employees_count), revenuePerEmployee: dec.employees_count > 0 ? Math.round(totalRevenue / dec.employees_count) : 0, personnelCosts: Math.round(personnelCosts), totalRevenue: Math.round(totalRevenue), totalCosts: Math.round(totalCosts), ebit: Math.round(ebit), ebitMargin: Math.round(ebitMargin), taxes, netIncome: Math.round(netIncome), serverCostPerCustomer: serverCost, grossMargin: Math.round(dec.gross_margin_pct), burnRate: Math.round(dec.burn_rate_eur), runway: dec.runway_months > 999 ? null : Math.round(dec.runway_months), cashBalance: Math.round(dec.cash_balance_eur), } }) } function emptyKPI(year: number): AnnualKPI { return { year, mrr: 0, arr: 0, customers: 0, arpu: 0, employees: 0, revenuePerEmployee: 0, personnelCosts: 0, totalRevenue: 0, totalCosts: 0, ebit: 0, ebitMargin: 0, taxes: 0, netIncome: 0, serverCostPerCustomer: 0, grossMargin: 0, burnRate: 0, runway: null, cashBalance: 0, } }