Subscription Service ROI Analyzer
Enter Your Subscription Details
Total Estimated Monthly Cost: $0.00
Total Estimated Annual Cost: $0.00
Benefit & Value Assessment
Financial Benefits ($/month) for Subscription
Time Saved (Converted to $)
Usage & Subjective Value
Calculated Monthly Financial Benefit: $0.00
Calculated Monthly Value of Time Saved: $0.00
Estimated Cost Per Use: $0.00
ROI Calculation
ROI for Subscription
Monthly Cost: $0.00
Total Financial Benefits (from Tab 2): $0.00
Value of Time Saved (from Tab 2): $0.00
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 = `| 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'} |
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