Long-Term Financial Goals Budget Planner
Financial Assumptions & Budget
Define Your Long-Term Financial Goals
No goals added yet.
Savings Plan & Analysis
Add goals in Tab 2 to see the savings plan.
Report Summary
A summary of your financial goals plan will appear here.
Budget analysis requires goals and an optional budget input.
'; return; } let totalReqMonthly = 0; let totalReqAnnual = 0; let tableHTML = `Detailed Savings Plan:
| Goal | Future Cost ($) | FV of Saved ($) | Net Needed ($) | Req. Annual Saving ($) | Req. Monthly Saving ($) |
|---|---|---|---|---|---|
| ${details.name} | ${details.futureCost.toFixed(2)} | ${details.fvOfSaved.toFixed(2)} | ${details.netNeeded.toFixed(2)} | ${details.reqAnnualSaving.toFixed(2)} | ${details.reqMonthlySaving.toFixed(2)} |
Budget Analysis
Your Stated Monthly Budget for Goals: $${monthlyBudgetForGoals.toFixed(2)}
Total Required Monthly Savings for Goals: $${totalReqMonthly.toFixed(2)}
`; if (difference >= 0) { analysisHTML += `Status: Surplus of $${difference.toFixed(2)} per month. You are on track or have extra!
`; } else { analysisHTML += `Status: Shortfall of $${Math.abs(difference).toFixed(2)} per month. You may need to adjust your budget or goals.
`; } budgetAnalysisDisplay.innerHTML = analysisHTML; } else { budgetAnalysisDisplay.innerHTML = `Enter a 'Total Monthly Amount Available for Goals' in Tab 1 for a budget analysis.
`; } return processedGoals; // Return for PDF } // --- Report & Export (Tab 4) --- function ltfg_generateReportPreview() { const previewDiv = document.getElementById('ltfgReportPreview'); const inflationRate = ltfg_getFloatValue('ltfgInflationRate', 3); const returnRate = ltfg_getFloatValue('ltfgReturnRate', 6); const monthlyBudgetForGoals = ltfg_getFloatValue('ltfgMonthlyBudgetForGoals', 0); if (ltfg_financialGoals.length === 0) { previewDiv.innerHTML = "Add goals to generate a plan preview.
"; return; } let totalReqMonthly = 0; ltfg_financialGoals.forEach(goal => { const details = ltfg_calculateGoalDetails(goal, inflationRate, returnRate); totalReqMonthly += details.reqMonthlySaving; }); let html = `Plan Overview
Inflation Rate Assumed: ${inflationRate.toFixed(2)}%
Investment Return Rate Assumed: ${returnRate.toFixed(2)}%
Number of Goals Defined: ${ltfg_financialGoals.length}
Total Required Monthly Savings for All Goals: $${totalReqMonthly.toFixed(2)}
`; if (monthlyBudgetForGoals > 0) { html += `Your Stated Monthly Budget for Goals: $${monthlyBudgetForGoals.toFixed(2)}
`; const difference = monthlyBudgetForGoals - totalReqMonthly; if (difference >= 0) { html += `Budget Status: Surplus of $${difference.toFixed(2)}/month.
`; } else { html += `Budget Status: Shortfall of $${Math.abs(difference).toFixed(2)}/month.
`; } } html += `The full PDF will contain detailed breakdowns for each goal.
`; previewDiv.innerHTML = html; } function ltfg_generatePdf() { const inflationRate = ltfg_getFloatValue('ltfgInflationRate', 3); const returnRate = ltfg_getFloatValue('ltfgReturnRate', 6); const monthlyBudgetForGoals = ltfg_getFloatValue('ltfgMonthlyBudgetForGoals', 0); const processedGoals = ltfg_financialGoals.map(goal => ltfg_calculateGoalDetails(goal, inflationRate, returnRate)); if (processedGoals.length === 0) { alert("Please add some goals before generating a PDF."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); let yPos = 20; const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim(); const accentColor = getComputedStyle(document.documentElement).getPropertyValue('--accent-color').trim(); const dangerColor = getComputedStyle(document.documentElement).getPropertyValue('--danger-color').trim(); const textColor = getComputedStyle(document.documentElement).getPropertyValue('--text-color').trim(); const toCurrency = (num) => `$${num.toFixed(2)}`; doc.setFontSize(20); doc.setTextColor(primaryColor); doc.text("Long-Term Financial Goals Budget Plan", doc.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += 15; doc.setFontSize(12); doc.setTextColor(textColor); doc.text(`Financial Assumptions: Inflation ${inflationRate.toFixed(2)}%, Investment Return ${returnRate.toFixed(2)}%`, 14, yPos); yPos += 10; if (processedGoals.length > 0) { doc.setFontSize(14); doc.setTextColor(primaryColor); doc.text("Detailed Goal Savings Plan", 14, yPos); yPos += 8; const tableBody = processedGoals.map(g => [ g.name, toCurrency(g.targetAmountToday), g.yearsUntilGoal, toCurrency(g.alreadySaved), toCurrency(g.futureCost), toCurrency(g.fvOfSaved), toCurrency(g.netNeeded), toCurrency(g.reqAnnualSaving), toCurrency(g.reqMonthlySaving) ]); doc.autoTable({ startY: yPos, head: [['Goal', 'Target (Today\'s $)', 'Years', 'Saved ($)', 'Future Cost ($)', 'FV of Saved ($)', 'Net Needed ($)', 'Req. Annual ($)', 'Req. Monthly ($)']], body: tableBody, theme: 'grid', headStyles: { fillColor: primaryColor, textColor: '#ffffff' }, styles: { fontSize: 7.5, cellPadding: 1.5, overflow: 'linebreak' }, // smaller font for more columns columnStyles: { 0: {cellWidth: 25}, 2: {cellWidth: 10}, 3: {cellWidth:18}, 4:{cellWidth:22}, 5:{cellWidth:22}, 6:{cellWidth:22}, 7:{cellWidth:22}, 8:{cellWidth:22}}, didDrawPage: (data) => { yPos = data.cursor.y; } }); yPos = doc.lastAutoTable.finalY + 10; } if (yPos > 260) { doc.addPage(); yPos = 20; } doc.setFontSize(14); doc.setTextColor(primaryColor); doc.text("Overall Savings & Budget Summary", 14, yPos); yPos += 8; doc.setFontSize(11); doc.setTextColor(textColor); const totalReqMonthly = processedGoals.reduce((sum, g) => sum + g.reqMonthlySaving, 0); const totalReqAnnual = processedGoals.reduce((sum, g) => sum + g.reqAnnualSaving, 0); doc.text(`Total Required Monthly Savings for All Goals: ${toCurrency(totalReqMonthly)}`, 14, yPos); yPos += 7; doc.text(`Total Required Annual Savings for All Goals: ${toCurrency(totalReqAnnual)}`, 14, yPos); yPos += 7; if (monthlyBudgetForGoals > 0) { doc.text(`Your Stated Monthly Budget for Goals: ${toCurrency(monthlyBudgetForGoals)}`, 14, yPos); yPos += 7; const difference = monthlyBudgetForGoals - totalReqMonthly; if (difference >= 0) { doc.setTextColor(accentColor); doc.text(`Budget Status: Surplus of ${toCurrency(difference)} per month.`, 14, yPos); } else { doc.setTextColor(dangerColor); doc.text(`Budget Status: Shortfall of ${toCurrency(Math.abs(difference))} per month.`, 14, yPos); } } doc.setTextColor(textColor); doc.save('long_term_goals_budget_plan.pdf'); } // Initialize document.addEventListener('DOMContentLoaded', () => { ltfg_showTab(0); ltfg_renderGoalsList(); // For empty state initially // Demo data ltfg_financialGoals.push({id: 'goal_001', name: 'House Down Payment', targetAmountToday: 60000, yearsUntilGoal: 5, alreadySaved: 10000}); ltfg_financialGoals.push({id: 'goal_002', name: 'Child\'s College Fund Start', targetAmountToday: 20000, yearsUntilGoal: 10, alreadySaved: 2000}); ltfg_renderGoalsList(); });