Skip to content

Commit

Permalink
Merge pull request #294 from tahmid-saj/dev-ts-utils
Browse files Browse the repository at this point in the history
migrating savings utils to ts
  • Loading branch information
tahmid-saj authored Sep 21, 2024
2 parents 1169cc3 + a8a9a57 commit 90b9836
Show file tree
Hide file tree
Showing 21 changed files with 138 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ReactApexChart from 'react-apexcharts';
import { MarketDataContext } from "../../../../contexts/shared/market-data/market-data.context";
import { Fragment, useContext } from "react";

import { MARKET_DATA_INTERVALS } from "../../../../utils/constants/market-data.constants";
import { MARKET_DATA_INTERVALS } from "../../../../utils/constants/market-data.constants.js";
import { Divider } from "@mui/material";
import { COLOR_CODES, COMMON_SPACING } from "../../../../utils/constants/shared.constants.js";
import SimplePaper from "../../mui/paper/paper.component.jsx";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const calculateSavingsGoalHelper = (savingsGoalResult: SavingsGoalResult | undef
})
}

const calculateSavingsGoalScheduleHelper = (savingsGoalResult: SavingsGoalResult | undefined): SavingsGoalScheduleResult[] | undefined => {
const calculateSavingsGoalScheduleHelper = (savingsGoalResult: SavingsGoalResult): SavingsGoalScheduleResult[] | undefined => {
return calculateSavingsGoalSchedule(savingsGoalResult)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ export type SavingsGoalScheduleResult = {
interestEarned: number,
totalInterestEarned: number,
balance: number
}
}

6 changes: 3 additions & 3 deletions src/contexts/signed-in/savings/savings.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { DEFAULT_SAVINGS_ACCOUNTS, DEFAULT_SAVINGS_ACCOUNTS_SUMMARY } from "../.

import { useSelector } from "react-redux";
import { selectCurrentUser } from "../../../store/shared/user/user.selector";
import { SavingsAccount, SavingsAccountsSummary, SavingsContextType, SavingsProviderProps } from "./savings.types";
import { SavingsAccount, SavingsAccountInfo, SavingsAccountsSummary, SavingsContextType, SavingsProviderProps } from "./savings.types";

// helper functions

Expand Down Expand Up @@ -89,8 +89,8 @@ const updateSavingsAccountHelper = (savingsAccounts: SavingsAccount[], originalS
return savingsAccount.savingsAccountName === originalSavingsAccountName;
});

