Business Expansion Cost Calculator

Expansion Project Overview

Expansion Cost Details

Sections below will appear based on the "Type of Expansion" selected in Tab 1. All costs are estimates.

Real Estate & Setup

$
$
$
$
$

Product/Service Development

$
$
$
$
$

Market Development & Launch

$
$
$
$
$

Operational Scaling & Support

$
$
$

Common Expansion Costs

$
$
$
$

Custom Expansion Costs

No custom costs added.

Contingency Planning

%

Expansion Budget Summary

Complete project setup and cost details in previous tabs to see the summary.

New Direct Employees: ${getNum('bec-new-employees', true)}

`; if (expansionTypeSelect.value === 'newLocation') { html += `

New Physical Locations: ${getNum('bec-new-locations', true)}

`; } html += `
`; html += '

Estimated Costs Breakdown:

'; html += ''; if (allCosts.length === 0 && contingencyAmount === 0) { html += ''; } else { const groupedByCategory = allCosts.reduce((acc, item) => { (acc[item.category] = acc[item.category] || []).push(item); return acc; }, {}); for (const category in groupedByCategory) { html += ``; groupedByCategory[category].forEach(item => { html += ``; }); } html += ``; html += ``; } html += ``; html += '
CategoryItemEstimated Cost
No costs entered.
${category}
${item.name} ${currency}${item.amount.toFixed(2)}
Subtotal of Direct Costs:${currency}${subtotalDirectCosts.toFixed(2)}
Contingency (${contingencyType === 'percentage' ? contingencyValue + '%' : 'Fixed'}):${currency}${contingencyAmount.toFixed(2)}
GRAND TOTAL ESTIMATED EXPANSION COST:${currency}${grandTotal.toFixed(2)}
'; summaryOutput.innerHTML = html; downloadPdfButton.disabled = allCosts.length === 0 && contingencyAmount === 0; } // PDF Download downloadPdfButton.addEventListener('click', function () { if (typeof jspdf === 'undefined' || typeof jspdf.jsPDF === 'undefined') { alert('Error: jsPDF library is not loaded.'); return; } const { jsPDF } = jspdf; const doc = new jsPDF('p'); const currency = currencySymbolInput.value || '$'; const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--bec-primary-color').trim(); const secondaryColor = getComputedStyle(document.documentElement).getPropertyValue('--bec-secondary-color').trim(); const textColor = getComputedStyle(document.documentElement).getPropertyValue('--bec-text-color').trim(); const buttonTextColor = getComputedStyle(document.documentElement).getPropertyValue('--bec-button-text-color').trim(); doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text('Business Expansion Cost Estimate', doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' }); doc.setFontSize(12); doc.setTextColor(textColor); let lastY = 30; doc.text(`Business Name: ${getVal('bec-business-name') || 'N/A'}`, 14, lastY); lastY += 7; doc.text(`Project Name: ${getVal('bec-project-name') || 'N/A'}`, 14, lastY); lastY += 7; const expTypeVal = expansionTypeSelect.value; doc.text(`Expansion Type: ${expTypeVal ? expansionTypeSelect.options[expansionTypeSelect.selectedIndex].text : 'N/A'}`, 14, lastY); lastY += 7; doc.text(`New Direct Employees: ${getNum('bec-new-employees', true)}`, 14, lastY); lastY += 7; if (expTypeVal === 'newLocation') { doc.text(`New Physical Locations: ${getNum('bec-new-locations', true)}`, 14, lastY); lastY += 7; } doc.text(`Currency: ${currency}`, 14, lastY); lastY += 10; const allCostsPdf = []; let subtotalDirectCostsPdf = 0; document.querySelectorAll('#costs .bec-cost-category-section').forEach(section => { const sectionTypes = section.dataset.expansionTypes; if (section.style.display === 'block' || (sectionTypes && sectionTypes.includes(expTypeVal)) || section.classList.contains('bec-visible')) { section.querySelectorAll('.bec-cost-item').forEach(input => { const cost = getNum(input.value, true); if (cost > 0) { allCostsPdf.push({ category: input.dataset.category, name: input.dataset.itemName, amount: cost }); subtotalDirectCostsPdf += cost; } }); } }); document.querySelectorAll('.bec-custom-cost-item').forEach(item => { const name = item.querySelector('.bec-custom-name').value || 'Custom Cost'; const amount = getNum(item.querySelector('.bec-custom-amount').value, true); if (amount > 0) { allCostsPdf.push({ category: 'Custom Expansion Costs', name, amount }); subtotalDirectCostsPdf += amount; } }); const contingencyTypePdf = getVal('bec-contingency-type'); const contingencyValuePdf = getNum('bec-contingency-value', true); let contingencyAmountPdf = (contingencyTypePdf === 'percentage') ? subtotalDirectCostsPdf * (contingencyValuePdf / 100) : contingencyValuePdf; const grandTotalPdf = subtotalDirectCostsPdf + contingencyAmountPdf; const tableBody = []; const groupedByCategoryPdf = allCostsPdf.reduce((acc, item) => { (acc[item.category] = acc[item.category] || []).push(item); return acc; }, {}); for (const category in groupedByCategoryPdf) { tableBody.push([{ content: category, colSpan: 2, styles: { fontStyle: 'bold', fillColor: '#f0f0f0' } }]); groupedByCategoryPdf[category].forEach(item => { tableBody.push([item.name, `${currency}${item.amount.toFixed(2)}`]); }); } tableBody.push([ { content: 'Subtotal of Direct Costs:', styles: { halign: 'right', fontStyle: 'bold'} }, { content: `${currency}${subtotalDirectCostsPdf.toFixed(2)}`, styles: { halign: 'right', fontStyle: 'bold' } } ]); tableBody.push([ { content: `Contingency (${contingencyTypePdf === 'percentage' ? contingencyValuePdf + '%' : 'Fixed'}):`, styles: { halign: 'right', fontStyle: 'bold'} }, { content: `${currency}${contingencyAmountPdf.toFixed(2)}`, styles: { halign: 'right', fontStyle: 'bold' } } ]); tableBody.push([ { content: 'GRAND TOTAL:', styles: { halign: 'right', fontStyle: 'bold', fillColor: primaryColor, textColor: buttonTextColor } }, { content: `${currency}${grandTotalPdf.toFixed(2)}`, styles: { halign: 'right', fontStyle: 'bold', fillColor: primaryColor, textColor: buttonTextColor } } ]); doc.autoTable({ startY: lastY, head: [['Cost Item / Category', 'Estimated Cost']], body: tableBody, theme: 'grid', headStyles: { fillColor: secondaryColor, textColor: buttonTextColor, fontSize: 10 }, styles: { fontSize: 9, cellPadding: 2 }, columnStyles: { 1: { halign: 'right' } }, didDrawCell: (data) => { // For rowspan-like appearance for category header if (data.cell.raw && data.cell.raw.colSpan === 2) { // Handled by autotable's colSpan } } }); doc.save(`Business_Expansion_Costs_${getVal('bec-project-name').replace(/\s+/g, '_') || 'Report'}.pdf`); }); // Initial setup checkEmptyState('#bec-custom-costs-container', 'bec-no-items-text'); toggleCostSections(); // Set initial visibility based on default expansion type toggleContingencyInputType(); // Set initial contingency input type showTab(0); updateAllCurrencyPrefixes(); });
Scroll to Top