// Forecasting module with 5 tabs const Forecasting = () => { const [tab, setTab] = React.useState('cashflow'); const [scenarioVars, setScenarioVars] = React.useState({ revenues: 0, costs: 0, rates: 3.8 }); const F = window.REGULA_EXT.forecasting; const tabs = [ { id: 'cashflow', label: 'Cash Flow' }, { id: 'bva', label: 'Budget vs Actual' }, { id: 'whatif', label: 'What-If Scenario' }, { id: 'roi', label: 'ROI Simulator' }, { id: 'stress', label: 'Stress Test Covenant' } ]; // Line chart helper const LineChart = ({ data, w = 860, h = 180, label = "M€" }) => { const padL = 28, padR = 12, padT = 12, padB = 24; const cw = w - padL - padR, ch = h - padT - padB; const min = Math.min(...data) * 0.95, max = Math.max(...data) * 1.05; const step = cw / (data.length - 1); const y = v => padT + ch - ((v - min) / (max - min)) * ch; const pts = data.map((v, i) => [padL + i * step, y(v)]); const d = pts.map((p, i) => (i === 0 ? 'M' : 'L') + p[0] + ',' + p[1]).join(' '); const areaD = d + ` L${padL + cw},${padT + ch} L${padL},${padT + ch} Z`; return ( {[min, (min+max)/2, max].map((t, i) => ( {t.toFixed(1)} ))} {pts.map((p, i) => i % 2 === 0 && )} {data.map((v, i) => i % 2 === 0 && ( W{i+1} ))} ); }; return (

Forecasting

Proiezioni AI · rolling 13 settimane · 12 mesi · 3-5 anni
{tabs.map(t => (
setTab(t.id)}>{t.label}
))}
{tab === 'cashflow' && ( <>
Cash flow rolling · 13 settimane
Min 39.6 M€ Max 44.8 M€
Cash in · principali flussi in ingresso
FonteSocietà13w12m
Incassi clienti commercialiMetalTech12.448.6
Ticket parco stagionaliAqua World4.818.6
Incassi serate + barClub Lumière1.66.4
Donazioni + 5×1000Fondazione0.93.8
Totale19.777.4
Cash out · principali flussi in uscita
CategoriaSocietà13w12m
Stipendi e contributiTutte−6.2−24.8
Fornitori materie primeMetalTech−5.4−21.6
Rate mutui e oneri fin.Tutte−2.1−8.0
F24 e imposteTutte−1.8−16.0
Totale−15.5−70.4
)} {tab === 'bva' && (
Scostamenti YTD con proiezione FY
Proiezione automatica
{F.bva.map((row, i) => { const dytd = ((row.actual - row.budget) / row.budget) * 100; const dfy = ((row.fy - row.fyBudget) / row.fyBudget) * 100; return ( ); })}
Categoria Actual YTD Budget YTD Δ YTD Proiezione FY Budget FY Δ FY attesa
{row.category} {row.actual.toFixed(1)} {row.budget.toFixed(1)} 0 ? 'var(--green)' : 'var(--red)' }}>{dytd > 0 ? '+' : ''}{dytd.toFixed(1)}% {row.fy.toFixed(1)} {row.fyBudget.toFixed(1)} 0 ? 'var(--green)' : 'var(--red)' }}>{dfy > 0 ? '+' : ''}{dfy.toFixed(1)}%
)} {tab === 'whatif' && (
Variabili
{[ { key: 'revenues', label: 'Ricavi', unit: '%', min: -20, max: 20 }, { key: 'costs', label: 'Costi variabili', unit: '%', min: -10, max: 20 }, { key: 'rates', label: 'Tasso medio debito', unit: '%', min: 2, max: 7, step: 0.1 } ].map(v => (
{v.label} {scenarioVars[v.key]}{v.unit}
setScenarioVars({ ...scenarioVars, [v.key]: parseFloat(e.target.value) })} style={{ width: '100%' }} />
{v.min}{v.unit}{v.max}{v.unit}
))}
Confronto scenari
{F.scenarios.map((s, i) => ( ))}
Scenario RicaviCostiTassi EBITDAUtile nettoCash EoY
{s.name} 0 ? 'var(--green)' : s.revenues < 0 ? 'var(--red)' : 'var(--muted)' }}>{s.revenues > 0 ? '+' : ''}{s.revenues}% 0 ? 'var(--red)' : 'var(--muted)' }}>{s.costs > 0 ? '+' : ''}{s.costs}% {s.rates}% {s.ebitda.toFixed(1)} {s.netIncome.toFixed(1)} {s.cash.toFixed(1)}
)} {tab === 'roi' && (
Input investimento
{[ ['Importo investimento', '3.5 M€'], ['Cash flow annuale atteso', '820 k€'], ['Durata', '8 anni'], ['WACC', '6.2%'], ['Valore terminale', '1.2 M€'] ].map(([l, v]) => (
{l} {v}
))}
Risultati
{[ ['Payback', '5.2 anni'], ['IRR', '11.4%'], ['NPV', '+1.82 M€'] ].map(([l, v]) => (
{l}
{v}
))}
Sensitivity · NPV (M€)
CF atteso \ WACC5.0%6.2%7.5%9.0%
700 k€0.880.24−0.40−1.08
820 k€2.621.821.040.22
950 k€4.503.502.581.62
)} {tab === 'stress' && (
Monitoraggio covenant bancari
2 OK 2 Attenzione 2 Sforati
{F.covenants.map((c, i) => ( ))}
CovenantSocietàSogliaValoreMargineRating
{c.name} {c.company} {c.threshold} {c.actual} {c.margin} ● {c.status === 'green' ? 'OK' : c.status === 'amber' ? 'Attenzione' : 'Sforato'}
)}
); }; Object.assign(window, { Forecasting });