Subscription Service ROI Analyzer

Enter Your Subscription Details

Total Estimated Monthly Cost: $0.00

Total Estimated Annual Cost: $0.00

Benefit & Value Assessment

ROI Calculation

Overall Subscription ROI Summary

Add and analyze subscriptions to see the summary here.

Net Monthly Value (ROI): $${netMonthlyValue.toFixed(2)}

ROI Percentage: ${roiPercentage === Infinity ? 'Infinite (Cost is $0)' : roiPercentage.toFixed(1) + '%'}

`; alert(`ROI analysis saved for ${sub.name}. Check the Summary tab.`); document.getElementById('downloadRoiPdfButton').disabled = false; // Enable PDF download } // --- Tab 4: Overall Summary --- function generateOverallSummary() { collectSubscriptionInputs(); // Make sure subscriptions array is current const container = document.getElementById('overallSummaryTableContainer'); const totalsContainer = document.getElementById('overallSummaryTotals'); const analyzedSubs = subscriptions.filter(s => s.roi && s.roi.totalQuantifiedBenefit !== undefined && s.monthlyCost > 0); if (analyzedSubs.length === 0) { container.innerHTML = "

No subscriptions have been fully analyzed yet. Please complete Benefit Assessment and ROI Calculation for your subscriptions.

"; totalsContainer.innerHTML = ""; document.getElementById('downloadRoiPdfButton').disabled = true; return; } let tableHTML = ``; let totalAllMonthlyCosts = 0; let totalAllBenefits = 0; analyzedSubs.forEach(sub => { totalAllMonthlyCosts += parseFloat(sub.monthlyCost); totalAllBenefits += sub.roi.totalQuantifiedBenefit; tableHTML += ` `; }); tableHTML += `
Subscription Name Monthly Cost Total Benefit Net Value (ROI $) ROI % Satisfaction
${sub.name} $${parseFloat(sub.monthlyCost).toFixed(2)} $${sub.roi.totalQuantifiedBenefit.toFixed(2)} $${sub.roi.netMonthlyValue.toFixed(2)} ${sub.roi.roiPercentage === Infinity ? 'Infinite' : sub.roi.roiPercentage.toFixed(1) + '%'} ${sub.benefits && sub.benefits.satisfactionRating ? sub.benefits.satisfactionRating + '/10' : 'N/A'}
`; container.innerHTML = tableHTML; const overallNetValue = totalAllBenefits - totalAllMonthlyCosts; totalsContainer.innerHTML = `

Total Monthly Cost (Analyzed Subs): $${totalAllMonthlyCosts.toFixed(2)}

Total Quantified Monthly Benefit (Analyzed Subs): $${totalAllBenefits.toFixed(2)}

Overall Net Monthly Value: $${overallNetValue.toFixed(2)}

