Passive Income vs. Active Income Budget Tool
Monthly Income Sources
Active Income
No active income sources added.
Passive Income
No passive income sources added.
Monthly Expenses
No expenses added yet.
Budget Analysis & Insights
Analysis Report
A summary of your income and expense analysis will appear here.
Enter income and expenses to see the report preview.
"; return;} previewDiv.innerHTML = `Financial Snapshot
Total Monthly Income: $${analysisData.totalIncome.toFixed(2)} (Active: $${analysisData.totalActiveIncome.toFixed(2)}, Passive: $${analysisData.totalPassiveIncome.toFixed(2)})
Total Monthly Expenses: $${analysisData.totalExpenses.toFixed(2)}
Net Monthly Savings: $${analysisData.netMonthlySavings.toFixed(2)}
Overall Savings Rate: ${analysisData.overallSavingsRate.toFixed(2)}%
Passive Income Analysis
Expenses Covered by Passive Income: ${analysisData.passiveCoveragePercentage.toFixed(2)}%
Passive Income Surplus/(Deficit): $${analysisData.passiveSurplusDeficit.toFixed(2)}
Full details including itemized lists will be in the PDF.
`; } function paib_generatePdf() { const analysisData = paib_calculateAndDisplayAnalysis(); if (!analysisData) { alert("Please ensure data is entered for analysis."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); let yPos = 20; const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim(); const passiveColor = getComputedStyle(document.documentElement).getPropertyValue('--passive-income-color').trim(); const activeColor = getComputedStyle(document.documentElement).getPropertyValue('--active-income-color').trim(); const expenseColor = getComputedStyle(document.documentElement).getPropertyValue('--expense-color').trim(); const textColor = getComputedStyle(document.documentElement).getPropertyValue('--text-color').trim(); const toCurrency = (num) => `$${num.toFixed(2)}`; doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Passive vs. Active Income Budget Analysis", doc.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += 15; function addSection(title, items, itemTotal, titleColor = primaryColor) { if (yPos > 250 && items.length > 0) { doc.addPage(); yPos = 20; } doc.setFontSize(14); doc.setTextColor(titleColor); doc.text(title, 14, yPos); yPos += 7; if (items.length > 0) { const tableBody = items.map(item => [item.name, toCurrency(item.amount)]); doc.autoTable({ startY: yPos, head: [['Source/Category', 'Monthly Amount ($)']], body: tableBody, theme: 'grid', headStyles: { fillColor: titleColor, textColor: '#ffffff' }, styles: { fontSize: 9, cellPadding: 2 }, didDrawPage: (d) => { yPos = d.cursor.y; } }); yPos = doc.lastAutoTable.finalY + 5; doc.setFontSize(10); doc.setTextColor(textColor); doc.setFont(undefined, 'bold'); doc.text(`Total Monthly ${title}: ${toCurrency(itemTotal)}`, 14, yPos); yPos += 8; doc.setFont(undefined, 'normal'); } else { doc.setFontSize(10); doc.setTextColor(textColor); doc.text(`No ${title.toLowerCase()} items added.`, 14, yPos); yPos += 7; } } addSection("Active Income", paib_activeIncomes, analysisData.totalActiveIncome, activeColor); addSection("Passive Income", paib_passiveIncomes, analysisData.totalPassiveIncome, passiveColor); addSection("Expenses", paib_expenses, analysisData.totalExpenses, expenseColor); if (yPos > 240) { doc.addPage(); yPos = 20; } doc.setFontSize(14); doc.setTextColor(primaryColor); doc.text("Overall Financial Summary", 14, yPos); yPos += 8; doc.setFontSize(10); doc.setTextColor(textColor); doc.text(`Total Monthly Income: ${toCurrency(analysisData.totalIncome)}`, 14, yPos); yPos += 6; doc.text(`Total Monthly Expenses: ${toCurrency(analysisData.totalExpenses)}`, 14, yPos); yPos += 6; doc.text(`Net Monthly Savings: ${toCurrency(analysisData.netMonthlySavings)}`, 14, yPos); yPos += 6; doc.text(`Overall Savings Rate: ${analysisData.overallSavingsRate.toFixed(2)}%`, 14, yPos); yPos += 8; doc.setFontSize(12); doc.setTextColor(primaryColor); doc.text("Passive Income Analysis", 14, yPos); yPos += 7; doc.setFontSize(10); doc.setTextColor(textColor); doc.text(`Percentage of Expenses Covered by Passive Income: ${analysisData.passiveCoveragePercentage.toFixed(2)}%`, 14, yPos); yPos += 6; doc.text(`Surplus/(Deficit) if Living Only on Passive Income: ${toCurrency(analysisData.passiveSurplusDeficit)}`, 14, yPos); yPos += 6; const targetPI = paib_getFloatValue('paibTargetPassiveIncome', 0); if (targetPI > 0) { const progressToTarget = analysisData.totalPassiveIncome / targetPI * 100; doc.text(`Progress Towards Target Monthly Passive Income ($${targetPI.toFixed(2)}): ${progressToTarget.toFixed(1)}%`, 14, yPos); yPos +=6; } doc.save('passive_vs_active_income_analysis.pdf'); } // Initialize document.addEventListener('DOMContentLoaded', () => { paib_showTab(0); paib_renderIncomeLists(); paib_updateTotalIncomeDisplays(); paib_renderExpenses(); paib_updateTotalExpensesDisplay(); // Demo Data paib_activeIncomes.push({id:'act_inc_001', name:'Main Job Salary', amount: 5000}); paib_passiveIncomes.push({id:'pas_inc_001', name:'Rental Unit 1', amount: 700}); paib_passiveIncomes.push({id:'pas_inc_002', name:'Stock Dividends (Avg)', amount: 150}); paib_expenses.push({id:'exp_001', name:'Mortgage/Rent', amount:1800}); paib_expenses.push({id:'exp_002', name:'Utilities', amount:250}); paib_expenses.push({id:'exp_003', name:'Groceries & Food', amount:600}); paib_renderIncomeLists(); paib_updateTotalIncomeDisplays(); paib_renderExpenses(); paib_updateTotalExpensesDisplay(); });