// FinanzplanSlide helpers — extracted from FinanzplanSlide.tsx export interface SheetMeta { name: string label_de: string label_en: string rows: number } export interface SheetRow { id: number row_label?: string person_name?: string item_name?: string category?: string section?: string is_editable?: boolean is_sum_row?: boolean values?: Record values_total?: Record values_brutto?: Record brutto_monthly?: number position?: string start_date?: string purchase_amount?: number [key: string]: unknown } export interface FpScenario { id: string name: string is_default: boolean } export const MONTH_LABELS = [ 'Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez', ] export const MONTH_LABELS_EN = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ] export function getLabel(row: SheetRow): string { return row.row_label || row.person_name || row.item_name || '—' } // German → English row label translations export const ROW_LABEL_MAP: Record = { // GuV / P&L 'Umsatzerlöse': 'Revenue', 'Materialaufwand': 'Cost of Materials', 'Material-/Wareneinsatz': 'Materials / COGS', 'Fremdleistungen': 'External Services', 'Rohertrag': 'Gross Profit', 'Rohergebnis': 'Gross Result', 'Gesamtleistung': 'Total Output', 'Personalkosten': 'Personnel Costs', 'Abschreibungen': 'Depreciation', 'Betriebliche Aufwendungen': 'Operating Expenses', 'Sonstige betriebliche Aufwendungen': 'Other Operating Expenses', 'EBIT': 'EBIT', 'Betriebsergebnis': 'Operating Result', 'Zinsergebnis': 'Net Interest', 'Zinsaufwand': 'Interest Expense', 'Zinsertrag': 'Interest Income', 'Ergebnis vor Steuern': 'Earnings Before Tax', 'EBT': 'EBT', 'Gewerbesteuer': 'Trade Tax', 'Körperschaftsteuer': 'Corporate Tax', 'Steuern gesamt': 'Total Taxes', 'Steuern': 'Taxes', 'Jahresüberschuss': 'Net Income', 'Jahresfehlbetrag': 'Net Loss', 'Ergebnis nach Steuern': 'Net Result', // Liquidität 'Einzahlungen': 'Cash Inflows', 'Summe Einzahlungen': 'Total Inflows', 'Auszahlungen': 'Cash Outflows', 'Summe Auszahlungen': 'Total Outflows', 'Überschuss/Fehlbetrag': 'Surplus / Deficit', 'ÜBERSCHUSS': 'SURPLUS', 'FEHLBETRAG': 'DEFICIT', 'ÜBERSCHUSS/FEHLBETRAG': 'SURPLUS / DEFICIT', 'Kontostand': 'Account Balance', 'Kontostand (Anfang)': 'Opening Balance', 'Kontostand (Ende)': 'Closing Balance', 'LIQUIDITÄT': 'LIQUIDITY', 'LIQUIDITAET': 'LIQUIDITY', 'Kredittilgung': 'Loan Repayment', 'Zins- und Tilgungszahlung': 'Interest & Principal', 'Investitionen': 'Investments', 'Sonstige Erträge': 'Other Income', // Kunden 'Neukunden': 'New Customers', 'Bestandskunden': 'Existing Customers', 'Bestandskunden gesamt': 'Total Existing Customers', 'Anzahl Kunden': 'Customer Count', 'GESAMT': 'TOTAL', 'GESAMTUMSATZ': 'TOTAL REVENUE', // Betriebliche Aufwendungen 'Fort-/Weiterbildungskosten (F)': 'Training & Development (F)', 'Fahrzeugkosten (F)': 'Vehicle Costs (F)', 'KFZ-Steuern (F)': 'Vehicle Tax (F)', 'KFZ-Versicherung (F)': 'Vehicle Insurance (F)', 'Reisekosten (F)': 'Travel Expenses (F)', 'Bewirtungskosten (F)': 'Entertainment Costs (F)', 'Internet/Mobilfunk (F)': 'Internet / Mobile (F)', 'Cloud-Hosting (SysEleven/Hetzner)': 'Cloud Hosting (SysEleven/Hetzner)', 'Berufsgenossenschaft (F)': 'Employers\' Liability Insurance (F)', 'Allgemeine Marketingkosten (F)': 'General Marketing Costs (F)', 'Gewerbesteuer (F)': 'Trade Tax (F)', 'Summe sonstige Aufwendungen': 'Total Other Expenses', 'SUMME Betriebliche Aufwendungen': 'TOTAL Operating Expenses', 'SUMME': 'TOTAL', 'Summe': 'Total', } export const FORMULA_TOOLTIPS: Record = { 'Fort-/Weiterbildungskosten (F)': 'Mitarbeiter (ohne Gründer) × 300 EUR/Mon', 'Fahrzeugkosten (F)': 'Mitarbeiter (ohne Gründer) × 200 EUR/Mon', 'KFZ-Steuern (F)': 'Mitarbeiter (ohne Gründer) × 25 EUR/Mon', 'KFZ-Versicherung (F)': 'Mitarbeiter (ohne Gründer) × 150 EUR/Mon', 'Reisekosten (F)': 'Headcount gesamt × 75 EUR/Mon', 'Bewirtungskosten (F)': 'Bestandskunden × 50 EUR/Mon', 'Internet/Mobilfunk (F)': 'Headcount gesamt × 50 EUR/Mon', 'Cloud-Hosting (SysEleven/Hetzner)': '1.500 EUR Basis + (Kunden - 10) × 100 EUR (erste 10 inkl.)', 'Berufsgenossenschaft (F)': '0,5% der Brutto-Lohnsumme (VBG IT/Büro)', 'Allgemeine Marketingkosten (F)': '8% vom Umsatz (2026-2028), 10% ab 2029', 'Gewerbesteuer (F)': '12,25% vom Gewinn (Messzahl 3,5% × Hebesatz 350%, nur bei Gewinn)', 'Personalkosten': 'Summe aus Tab Personalkosten', 'Abschreibungen': 'Summe AfA aus Tab Investitionen', } export const FORMULA_TOOLTIPS_EN: Record = { 'Fort-/Weiterbildungskosten (F)': 'Employees (excl. founders) × €300/month', 'Fahrzeugkosten (F)': 'Employees (excl. founders) × €200/month', 'KFZ-Steuern (F)': 'Employees (excl. founders) × €25/month', 'KFZ-Versicherung (F)': 'Employees (excl. founders) × €150/month', 'Reisekosten (F)': 'Total headcount × €75/month', 'Bewirtungskosten (F)': 'Existing customers × €50/month', 'Internet/Mobilfunk (F)': 'Total headcount × €50/month', 'Cloud-Hosting (SysEleven/Hetzner)': '€1,500 base + (customers − 10) × €100 (first 10 included)', 'Berufsgenossenschaft (F)': '0.5% of gross payroll (VBG IT/Office)', 'Allgemeine Marketingkosten (F)': '8% of revenue (2026–2028), 10% from 2029', 'Gewerbesteuer (F)': '12.25% of profit (rate 3.5% × multiplier 350%, only when profitable)', 'Personalkosten': 'Sum from Personnel Costs tab', 'Abschreibungen': 'Sum of depreciation from Investments tab', } export function getValues(row: SheetRow): Record { return row.values || row.values_total || row.values_brutto || (row as Record).values_invest as Record || {} } export function formatCell(v: number | undefined): string { if (v === undefined || v === null) return '' if (v === 0) return '—' return Math.round(v).toLocaleString('de-DE', { maximumFractionDigits: 0 }) }