174 lines
6.9 KiB
JavaScript
174 lines
6.9 KiB
JavaScript
const ObjectId = require('mongodb').ObjectId;
|
|
|
|
async function calculatePlanProgress(plans, assets, userId) {
|
|
if (!plans || typeof plans.retirementAssets === 'undefined') {
|
|
console.error("Invalid plan document provided to calculatePlanProgress:", plans);
|
|
return 0;
|
|
}
|
|
if (!assets || typeof assets.find !== 'function') {
|
|
console.error("Invalid assetsCollection provided to calculatePlanProgress");
|
|
return 0;
|
|
}
|
|
|
|
try {
|
|
const userAssets = await assets.find({ userId: new ObjectId(userId) }).toArray();
|
|
const totalUserAssetValue = await calculateTotalAssetValue(userAssets);
|
|
let percentage = 0;
|
|
|
|
if (plans.retirementAssets > 0) {
|
|
percentage = (totalUserAssetValue / plans.retirementAssets) * 100;
|
|
}
|
|
return percentage;
|
|
} catch (err) {
|
|
console.error("Error in calculatePlanProgress:", err);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function updatePlanProgressInDB(planId, percentage, plans) {
|
|
if (!plans || typeof plans.updateOne !== 'function') {
|
|
console.error("Error with the plans collection");
|
|
return;
|
|
}
|
|
if (typeof percentage !== 'number' || isNaN(percentage)) {
|
|
console.error(`Error with the percentage: ${percentage}`);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await plans.updateOne({ _id: new ObjectId(planId) }, { $set: { progress: parseFloat(percentage.toFixed(2)) } });
|
|
} catch (err) {
|
|
console.error("Error in updatePlanProgressInDB:", err);
|
|
}
|
|
}
|
|
|
|
async function calculateTotalAssetValue(assets) {
|
|
if (!assets || typeof assets.find !== 'function') {
|
|
console.error("Error with the assets collection");
|
|
return 0;
|
|
}
|
|
try {
|
|
let totalAssetValue = 0;
|
|
const today = new Date();
|
|
|
|
for (const asset of assets) {
|
|
if (asset.icon === "Motorcycle" || asset.icon === "Car") {
|
|
if (asset.value < 1000) {
|
|
totalAssetValue += asset.value;
|
|
} else {
|
|
const assetYear = asset.year;
|
|
const age = today.getFullYear() - assetYear;
|
|
let depreciatedValue;
|
|
|
|
if (age < 1){
|
|
depreciatedValue = asset.value * 0.9;
|
|
}else{
|
|
depreciatedValue = asset.value * Math.pow(0.90, age);
|
|
}
|
|
|
|
if (depreciatedValue < 1000) {
|
|
totalAssetValue += 1000;
|
|
} else {
|
|
totalAssetValue += depreciatedValue;
|
|
}
|
|
}
|
|
} else {
|
|
totalAssetValue += asset.value;
|
|
}
|
|
}
|
|
return totalAssetValue;
|
|
} catch (err) {
|
|
console.error("Error in calculateTotalAssetValue:", err);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
async function calculateProgress(plan, assets, users, userId) {
|
|
if (!plan || typeof plan !== 'object') {
|
|
console.error("Error with the plan");
|
|
return;
|
|
}
|
|
if (!assets || typeof assets.find !== 'function') {
|
|
console.error("Error with the assets collection");
|
|
return;
|
|
}
|
|
if (!users || typeof users.findOne !== 'function') {
|
|
console.error("Error with the users collection");
|
|
return;
|
|
}
|
|
if (!userId) {
|
|
console.error("No user ID provided");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const userAssets = await assets.find({ userId: new ObjectId(userId) }).toArray();
|
|
const totalUserAssetValue = await calculateTotalAssetValue(userAssets);
|
|
const totalUserPlanValue = plan.retirementAssets;
|
|
|
|
|
|
const userDoc = await users.findOne({ _id: new ObjectId(userId) });
|
|
|
|
if (!userDoc || !userDoc.dob) {
|
|
console.error("[calculateProgress] User document or DOB not found for userId:", userId);
|
|
// Ensure a structured return even on error to avoid undefined.progress issues
|
|
return { monthlyInvestment: NaN, totalCostOfRetirement: NaN, monthsUntilRetirement: NaN, yearsRetired: NaN, yearsUntilRetirement: NaN, percentage: NaN };
|
|
}
|
|
const userDob = new Date(userDoc.dob);
|
|
|
|
if (isNaN(userDob.getTime())) {
|
|
console.error("[calculateProgress] userDob is an invalid date. Aborting calculation.");
|
|
return { monthlyInvestment: NaN, totalCostOfRetirement: NaN, monthsUntilRetirement: NaN, yearsRetired: NaN, yearsUntilRetirement: NaN, percentage: NaN };
|
|
}
|
|
|
|
const today = new Date();
|
|
const userUnalivedBy = new Date(userDob);
|
|
userUnalivedBy.setFullYear(userUnalivedBy.getFullYear() + 90);
|
|
const yearOfRetirement = userDob.getFullYear() + plan.retirementAge;
|
|
const monthsUntilRetirement = (yearOfRetirement - today.getFullYear()) * 12;
|
|
const yearsRetired = userUnalivedBy.getFullYear() - yearOfRetirement;
|
|
|
|
const totalCostOfRetirement = ((plan.retirementExpenses + plan.retirementLiabilities) * 12) * yearsRetired;
|
|
|
|
const monthlyInvestment = (totalUserPlanValue - totalUserAssetValue + totalCostOfRetirement) / monthsUntilRetirement;
|
|
|
|
const percentageCalculated = (totalUserAssetValue / (totalUserPlanValue + totalCostOfRetirement)) * 100;
|
|
|
|
if (monthsUntilRetirement <= 0) {
|
|
return { monthlyInvestment: 0, totalCostOfRetirement: totalCostOfRetirement, monthsUntilRetirement: 0, yearsRetired: yearsRetired, yearsUntilRetirement: 0, percentage: 0 };
|
|
}
|
|
|
|
const progress = {};
|
|
|
|
progress.monthlyInvestment = Math.round(monthlyInvestment);
|
|
progress.totalCostOfRetirement = totalCostOfRetirement;
|
|
progress.monthsUntilRetirement = monthsUntilRetirement;
|
|
progress.yearsRetired = yearsRetired;
|
|
progress.yearsUntilRetirement = (yearOfRetirement - today.getFullYear());
|
|
progress.percentage = percentageCalculated;
|
|
|
|
return progress;
|
|
|
|
} catch (err) {
|
|
console.error("Error in calculateProgress:", err);
|
|
// Ensure a structured return even on error to avoid undefined.progress issues
|
|
return { monthlyInvestment: NaN, totalCostOfRetirement: NaN, monthsUntilRetirement: NaN, yearsRetired: NaN, yearsUntilRetirement: NaN, percentage: NaN };
|
|
}
|
|
}
|
|
|
|
async function updateProgress(plans, assets, users, userId) {
|
|
const userPlansFromDB = await plans.find({ userId: new ObjectId(userId) }).toArray();
|
|
|
|
for (const plan of userPlansFromDB) {
|
|
const progress = await calculateProgress(plan, assets, users, userId);
|
|
await updatePlanProgressInDB(plan._id, progress.percentage, plans);
|
|
}
|
|
|
|
const updatedUserPlans = await plans.find({ userId: new ObjectId(userId) }).toArray();
|
|
return updatedUserPlans;
|
|
}
|
|
|
|
|
|
|
|
module.exports = { calculatePlanProgress, updatePlanProgressInDB, calculateTotalAssetValue, calculateProgress, updateProgress}; |