Strategic Financial Planning Simulator

Strategic Financial Planning Simulator

1. Enter Initial Data & Assumptions

Initial Financials (Year 0)

Growth & Operating Assumptions

Investment & Working Capital Assumptions

Calculate the model to see the Balance Sheet.

'; keyMetricsOutputDiv.innerHTML = '

Calculate the model to see the Key Metrics.

'; // Reset to the first tab openTab('inputs'); hideMessage(); } /** * Downloads the financial projections as a PDF. */ function downloadPDF() { if (!window.financialProjections) { showMessage('Please calculate the financial projections first.', 'info'); return; } const { jsPDF } = window.jspdf; const pdf = new jsPDF('l', 'mm', 'a4'); // 'l' for landscape, 'mm', 'a4' size (better for wide tables) const BLACK_COLOR = [31, 41, 55]; // Tailwind gray-900 equivalent const BLUE_HEADER_COLOR = [29, 78, 216]; // Tailwind blue-700 equivalent let y = 15; // Y-coordinate for placing content // Title pdf.setFontSize(22); pdf.setFont('helvetica', 'bold'); pdf.setTextColor(BLACK_COLOR[0], BLACK_COLOR[1], BLACK_COLOR[2]); pdf.text('Strategic Financial Planning Simulator Results', 148, y, { align: 'center' }); // Centered for landscape y += 15; // --- 1. Input Parameters Section --- pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('1. Input Parameters & Assumptions', 15, y); y += 8; const inputs = window.financialProjections.inputs; const inputData = [ ['Initial Revenue', formatCurrency(inputs.initialRevenue)], ['Initial COGS', formatCurrency(inputs.initialCogs)], ['Initial Operating Expenses', formatCurrency(inputs.initialOperatingExpenses)], ['Initial Cash', formatCurrency(inputs.initialCash)], ['Initial Accounts Receivable', formatCurrency(inputs.initialAccountsReceivable)], ['Initial Inventory', formatCurrency(inputs.initialInventory)], ['Initial Fixed Assets (Net)', formatCurrency(inputs.initialFixedAssets)], ['Initial Accounts Payable', formatCurrency(inputs.initialAccountsPayable)], ['Initial Accrued Expenses', formatCurrency(inputs.initialAccruedExpenses)], ['Initial Long-Term Debt', formatCurrency(inputs.initialLongTermDebt)], ['Initial Equity', formatCurrency(inputs.initialEquity)], ['Projection Years', inputs.projectionYears], ['Annual Revenue Growth Rate', `${(inputs.revenueGrowthRate * 100).toFixed(2)}%`], ['COGS as % of Revenue', `${(inputs.cogsAsPctRevenue * 100).toFixed(2)}%`], ['Operating Expenses as % of Revenue', `${(inputs.opexAsPctRevenue * 100).toFixed(2)}%`], ['Depreciation Rate (% of Fixed Assets)', `${(inputs.depreciationRate * 100).toFixed(2)}%`], ['Interest Rate on Debt', `${(inputs.interestRateOnDebt * 100).toFixed(2)}%`], ['Tax Rate', `${(inputs.taxRate * 100).toFixed(2)}%`], ['CAPEX as % of Revenue', `${(inputs.capexAsPctRevenue * 100).toFixed(2)}%`], ['Accounts Receivable Days', inputs.arDays], ['Inventory Days', inputs.inventoryDays], ['Accounts Payable Days', inputs.apDays], ['Accrued Expenses Days', inputs.accruedDays] ]; pdf.autoTable({ startY: y, head: [['Parameter', 'Value']], body: inputData, theme: 'grid', styles: { fontSize: 8, cellPadding: 2, overflow: 'linebreak', lineColor: 200, lineWidth: 0.1 }, headStyles: { fillColor: BLUE_HEADER_COLOR, textColor: 255, fontStyle: 'bold' }, margin: { left: 15, right: 15 }, columnStyles: { 0: { cellWidth: 80 }, 1: { cellWidth: 'auto' } } }); y = pdf.autoTable.previous.finalY + 15; // Helper to add a financial statement table const addFinancialStatementTable = (title, data, displayNames, formatters, startY) => { // Add new page if current content won't fit if (startY + 30 + (Object.keys(displayNames).length * 7) > pdf.internal.pageSize.height - 15) { pdf.addPage('l', 'a4'); // Add a new page in landscape startY = 15; // Reset Y } pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text(title, 15, startY); startY += 8; const headers = ['Line Item']; for (let i = 0; i < data.length; i++) { headers.push(data[i].year === 0 ? 'Current Year' : `Year ${data[i].year}`); } const tableBody = []; Object.keys(displayNames).forEach(item => { const row = [displayNames[item]]; data.forEach(yearData => { const formattedValue = formatters[item] ? formatters[item](yearData[item]) : formatCurrency(yearData[item]); row.push({ content: formattedValue, styles: { halign: 'right' } }); }); tableBody.push(row); }); pdf.autoTable({ startY: startY, head: [headers], body: tableBody, theme: 'grid', styles: { fontSize: 7, cellPadding: 1, overflow: 'linebreak', lineColor: 200, lineWidth: 0.1 }, headStyles: { fillColor: BLUE_HEADER_COLOR, textColor: 255, fontStyle: 'bold' }, margin: { left: 15, right: 15 }, didParseCell: function (data) { if (data.column.index > 0) { // All data columns are right-aligned data.cell.styles.halign = 'right'; } } }); return pdf.autoTable.previous.finalY + 15; }; // --- Income Statement --- const isDisplayNames = { revenue: 'Revenue', cogs: 'Cost of Goods Sold (COGS)', grossProfit: 'Gross Profit', operatingExpenses: 'Operating Expenses', ebitda: 'EBITDA', depreciation: 'Depreciation', ebit: 'EBIT', interestExpense: 'Interest Expense', ebt: 'Earnings Before Tax (EBT)', taxes: 'Taxes', netIncome: 'Net Income' }; const isFormatters = {}; // All are currency, handled by default formatCurrency for this y = addFinancialStatementTable('2. Projected Income Statement', window.financialProjections.incomeStatement, isDisplayNames, isFormatters, y); // --- Cash Flow Statement --- const cfsDisplayNames = { netIncome: 'Net Income', depreciation: 'Depreciation', changeInAR: 'Change in Accounts Receivable', changeInInventory: 'Change in Inventory', changeInAP: 'Change in Accounts Payable', changeInAccruedExpenses: 'Change in Accrued Expenses', cashFlowFromOperations: 'Cash Flow From Operations', capex: 'Capital Expenditures (CAPEX)', cashFlowFromInvesting: 'Cash Flow From Investing', debtIssuanceRepayment: 'Debt Issuance / (Repayment)', equityIssuanceDividends: 'Equity Issuance / (Dividends)', cashFlowFromFinancing: 'Cash Flow From Financing', netChangeInCash: 'Net Change in Cash', endingCash: 'Ending Cash Balance' }; const cfsFormatters = {}; // All are currency y = addFinancialStatementTable('3. Projected Cash Flow Statement', window.financialProjections.cashFlow, cfsDisplayNames, cfsFormatters, y); // --- Balance Sheet --- const bsDisplayNames = { cash: 'Cash', accountsReceivable: 'Accounts Receivable', inventory: 'Inventory', totalCurrentAssets: 'Total Current Assets', fixedAssetsNet: 'Fixed Assets (Net)', totalAssets: 'TOTAL ASSETS', accountsPayable: 'Accounts Payable', accruedExpenses: 'Accrued Expenses', totalCurrentLiabilities: 'Total Current Liabilities', longTermDebt: 'Long-Term Debt', totalLiabilities: 'TOTAL LIABILITIES', equity: 'Equity', totalLiabilitiesAndEquity: 'TOTAL LIABILITIES & EQUITY' }; const bsFormatters = {}; // All are currency y = addFinancialStatementTable('4. Projected Balance Sheet', window.financialProjections.balanceSheet, bsDisplayNames, bsFormatters, y); // --- Key Metrics --- const kmDisplayNames = { ebitdaMargin: 'EBITDA Margin', netProfitMargin: 'Net Profit Margin', currentRatio: 'Current Ratio', debtToEquity: 'Debt to Equity', unleveredFreeCashFlow: 'Unlevered Free Cash Flow' }; const kmFormatters = { ebitdaMargin: (val) => `${(val * 100).toFixed(2)}%`, netProfitMargin: (val) => `${(val * 100).toFixed(2)}%`, currentRatio: (val) => `${val.toFixed(2)}x`, debtToEquity: (val) => `${val.toFixed(2)}x`, unleveredFreeCashFlow: formatCurrency }; y = addFinancialStatementTable('5. Key Metrics', window.financialProjections.keyMetrics.filter(m => m.year > 0), kmDisplayNames, kmFormatters, y); // Exclude Year 0 from key metrics pdf.save('Strategic_Financial_Planning_Simulator_Results.pdf'); } /** * Initializes DOM element references once the document is fully loaded. */ document.addEventListener('DOMContentLoaded', () => { // Initial Financials Inputs initialRevenueInput = document.getElementById('initialRevenue'); initialCogsInput = document.getElementById('initialCogs'); initialOperatingExpensesInput = document.getElementById('initialOperatingExpenses'); initialCashInput = document.getElementById('initialCash'); initialAccountsReceivableInput = document.getElementById('initialAccountsReceivable'); initialInventoryInput = document.getElementById('initialInventory'); initialFixedAssetsInput = document.getElementById('initialFixedAssets'); initialAccountsPayableInput = document.getElementById('initialAccountsPayable'); initialAccruedExpensesInput = document.getElementById('initialAccruedExpenses'); initialLongTermDebtInput = document.getElementById('initialLongTermDebt'); initialEquityInput = document.getElementById('initialEquity'); // Growth & Operating Assumptions Inputs projectionYearsInput = document.getElementById('projectionYears'); revenueGrowthRateInput = document.getElementById('revenueGrowthRate'); cogsAsPctRevenueInput = document.getElementById('cogsAsPctRevenue'); opexAsPctRevenueInput = document.getElementById('opexAsPctRevenue'); depreciationRateInput = document.getElementById('depreciationRate'); interestRateOnDebtInput = document.getElementById('interestRateOnDebt'); taxRateInput = document.getElementById('taxRate'); // Investment & Working Capital Assumptions Inputs capexAsPctRevenueInput = document.getElementById('capexAsPctRevenue'); arDaysInput = document.getElementById('arDays'); inventoryDaysInput = document.getElementById('inventoryDays'); apDaysInput = document.getElementById('apDays'); accruedDaysInput = document.getElementById('accruedDays'); // Output Elements incomeStatementOutputDiv = document.getElementById('incomeStatementOutput'); cashFlowOutputDiv = document.getElementById('cashFlowOutput'); balanceSheetOutputDiv = document.getElementById('balanceSheetOutput'); keyMetricsOutputDiv = document.getElementById('keyMetricsOutput'); messageBox = document.getElementById('messageBox'); // Initialize navigation button states updateNavigationButtons(); });
Scroll to Top