Customer Acquisition Cost (CAC) Calculator
Setup & Expense Inputs
Marketing Expenses (for the period)
$
$
$
$
$
Sales Expenses (for acquiring new customers in the period)
$
Portion of salaries/commissions directly related to acquiring new customers.
$
$
$
Acquisition Results
LTV, Ratio Analysis & Export
Customer Lifetime Value (LTV) Calculation (Optional)
$
Months to Recover CAC (Optional)
$
Calculations will appear here once inputs are provided.
Months to Recover CAC: Not enough data
`; } analysisResultsDiv.innerHTML = html; downloadPdfButton.disabled = false; // Enable PDF once this tab is viewed and calculated } // 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('--cac-primary-color').trim(); const secondaryColor = getComputedStyle(document.documentElement).getPropertyValue('--cac-secondary-color').trim(); const textColor = getComputedStyle(document.documentElement).getPropertyValue('--cac-text-color').trim(); const buttonTextColor = getComputedStyle(document.documentElement).getPropertyValue('--cac-button-text-color').trim(); doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text('Customer Acquisition Cost Analysis', doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' }); doc.setFontSize(12); doc.setTextColor(textColor); let lastY = 30; doc.text(`Business Name: ${getVal('cac-business-name') || 'N/A'}`, 14, lastY); lastY += 7; doc.text(`Campaign/Analysis Period: ${getVal('cac-period-name') || 'N/A'}`, 14, lastY); lastY += 7; doc.text(`Period for Calculation: ${getVal('cac-calc-period') || 'N/A'}`, 14, lastY); lastY += 7; doc.text(`Currency: ${currency}`, 14, lastY); lastY += 10; const cacData = calculateCACData(); const ltvData = { avgPurchaseValue: getNum('cac-ltv-avg-purchase-value'), avgPurchaseFreq: getNum('cac-ltv-avg-purchase-freq'), avgLifespan: getNum('cac-ltv-avg-lifespan'), ltv: 0 }; if (ltvData.avgPurchaseValue > 0 && ltvData.avgPurchaseFreq > 0 && ltvData.avgLifespan > 0) { ltvData.ltv = ltvData.avgPurchaseValue * ltvData.avgPurchaseFreq * ltvData.avgLifespan; } const recoverType = getVal('cac-recover-type'); const recoverAmount = getNum('cac-recover-amount'); let monthsToRecoverVal = 0; if (recoverAmount > 0 && cacData.cac >= 0) { monthsToRecoverVal = cacData.cac > 0 ? cacData.cac / recoverAmount : 0; } // Expense Details doc.setFontSize(11); doc.setTextColor(primaryColor); doc.text('Expense Breakdown:', 14, lastY); lastY += 6; const expenseBody = [ ['Marketing - Advertising', formatCurrency(getNum('cac-mkt-ads'), currency)], ['Marketing - Content Creation', formatCurrency(getNum('cac-mkt-content'), currency)], ['Marketing - Software/Tools', formatCurrency(getNum('cac-mkt-tools'), currency)], ['Marketing - Events/PR', formatCurrency(getNum('cac-mkt-events'), currency)], ['Marketing - Other', formatCurrency(getNum('cac-mkt-other'), currency)], [{content: 'Total Marketing Expenses', styles: {fontStyle: 'bold'}}, {content: formatCurrency(cacData.marketingCosts, currency), styles: {fontStyle: 'bold'}}], ['Sales - Salaries/Commissions (Acquisition)', formatCurrency(getNum('cac-sales-salaries'), currency)], ['Sales - Software/Tools (CRM, etc.)', formatCurrency(getNum('cac-sales-tools'), currency)], ['Sales - Travel (Acquisition)', formatCurrency(getNum('cac-sales-travel'), currency)], ['Sales - Other (Acquisition)', formatCurrency(getNum('cac-sales-other'), currency)], [{content: 'Total Sales Expenses (Acquisition)', styles: {fontStyle: 'bold'}}, {content: formatCurrency(cacData.salesCosts, currency), styles: {fontStyle: 'bold'}}], [{content: 'TOTAL ACQUISITION EXPENSES', styles: {fontStyle: 'bold', fillColor: secondaryColor, textColor: buttonTextColor}}, {content: formatCurrency(cacData.totalAcquisitionCosts, currency), styles: {fontStyle: 'bold', fillColor: secondaryColor, textColor: buttonTextColor}}] ]; doc.autoTable({ startY: lastY, theme: 'grid', head: [['Expense Item', 'Amount']], body: expenseBody, headStyles: {fillColor: secondaryColor, textColor: buttonTextColor, fontSize: 9}, styles: {fontSize: 8, cellPadding: 2}, columnStyles: { 1: {halign: 'right'} } }); lastY = doc.lastAutoTable.finalY + 10; // Results doc.setFontSize(11); doc.setTextColor(primaryColor); doc.text('Key Metrics:', 14, lastY); lastY += 6; const resultsBody = [ ['Number of New Customers Acquired', cacData.newCustomers.toString()], [{content: 'Customer Acquisition Cost (CAC)', styles: {fontStyle:'bold', fillColor: primaryColor, textColor: buttonTextColor}}, {content: formatCurrency(cacData.cac, currency), styles: {fontStyle:'bold', fillColor: primaryColor, textColor: buttonTextColor}}], ]; if (ltvData.ltv > 0) { resultsBody.push(['Average Purchase Value', formatCurrency(ltvData.avgPurchaseValue, currency)]); resultsBody.push(['Average Purchase Frequency (per year)', ltvData.avgPurchaseFreq.toFixed(2)]); resultsBody.push(['Average Customer Lifespan (years)', ltvData.avgLifespan.toFixed(1)]); resultsBody.push(['Customer Lifetime Value (LTV)', formatCurrency(ltvData.ltv, currency)]); if (cacData.cac > 0) { resultsBody.push(['LTV : CAC Ratio', `${(ltvData.ltv / cacData.cac).toFixed(2)} : 1`]); } } if (recoverAmount > 0 && cacData.cac >= 0) { let recTypeLabel = recoverType === 'revenue' ? "Avg. Monthly Revenue/Cust." : "Avg. Monthly Gross Margin/Cust."; resultsBody.push([`Metric for Recovery (${recTypeLabel})`, formatCurrency(recoverAmount, currency)]); resultsBody.push(['Months to Recover CAC', `${monthsToRecoverVal.toFixed(1)} months`]); } doc.autoTable({ startY: lastY, theme: 'grid', head: [['Metric', 'Value']], body: resultsBody, headStyles: {fillColor: secondaryColor, textColor: buttonTextColor, fontSize: 9}, styles: {fontSize: 8, cellPadding: 2}, columnStyles: { 1: {halign: 'right'} } }); doc.save(`CAC_Analysis_${getVal('cac-campaign-name').replace(/\s+/g, '_') || getVal('cac-calc-period').replace(/\s+/g, '_') || 'Report'}.pdf`); }); // Initial setup showTab(0); updateAllCurrencyPrefixes(); calculateAndDisplayCAC(true); // Initial quick CAC calculation });