`; document.getElementById('downloadRoiPdfButton').disabled = false; } // --- PDF Generation --- function downloadRoiPdf() { if (subscriptions.filter(s => s.roi && s.roi.totalQuantifiedBenefit !== undefined && s.monthlyCost > 0).length === 0) { alert("Please add and analyze at least one subscription to generate a PDF."); return; } if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('PDF generation library (jsPDF) is not loaded.'); return; } const jsPDFConstructor = window.jspdf.jsPDF; const doc = new jsPDFConstructor(); if (typeof doc.autoTable !== 'function') { alert('jsPDF AutoTable plugin not loaded.'); return; } const primaryColor = '#007bff', textColor = '#212529', tableHeaderColor = '#e9ecef'; let yPos = 22; doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Subscription Service ROI Analysis", 14, yPos); yPos += 8; doc.setFontSize(10); doc.setTextColor(textColor); doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 14, yPos); yPos += 12; let totalAllMonthlyCostsPdf = 0; let totalAllBenefitsPdf = 0; subscriptions.forEach((sub, index) => { if (!(sub.monthlyCost > 0)) return; // Skip if no cost defined if (yPos > 250) { doc.addPage(); yPos = 20; } doc.setFontSize(14); doc.setTextColor(primaryColor); doc.text(`Subscription: ${sub.name}`, 14, yPos); yPos += 7; let subDetailsBody = [ ['Category:', sub.category || 'N/A'], ['Billing Cycle:', sub.cycle], ['Cost:', `$${sub.cost.toFixed(2)} per ${sub.cycle.toLowerCase()}`], ['Effective Monthly Cost:', `$${parseFloat(sub.monthlyCost).toFixed(2)}`] ]; doc.autoTable({ startY: yPos, body: subDetailsBody, theme: 'plain', styles: {fontSize:9, cellPadding:1}, columnStyles: {0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 5; if (sub.benefits && sub.benefits.calculatedFinancialBenefit !== undefined) { if (yPos > 260) { doc.addPage(); yPos = 20; } doc.setFontSize(11); doc.setTextColor(textColor); doc.text("Benefit Assessment:", 16, yPos); yPos += 5; let benefitsBody = [ ['Direct Financial Savings:', `$${sub.benefits.directSavings.toFixed(2)} /month`], ['Income Generated/Enabled:', `$${sub.benefits.earningsGenerated.toFixed(2)} /month`], ['Value of Discounts/Perks:', `$${sub.benefits.discountsValue.toFixed(2)} /month`], ['Total Financial Benefit:', `$${sub.benefits.calculatedFinancialBenefit.toFixed(2)} /month`], ['Time Saved:', `${sub.benefits.timeSavedHours} hrs/month (Value: $${sub.benefits.calculatedTimeSavedValue.toFixed(2)})`], ['Usage:', `${sub.benefits.usageFrequencyValue} times per ${sub.benefits.usagePeriod} (Cost/Use: $${(sub.benefits.calculatedCostPerUse || 0).toFixed(2)})`], ['Satisfaction/Importance:', `${sub.benefits.satisfactionRating}/10`] ]; doc.autoTable({ startY: yPos, body: benefitsBody, theme: 'plain', styles: {fontSize:9, cellPadding:1}, columnStyles: {0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 5; } if (sub.roi && sub.roi.totalQuantifiedBenefit !== undefined) { totalAllMonthlyCostsPdf += parseFloat(sub.monthlyCost); totalAllBenefitsPdf += sub.roi.totalQuantifiedBenefit; if (yPos > 260) { doc.addPage(); yPos = 20; } doc.setFontSize(11); doc.setTextColor(textColor); doc.text("ROI Calculation:", 16, yPos); yPos += 5; let roiBody = [ ['User-Assigned Intangible Value:', `$${sub.roi.userValueOtherBenefits.toFixed(2)} /month`], ['Total Quantified Benefit:', `$${sub.roi.totalQuantifiedBenefit.toFixed(2)} /month`], ['Net Monthly Value (ROI $):', `$${sub.roi.netMonthlyValue.toFixed(2)}`], ['ROI Percentage:', `${sub.roi.roiPercentage === Infinity ? 'Infinite (Cost $0)' : sub.roi.roiPercentage.toFixed(1) + '%'}`] ]; doc.autoTable({ startY: yPos, body: roiBody, theme: 'plain', styles: {fontSize:9, cellPadding:1}, columnStyles: {0:{fontStyle:'bold'}}}); yPos = doc.lastAutoTable.finalY + 8; } yPos += 2; // Extra space between subscriptions }); // Overall Summary Table if (yPos > 230) { doc.addPage(); yPos = 20; } doc.setFontSize(14); doc.setTextColor(primaryColor); doc.text("Overall Summary of Analyzed Subscriptions", 14, yPos); yPos += 7; const summaryBodyPdf = subscriptions .filter(s => s.roi && s.roi.totalQuantifiedBenefit !== undefined && parseFloat(s.monthlyCost) > 0) .map(sub => [ sub.name, `$${parseFloat(sub.monthlyCost).toFixed(2)}`, `$${sub.roi.totalQuantifiedBenefit.toFixed(2)}`, `$${sub.roi.netMonthlyValue.toFixed(2)}`, `${sub.roi.roiPercentage === Infinity ? 'Infinite' : sub.roi.roiPercentage.toFixed(1) + '%'}`, `${sub.benefits && sub.benefits.satisfactionRating ? sub.benefits.satisfactionRating + '/10' : 'N/A'}` ]); doc.autoTable({ startY: yPos, head: [['Subscription', 'Monthly Cost', 'Total Benefit', 'Net Value ($)', 'ROI %', 'Satisfaction']], body: summaryBodyPdf, theme: 'grid', headStyles: { fillColor: tableHeaderColor, textColor: textColor, fontStyle: 'bold', fontSize: 9 }, styles: { fontSize: 8, cellPadding: 1.5 }, columnStyles: { 1:{halign:'right'}, 2:{halign:'right'}, 3:{halign:'right'}, 4:{halign:'right'}, 5:{halign:'center'}} }); yPos = doc.lastAutoTable.finalY + 7; doc.setFontSize(10); doc.setTextColor(textColor); doc.text(`Total Monthly Cost (Analyzed): $${totalAllMonthlyCostsPdf.toFixed(2)}`, 14, yPos); yPos += 5; doc.text(`Total Quantified Benefit (Analyzed): $${totalAllBenefitsPdf.toFixed(2)}`, 14, yPos); yPos += 5; const overallNetValuePdf = totalAllBenefitsPdf - totalAllMonthlyCostsPdf; doc.setFontSize(11); doc.setFont(undefined, 'bold'); doc.text(`Overall Net Monthly Value: $${overallNetValuePdf.toFixed(2)}`, 14, yPos); doc.save("Subscription_ROI_Analysis.pdf"); } // Initialize updateRoiNavButtons(); populateSubscriptionSelects(); // Initial population if any default rows are added
Scroll to Top