`;
analysisHTML += `
`;
if (set.paidService.netEffectiveCost < set.freeService.totalEffectiveMonthlyCost) {
analysisHTML += `
The Paid Service (${set.paidService.name}) appears to offer better overall value for this set, considering your inputs.
`;
set.analysis = { recommendedOption: "Paid Service" };
} else if (set.paidService.netEffectiveCost > set.freeService.totalEffectiveMonthlyCost) {
analysisHTML += `
The Free Service (${set.freeService.name}) appears to be more cost-effective for this set, considering your inputs.
`;
set.analysis = { recommendedOption: "Free Service" };
} else {
analysisHTML += `
Both services have a similar effective value/cost for this set. Consider qualitative factors.
`;
set.analysis = { recommendedOption: "Depends/Equivalent" };
}
analysisHTML += `
`;
container.innerHTML = analysisHTML;
}
// --- Tab 4: Overall Summary ---
function generateOverallComparisonSummary() {
collectAllSetInputs(); // Ensure all data is current
const container = document.getElementById('overallComparisonSummaryTable');
const analyzedSets = comparisonSets.filter(s => s.analysis && s.paidService.featuresValue && s.paidService.featuresValue.totalValue !== undefined);
if (analyzedSets.length === 0) {
container.innerHTML = "
No comparison sets have been fully analyzed. Please complete steps 1-3 for each set.
";
document.getElementById('downloadComparerPdfButton').disabled = true;
return;
}
let tableHTML = `
| Comparison Set |
Free Service (Effective Cost) |
Paid Service (Net Value/Cost) |
Recommendation |
`;
analyzedSets.forEach(set => {
const freeEffCost = set.freeService.totalEffectiveMonthlyCost;
const paidNetEffValue = set.paidService.netEffectiveCost; // Negative is good (benefit)
tableHTML += `
| ${set.setName} |
${set.freeService.name}: $${freeEffCost.toFixed(2)} |
${set.paidService.name}: $${Math.abs(paidNetEffValue).toFixed(2)} ${paidNetEffValue < 0 ? '(Net Benefit)' : paidNetEffValue > 0 ? '(Net Cost)' : '(Breakeven)'} |
${set.analysis.recommendedOption} |
`;
});
tableHTML += `
`;
container.innerHTML = tableHTML;
document.getElementById('downloadComparerPdfButton').disabled = false;
}
// --- PDF Generation ---
function downloadComparerPdf() {
const analyzedSets = comparisonSets.filter(s => s.analysis && s.paidService.featuresValue && s.paidService.featuresValue.totalValue !== undefined);
if (analyzedSets.length === 0) {
alert("Please fully analyze at least one comparison set 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("Free vs. Paid Services: Cost-Benefit Analysis", 14, yPos); yPos += 8;
doc.setFontSize(10); doc.setTextColor(textColor);
doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 14, yPos); yPos += 7;
doc.text(`Your Value of Time: $${(parseFloat(document.getElementById('valuePerHourGlobal').value) || 0).toFixed(2)}/hour`, 14, yPos); yPos += 10;
analyzedSets.forEach((set, index) => {
if (yPos > 240 && index > 0) { doc.addPage(); yPos = 20; } // New page if needed
doc.setFontSize(14); doc.setTextColor(primaryColor);
doc.text(`Comparison Set: ${set.setName}`, 14, yPos); yPos += 7;
// Free Service Details
doc.setFontSize(11); doc.setTextColor(textColor); doc.setFont(undefined, 'bold');
doc.text(`Free Service: ${set.freeService.name}`, 14, yPos); yPos += 5; doc.setFont(undefined, 'normal');
let freeBody = [
['Direct Monetary Cost/month:', `$${set.freeService.monetaryCostMonthly.toFixed(2)}`],
['Time Cost (Ads/Interrupts):', `${set.freeService.timeCostAdsHours} hrs/month`],
['Time Cost (Workarounds):', `${set.freeService.timeCostWorkaroundsHours} hrs/month`],
['Monetized Time Cost:', `$${((set.freeService.timeCostAdsHours + set.freeService.timeCostWorkaroundsHours) * set.valuePerHour).toFixed(2)}/month`],
['Cost of Add-ons/month:', `$${set.freeService.addOnsCostMonthly.toFixed(2)}`],
[{content: 'Total Effective Monthly Cost (Free):', styles:{fontStyle:'bold'}}, {content: `$${set.freeService.totalEffectiveMonthlyCost.toFixed(2)}`, styles:{fontStyle:'bold'}}]
];
doc.autoTable({ startY: yPos, body: freeBody, theme: 'plain', styles: {fontSize:9, cellPadding:1}, columnStyles: {0:{fontStyle:'bold'}}});
yPos = doc.lastAutoTable.finalY + 7;
if (yPos > 260) { doc.addPage(); yPos = 20; }
// Paid Service Details
doc.setFontSize(11); doc.setTextColor(textColor); doc.setFont(undefined, 'bold');
doc.text(`Paid Service: ${set.paidService.name}`, 14, yPos); yPos += 5; doc.setFont(undefined, 'normal');
let paidBody = [
['Subscription Cost:', `$${set.paidService.subscriptionCost.toFixed(2)} (${set.paidService.billingCycle})`],
['Effective Monthly Subscription Cost:', `$${set.paidService.effectiveMonthlySubscriptionCost.toFixed(2)}`],
['--- Valued Benefits of Paid Service ---', ''],
['Increased Efficiency/Productivity:', `$${set.paidService.featuresValue.efficiencyGainValue.toFixed(2)}/month`],
['Value of Premium Features:', `$${set.paidService.featuresValue.premiumFeaturesValue.toFixed(2)}/month`],
['Value of Better Support/Reliability:', `$${set.paidService.featuresValue.supportValue.toFixed(2)}/month`],
['Value of Ad-Free/Better UX:', `$${set.paidService.featuresValue.adFreeValue.toFixed(2)}/month`],
['Other Quantifiable Benefits:', `$${set.paidService.featuresValue.otherBenefitsValue.toFixed(2)}/month`],
[{content: 'Total Quantified Value of Benefits:', styles:{fontStyle:'bold'}}, {content: `$${set.paidService.featuresValue.totalValue.toFixed(2)}/month`, styles:{fontStyle:'bold'}}],
[{content: 'Net Effective Value/Cost (Paid):', styles:{fontStyle:'bold'}},
{content: `$${Math.abs(set.paidService.netEffectiveCost).toFixed(2)} ${set.paidService.netEffectiveCost < 0 ? '(Net Benefit)' : set.paidService.netEffectiveCost > 0 ? '(Net Cost)' : '(Breakeven)'}`, styles:{fontStyle:'bold'}}]
];
doc.autoTable({ startY: yPos, body: paidBody, theme: 'plain', styles: {fontSize:9, cellPadding:1}, columnStyles: {0:{fontStyle:'bold'}}});
yPos = doc.lastAutoTable.finalY + 7;
if (yPos > 260) { doc.addPage(); yPos = 20; }
// Feature Comparison Rows (if any)
if(set.featureComparisonRows && set.featureComparisonRows.filter(fr => fr.featureName.trim() !== '').length > 0){
doc.setFontSize(10); doc.setTextColor(textColor); doc.setFont(undefined, 'bold');
doc.text("Key Feature Differences:", 14, yPos); yPos+=5; doc.setFont(undefined, 'normal');
const featureTableBody = set.featureComparisonRows
.filter(fr => fr.featureName.trim() !== '')
.map(fr => [fr.featureName, fr.freeValue, fr.paidValue]);
doc.autoTable({
startY: yPos,
head: [['Feature', 'Free Version Offers', 'Paid Version Offers']],
body: featureTableBody,
theme: 'grid',
headStyles: {fillColor: tableHeaderColor, textColor: textColor, fontSize:8.5, fontStyle:'bold'},
styles: {fontSize:8, cellPadding:1.5}
});
yPos = doc.lastAutoTable.finalY + 7;
}
// Recommendation for this set
doc.setFontSize(10); doc.setFont(undefined, 'bold');
doc.text(`Recommendation for ${set.setName}: ${set.analysis.recommendedOption}`, 14, yPos); yPos += 10;
});
// Overall Summary Table (if multiple sets analyzed)
if (analyzedSets.length > 1) {
if (yPos > 230) { doc.addPage(); yPos = 20; }
doc.setFontSize(14); doc.setTextColor(primaryColor);
doc.text("Overall Comparison Summary", 14, yPos); yPos += 7;
const summaryPdfBody = analyzedSets.map(set => [
set.setName,
`$${set.freeService.totalEffectiveMonthlyCost.toFixed(2)}`,
`$${Math.abs(set.paidService.netEffectiveCost).toFixed(2)} ${set.paidService.netEffectiveCost < 0 ? '(Net Benefit)' : set.paidService.netEffectiveCost > 0 ? '(Net Cost)' : '(Breakeven)'}`,
set.analysis.recommendedOption
]);
doc.autoTable({
startY: yPos,
head: [['Comparison Set', 'Free Service (Effective Cost)', 'Paid Service (Net Value/Cost)', 'Recommendation']],
body: summaryPdfBody,
theme: 'grid',
headStyles: { fillColor: tableHeaderColor, textColor: textColor, fontStyle: 'bold', fontSize:9 },
styles: { fontSize: 8, cellPadding: 1.5 },
columnStyles: {1:{halign:'right'}, 2:{halign:'right'}}
});
}
doc.save("Free_vs_Paid_Services_Analysis.pdf");
}
// Initialize
updateComparerNavButtons();
populateComparisonSetSelects();