const savingsAccountInfo = {
originalSavingsAccountInfo: originalSavingsAccount,
const savingsAccountInfo: SavingsAccountInfo = {
originalSavingsAccountInfo: originalSavingsAccount as SavingsAccount,
updatedSavingsAccountInfo: {
...updatedSavingsAccount,

Expand Down
13 changes: 13 additions & 0 deletions src/contexts/signed-in/savings/savings.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ export type SavingsAccount = {
savings: SavingsCalculationRecord[];
}

export type SavingsAccountCalculated = {
totalSavings: number;
totalContribution: number;
totalInterest: number;

savings: SavingsCalculationRecord[];
}

export interface SavingsContextType {
savingsAccounts: SavingsAccount[];

Expand Down Expand Up @@ -48,4 +56,9 @@ export type SavingsAccountsSummary = {
currentAllSavingsAccountsBalance?: number;
totalAllContribution?: number;
totalAllInterest?: number;
}

export type SavingsAccountInfo = {
originalSavingsAccountInfo: SavingsAccount;
updatedSavingsAccountInfo: SavingsAccount;
}
8 changes: 8 additions & 0 deletions src/contexts/signed-out/savings/savings.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ export type SavingsAccount = {
savings: SavingsCalculationRecord[];
}

export type SavingsAccountCalculated = {
totalSavings: number;
totalContribution: number;
totalInterest: number;

savings: SavingsCalculationRecord[];
}

export interface SavingsContextType {
savingsAccounts: SavingsAccount[];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { calculateSavingsGoal as _calculateSavingsGoal,
import { ActionWithPayload, createAction, withMatcher } from "../../../utils/reducer/reducer.utils";
import { SAVINGS_GOAL_CALCULATOR_ACTION_TYPES, SavingsGoalResult, SavingsGoalScheduleResult } from "./savings-goal-calculator.types";

export type CalculateSavingsGoal = ActionWithPayload<SAVINGS_GOAL_CALCULATOR_ACTION_TYPES.SET_SAVINGS_GOAL_RESULT, SavingsGoalResult>
export type CalculateSavingsGoal = ActionWithPayload<SAVINGS_GOAL_CALCULATOR_ACTION_TYPES.SET_SAVINGS_GOAL_RESULT, SavingsGoalResult | undefined>
export type CalculateSavingsGoalSchedule = ActionWithPayload<SAVINGS_GOAL_CALCULATOR_ACTION_TYPES.SET_SAVINGS_GOAL_SCHEDULE_RESULT, SavingsGoalScheduleResult[]>

type SavingsGoalInput = {
Expand All @@ -19,7 +19,7 @@ type SavingsGoalInput = {
}

// helper functions
const calculateSavingsGoalHelper = (savingsGoalResult: SavingsGoalResult, savingsGoalInput: SavingsGoalInput): SavingsGoalResult => {
const calculateSavingsGoalHelper = (savingsGoalResult: SavingsGoalResult, savingsGoalInput: SavingsGoalInput): SavingsGoalResult | undefined => {
if (validateSavingsGoalInput(savingsGoalInput)) {
return savingsGoalResult
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { MarketDataQuery } from "../../contexts/shared/market-data/market-data.types";
import { errorOnGetStocksMarketData, errorOnGetIndicesMarketData,
errorOnGetCryptoMarketData, errorOnGetForexMarketData } from "../errors/market-data.errors";

// stocks
export async function getStocksMarketData(marketDataQuery) {
export async function getStocksMarketData(marketDataQuery: MarketDataQuery): Promise<any> {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_MARKET_DATA}${process.env.REACT_APP_API_URL_MARKET_DATA_STOCKS}`, {
Expand All @@ -22,7 +23,7 @@ export async function getStocksMarketData(marketDataQuery) {
}

// indices
export async function getIndicesMarketData(marketDataQuery) {
export async function getIndicesMarketData(marketDataQuery: MarketDataQuery): Promise<any> {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_MARKET_DATA}${process.env.REACT_APP_API_URL_MARKET_DATA_INDICES}`, {
Expand All @@ -42,7 +43,7 @@ export async function getIndicesMarketData(marketDataQuery) {
}

// crypto
export async function getCryptoMarketData(marketDataQuery) {
export async function getCryptoMarketData(marketDataQuery: MarketDataQuery): Promise<any> {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_MARKET_DATA}${process.env.REACT_APP_API_URL_MARKET_DATA_CRYPTO}`, {
Expand All @@ -62,7 +63,7 @@ export async function getCryptoMarketData(marketDataQuery) {
}

// forex
export async function getForexMarketData(marketDataQuery) {
export async function getForexMarketData(marketDataQuery: MarketDataQuery): Promise<any> {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_MARKET_DATA}${process.env.REACT_APP_API_URL_MARKET_DATA_FOREX}`, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { SavingsAccount, SavingsAccountInfo, SavingsAccountsSummary } from "../../contexts/signed-in/savings/savings.types";
import { errorOnGetSavingsAccountsData, errorOnGetSavingsAccountsSummaryData,
errorOnPostSavingsAccountCreate, errorOnPutSavingsAccountData, errorOnSavingsAccountInvestment,
errorOnPutSavingsAccountsData, errorOnPutSavingsAccountsSummaryData } from "../errors/savings.errors";

// savings accounts api requests

// getting savings accounts and summary data on sign in
export const getSavingsAccountsData = async (userId, email) => {
export const getSavingsAccountsData = async (userId: string | null | undefined, email: string | null | undefined): Promise<any> => {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_SAVINGS_ACCOUNTS}/${userId}/${email}`);
Expand All @@ -17,7 +18,7 @@ export const getSavingsAccountsData = async (userId, email) => {
}
};

export const getSavingsAccountsSummaryData = async (userId, email) => {
export const getSavingsAccountsSummaryData = async (userId: string | null | undefined, email: string | null | undefined): Promise<any> => {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_SAVINGS_ACCOUNTS_SUMMARY}/${userId}/${email}`);
Expand All @@ -30,7 +31,8 @@ export const getSavingsAccountsSummaryData = async (userId, email) => {
};

// saving accounts operations
export const postSavingsAccountCreate = async (userId, email, savingsAccountInfo) => {
export const postSavingsAccountCreate = async (userId: string | null | undefined, email: string | null | undefined,
savingsAccountInfo: SavingsAccount): Promise<number | undefined> => {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_SAVINGS_ACCOUNTS}/${userId}/${email}`, {
Expand All @@ -48,7 +50,8 @@ export const postSavingsAccountCreate = async (userId, email, savingsAccountInfo
}
};

export const putSavingsAccountData = async (userId, email, savingsAccountInfo) => {
export const putSavingsAccountData = async (userId: string | null | undefined, email: string | null | undefined,
savingsAccountInfo: SavingsAccountInfo): Promise<number | undefined> => {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_SAVINGS_ACCOUNTS}/${userId}/${email}`, {
Expand All @@ -66,7 +69,8 @@ export const putSavingsAccountData = async (userId, email, savingsAccountInfo) =
}
};

export const deleteSavingsAccount = async (userId, email, closingSavingsAccountName) => {
export const deleteSavingsAccount = async (userId: string | null | undefined, email: string | null | undefined,
closingSavingsAccountName: string): Promise<number | undefined> => {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_SAVINGS_ACCOUNTS}/${userId}/${email}`, {
Expand All @@ -77,15 +81,16 @@ export const deleteSavingsAccount = async (userId, email, closingSavingsAccountN
body: String(closingSavingsAccountName)
});

return response.statusCode;
return response.status;
} catch (error) {
errorOnSavingsAccountInvestment();

}
};

// updating savings accounts and summary data on sign out
export const putSavingsAccountsData = async (userId, email, savingsAccounts) => {
export const putSavingsAccountsData = async (userId: string | null | undefined, email: string | null | undefined,
savingsAccounts: SavingsAccount[]): Promise<number | undefined> => {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_SAVINGS_ACCOUNTS}/${userId}/${email}`, {
Expand All @@ -105,7 +110,8 @@ export const putSavingsAccountsData = async (userId, email, savingsAccounts) =>
}
};

export const putSavingsAccountsSummaryData = async (userId, email, savingsAccountsSummary) => {
export const putSavingsAccountsSummaryData = async (userId: string | null | undefined, email: string | null | undefined,
savingsAccountsSummary: SavingsAccountsSummary): Promise<number | undefined> => {
try {

const response = await fetch(`${process.env.REACT_APP_API_URL_SAVINGS_ACCOUNTS}/${userId}/${email}`, {
Expand Down
38 changes: 30 additions & 8 deletions src/utils/calculations/savings.calculations.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
import { SavingsGoalInput, SavingsGoalResult, SavingsGoalScheduleResult } from "../../contexts/shared/savings-goal-calculator/savings-goal-calculator.types";
import { SavingsAccount } from "../../contexts/signed-in/savings/savings.types";
import { SavingsAccountCalculated } from "../../contexts/signed-out/savings/savings.types";
import { SAVINGS_CONTRIBUTION_INTERVALS, SAVINGS_GOAL_COMPOUNDED,
AVERAGE_DAYS_IN_MONTH
} from "../constants/savings.constants";
import date from 'date-and-time'

type CompoundedInterestInput = {
A: number;
P: number;
r: number;
t: number;
n: number;
}

type SavingsAccountCalculationInput = {
initialDeposit: number;
startDate: string;
monthlyContribution: number;
contributionPeriod: number;
contributionInterval: string;
apy: number;
}

// helper functions
const calculateCompoundedInterestPMT = (compoundedInterestInput) => {
const calculateCompoundedInterestPMT = (compoundedInterestInput: CompoundedInterestInput): number => {
let res = compoundedInterestInput.A
res -= compoundedInterestInput.P * (Math.pow(1 + (compoundedInterestInput.r / compoundedInterestInput.n), compoundedInterestInput.n * compoundedInterestInput.t))
res /= (Math.pow(1 + (compoundedInterestInput.r / compoundedInterestInput.n), compoundedInterestInput.n * compoundedInterestInput.t) - 1) / (compoundedInterestInput.r / compoundedInterestInput.n)

return res
}

const calculateCompoundedInterestA = (compoundedInterestInput, PMT) => {
const calculateCompoundedInterestA = (compoundedInterestInput: CompoundedInterestInput, PMT: number): { interestEarned: number, balance: number } => {
const interestEarned = compoundedInterestInput.P * Math.pow(compoundedInterestInput.r / compoundedInterestInput.n, compoundedInterestInput.n * compoundedInterestInput.t)
const compoundedResult = compoundedInterestInput.P * Math.pow(1 + (compoundedInterestInput.r / compoundedInterestInput.n), compoundedInterestInput.n * compoundedInterestInput.t)
const balance = compoundedResult + PMT
Expand All @@ -23,7 +43,7 @@ const calculateCompoundedInterestA = (compoundedInterestInput, PMT) => {
}
}

const calculatePMTCompoundedInterestA = (compoundedInterestInput, PMT) => {
const calculatePMTCompoundedInterestA = (compoundedInterestInput: CompoundedInterestInput, PMT: number): number => {
let res = compoundedInterestInput.P
res *= Math.pow(1 + (compoundedInterestInput.r / compoundedInterestInput.n), compoundedInterestInput.n * compoundedInterestInput.t)
res += PMT * ((Math.pow(1 + (compoundedInterestInput.r / compoundedInterestInput.n), compoundedInterestInput.n * compoundedInterestInput.t) - 1) / (compoundedInterestInput.r / compoundedInterestInput.n))
Expand All @@ -33,13 +53,14 @@ const calculatePMTCompoundedInterestA = (compoundedInterestInput, PMT) => {

// savings calculations

export const calculateSavings = (savingsAccount) => {
export const calculateSavings = (savingsAccount: SavingsAccountCalculationInput): SavingsAccountCalculated => {
// return calculated totalSavings, totalContribution, totalInterest

let resSavings = []
const startDate = new Date(savingsAccount.startDate)

let compoundedInterestInput = {
let compoundedInterestInput: CompoundedInterestInput = {
A: 0,
P: savingsAccount.initialDeposit,
r: savingsAccount.apy / 100,
t: 0,
Expand Down Expand Up @@ -96,7 +117,7 @@ export const calculateSavings = (savingsAccount) => {


// savings goal
export const calculateSavingsGoal = (savingsGoalInput) => {
export const calculateSavingsGoal = (savingsGoalInput: SavingsGoalInput): SavingsGoalResult | undefined => {


let compoundedInterestInput = {
Expand Down Expand Up @@ -132,12 +153,13 @@ export const calculateSavingsGoal = (savingsGoalInput) => {
}
}

export const calculateSavingsGoalSchedule = (savingsGoalResult) => {
export const calculateSavingsGoalSchedule = (savingsGoalResult: SavingsGoalResult): SavingsGoalScheduleResult[] => {
let res = []
let totalInterest = 0
const startDate = new Date(savingsGoalResult.dateFirstDeposit)

let compoundedInterestInput = {
let compoundedInterestInput: CompoundedInterestInput = {
A: 0,
P: savingsGoalResult.amountFirstDeposit,
r: savingsGoalResult.interestRatePerYear / 100,
t: (1 / 12),
Expand Down
2 changes: 0 additions & 2 deletions src/utils/constants/investments.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ export enum INVESTMENT_COMPOUNDING_PERIOD_MONTHS {
// },
// }

const AVERAGE_DAYS_IN_MONTH = 30.437; // Example value for AVERAGE_DAYS_IN_MONTH, replace with actual value if needed

// Define enum for compounding types
export enum InvestmentCompoundingType {
Annually = "Annually",
Expand Down
22 changes: 0 additions & 22 deletions src/utils/constants/market-data.constants.js

This file was deleted.

22 changes: 22 additions & 0 deletions src/utils/constants/market-data.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// market data constants

export enum MARKET_DATA_TYPES {
stocks = "Stocks",
indices = "Indices",
crypto = "Crypto",
currencies = "Currencies"
}

export const DEFAULT_MARKET_DATA = undefined

export const MARKET_DATA_SEARCH_QUERY_MULTIPLIER = 1

export const MARKET_DATA_CRYPTO_PREFIX = "X:"
export const MARKET_DATA_FOREX_PREFIX = "C:"

export enum MARKET_DATA_INTERVALS {
"Hour" = "Hourly",
"Day" = "Daily",
"Week" = "Weekly",
"Month" = "Monthly"
}
File renamed without changes.
22 changes: 0 additions & 22 deletions src/utils/constants/savings.constants.js

This file was deleted.

Loading

0 comments on commit 90b9836

Please sign in to comment.