dev1/src/utils/FinancialProjectionService.js

138 lines
4.9 KiB
JavaScript

import moment from 'moment';
// Function to simulate monthly financial projection
// src/utils/FinancialProjectionService.js
export function simulateFinancialProjection(userProfile) {
const {
currentSalary,
monthlyExpenses,
monthlyDebtPayments,
studentLoanAmount,
interestRate, // ✅ Corrected
loanTerm, // ✅ Corrected
extraPayment,
expectedSalary,
emergencySavings,
retirementSavings,
monthlyRetirementContribution,
monthlyEmergencyContribution,
gradDate,
fullTimeCollegeStudent: inCollege,
partTimeIncome,
startDate,
programType,
isFullyOnline,
creditHoursPerYear,
calculatedTuition,
hoursCompleted,
loanDeferralUntilGraduation,
programLength
} = userProfile;
const monthlyLoanPayment = calculateLoanPayment(studentLoanAmount, interestRate, loanTerm);
let totalEmergencySavings = emergencySavings;
let totalRetirementSavings = retirementSavings;
let loanBalance = studentLoanAmount;
let projectionData = [];
const graduationDate = gradDate ? new Date(gradDate) : null;
let milestoneIndex = 0;
let loanPaidOffMonth = null;
// Dynamic credit hours based on the program type
let requiredCreditHours;
switch (programType) {
case "Associate Degree":
requiredCreditHours = 60;
break;
case "Bachelor's Degree":
requiredCreditHours = 120;
break;
case "Master's Degree":
requiredCreditHours = 30;
break;
case "Doctoral Degree":
requiredCreditHours = 60;
break;
default:
requiredCreditHours = 120;
}
const remainingCreditHours = requiredCreditHours - hoursCompleted;
const programDuration = Math.ceil(remainingCreditHours / creditHoursPerYear);
const tuitionCost = calculatedTuition;
const totalTuitionCost = tuitionCost * programDuration;
const date = new Date(startDate);
for (let month = 0; month < 240; month++) {
date.setMonth(date.getMonth() + 1);
if (loanBalance <= 0 && !loanPaidOffMonth) {
loanPaidOffMonth = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
}
let tuitionCostThisMonth = 0;
if (inCollege && !loanDeferralUntilGraduation) {
tuitionCostThisMonth = totalTuitionCost / programDuration / 12;
}
let thisMonthLoanPayment = 0;
if (loanDeferralUntilGraduation && graduationDate && date < graduationDate) {
const interestForMonth = loanBalance * (interestRate / 100 / 12); // ✅ Corrected here
loanBalance += interestForMonth;
} else if (loanBalance > 0) {
const interestForMonth = loanBalance * (interestRate / 100 / 12); // ✅ Corrected here
const principalForMonth = Math.min(loanBalance, monthlyLoanPayment + extraPayment - interestForMonth);
loanBalance -= principalForMonth;
loanBalance = Math.max(loanBalance, 0);
thisMonthLoanPayment = monthlyLoanPayment + extraPayment;
}
const salaryNow = graduationDate && date >= graduationDate ? expectedSalary : currentSalary;
const totalMonthlyExpenses = monthlyExpenses
+ tuitionCostThisMonth
+ monthlyDebtPayments
+ thisMonthLoanPayment;
const monthlyIncome = salaryNow / 12;
let extraCash = monthlyIncome - totalMonthlyExpenses - monthlyRetirementContribution - monthlyEmergencyContribution;
extraCash = Math.max(extraCash, 0);
// update savings explicitly with contributions first
totalEmergencySavings += monthlyEmergencyContribution + (extraCash * 0.3);
totalRetirementSavings += monthlyRetirementContribution + (extraCash * 0.7);
totalRetirementSavings *= (1 + 0.07 / 12);
// netSavings calculation fixed
projectionData.push({
month: `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`,
salary: salaryNow,
monthlyIncome: monthlyIncome,
expenses: totalMonthlyExpenses,
loanPayment: thisMonthLoanPayment,
retirementContribution: monthlyRetirementContribution,
emergencyContribution: monthlyEmergencyContribution,
netSavings: monthlyIncome - totalMonthlyExpenses, // Exclude contributions here explicitly!
totalEmergencySavings,
totalRetirementSavings,
loanBalance
});
}
return { projectionData, loanPaidOffMonth, emergencySavings };
}
function calculateLoanPayment(principal, annualRate, years) {
const monthlyRate = annualRate / 100 / 12;
const numPayments = years * 12;
return (principal * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -numPayments));
}