Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor lifetime type #78

Merged
merged 7 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions app/components/graphs/LifetimeFairholdLandPurchaseWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,15 @@ const LifetimeFairholdLandPurchaseWrapper: React.FC<Props> = ({

// Process and format the data for the chart
const chartData =
(household.tenure.fairholdLandPurchase?.lifetime || []).map(
(household.lifetime.lifetimeData).map(
(item, index) => {
// Access and store household.lifetime array
// TODO remove defensive code after types tightened upstream
const incomeThreshold =
household.lifetime && household.lifetime[index]
? household.lifetime[index].affordabilityThresholdIncome
: 0;

// Access and store all other variables
return {
year: index.toString(),
landCost: item.landMortgagePaymentYearly,
houseCost: item.houseMortgagePaymentYearly,
incomeThreshold: item.affordabilityThresholdIncome,
landCost: item.fairholdLandMortgageYearly,
houseCost: item.depreciatedHouseMortgageYearly,
// billsCost: item.gasBillYearly,
maintenanceCost: item.maintenanceCost,
incomeThreshold: incomeThreshold,
};
}
) ?? [];
Expand Down
27 changes: 10 additions & 17 deletions app/components/graphs/LifetimeFairholdLandRentWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,16 @@ const LifetimeFairholdLandRentWrapper: React.FC<Props> = ({ household }) => {

// Process and format the data for the chart
const chartData =
(household.tenure.fairholdLandRent?.lifetime || []).map((item, index) => {
// Access and store household.lifetime array
// TODO remove defensive code after types tightened upstream
const incomeThreshold =
household.lifetime && household.lifetime[index]
? household.lifetime[index].affordabilityThresholdIncome
: 0;

// Access and store all other variables
return {
year: index.toString(),
landCost: item.fairholdRentLand,
houseCost: item.houseMortgagePaymentYearly,
maintenanceCost: item.maintenanceCost,
// billsCost: item.gasBillYearly,
incomeThreshold: incomeThreshold,
};
(household.lifetime.lifetimeData).map(
(item, index) => {
return {
year: index.toString(),
incomeThreshold: item.affordabilityThresholdIncome,
landCost: item.fairholdLandRentYearly,
houseCost: item.depreciatedHouseMortgageYearly,
maintenanceCost: item.maintenanceCost,
// billsCost: item.gasBillYearly,
};
}) ?? [];

return (
Expand Down
27 changes: 10 additions & 17 deletions app/components/graphs/LifetimeMarketPurchaseWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,16 @@ const LifetimeMarketPurchaseWrapper: React.FC<Props> = ({ household }) => {

// Process and format the data for the chart
const chartData =
(household.tenure.marketPurchase?.lifetime || []).map((item, index) => {
// Access and store household.lifetime array
// TODO remove defensive code after types tightened upstream
const incomeThreshold =
household.lifetime && household.lifetime[index]
? household.lifetime[index].affordabilityThresholdIncome
: 0;

// Access and store all other variables
return {
year: index.toString(), // or just `year: index` if you want it as a number
landCost: item.landMortgagePaymentYearly,
houseCost: item.houseMortgagePaymentYearly,
maintenanceCost: item.maintenanceCost,
// billsCost: item.gasBillYearly,
incomeThreshold: incomeThreshold,
};
(household.lifetime.lifetimeData).map(
(item, index) => {
return {
year: index.toString(),
incomeThreshold: item.affordabilityThresholdIncome,
landCost: item.marketLandMortgageYearly,
houseCost: item.newbuildHouseMortgageYearly,
maintenanceCost: item.maintenanceCost,
// billsCost: item.gasBillYearly,
};
}) ?? [];

return (
Expand Down
17 changes: 5 additions & 12 deletions app/components/graphs/LifetimeMarketRentWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,14 @@ const LifetimeMarketRentWrapper: React.FC<Props> = ({ household }) => {

// Process and format the data for the chart
const chartData =
(household.tenure.marketRent?.lifetime || []).map((item, index) => {
// Access and store household.lifetime array
// TODO remove defensive code after types tightened upstream
const incomeThreshold =
household.lifetime && household.lifetime[index]
? household.lifetime[index].affordabilityThresholdIncome
: 0;

// Access and store all other variables
(household.lifetime.lifetimeData).map(
(item, index) => {
return {
year: index.toString(),
landCost: item.averageRentLandYearly,
houseCost: item.averageRentHouseYearly,
incomeThreshold: item.affordabilityThresholdIncome,
landCost: item.marketLandRentYearly,
houseCost: item.marketHouseRentYearly,
// billsCost: item.gasBillYearly,
incomeThreshold: incomeThreshold,
};
}) ?? [];

Expand Down
48 changes: 24 additions & 24 deletions app/components/graphs/TotalPaymentWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,54 @@ import React from "react";
import ErrorBoundary from '../ErrorBoundary';
import { Household } from "@/app/models/Household";
import TotalPaymentBarChart from "./TotalPaymentBarChart";
import { LifetimeData } from "@/app/models/Lifetime";

interface TotalPaymentWrapperProps {
household: Household;
}

type LifetimeValues = {
[key: string]: number;
};

const TotalPaymentWrapper: React.FC<TotalPaymentWrapperProps> = ({
household,
}) => {
console.log("TotalPaymentWrapper household: ", household);

const sumLifetimeValues = (
lifetime: LifetimeValues[] | undefined,
keys: string[]
lifetime: LifetimeData[] | undefined,
keys: (keyof LifetimeData)[]
): number => {
if (!lifetime || !Array.isArray(lifetime)) return 0;

return lifetime.reduce((sum, entry) => {
return (
sum +
keys.reduce((entrySum, key) => {
return entrySum + (typeof entry[key] === "number" ? entry[key] : 0);
}, 0)
);
}, 0);

let totalSum = 0;

for (const entry of lifetime) {
let entrySum = 0;
for (const key of keys) {
entrySum += entry[key];
}
totalSum += entrySum;
}

return totalSum;
};

const chartData = [
{
paymentType: "Total Payments",
marketPurchase: sumLifetimeValues(
household.tenure.marketPurchase?.lifetime,
["houseMortgagePaymentYearly", "landMortgagePaymentYearly"]
household.lifetime.lifetimeData,
["newbuildHouseMortgageYearly", "marketLandMortgageYearly"]
),
marketRent: sumLifetimeValues(household.tenure.marketRent?.lifetime, [
"averageRentHouseYearly",
"averageRentLandYearly",
marketRent: sumLifetimeValues(
household.lifetime.lifetimeData,
["marketHouseRentYearly", "marketLandRentYearly",
]),
fairholdLandPurchase: sumLifetimeValues(
household.tenure.fairholdLandPurchase?.lifetime,
["houseMortgagePaymentYearly", "landMortgagePaymentYearly"]
household.lifetime.lifetimeData,
["depreciatedHouseMortgageYearly", "fairholdLandMortgageYearly"]
),
fairholdLandRent: sumLifetimeValues(
household.tenure.fairholdLandRent?.lifetime,
["fairholdRentLand", "houseMortgagePaymentYearly"]
household.lifetime.lifetimeData,
["depreciatedHouseMortgageYearly", "fairholdLandRentYearly"]
),
},
];
Expand Down
61 changes: 20 additions & 41 deletions app/models/Household.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Property } from "./Property";
import { SocialRent } from "./tenure/SocialRent";
import { ForecastParameters } from "./ForecastParameters";
import { socialRentAdjustmentTypes } from "../data/socialRentAdjustmentsRepo";
import { Lifetime, LifetimeParams } from "./Lifetime";

const HOUSE_MULTIPLIER = 2.4;

Expand All @@ -20,11 +21,6 @@ type ConstructorParams = Pick<
housePriceIndex: number;
};

type Lifetime = {
affordabilityThresholdIncome: number;
incomeYearly: number;
}[];

export class Household {
public incomePerPersonYearly: number;
public gasBillYearly: number;
Expand All @@ -47,10 +43,7 @@ export class Household {
this.forecastParameters = params.forecastParameters;
this.incomeYearly = HOUSE_MULTIPLIER * params.incomePerPersonYearly;
this.tenure = this.calculateTenures(params);
this.lifetime = this.calculateLifetime(
this.incomeYearly,
params.forecastParameters
);
this.lifetime = this.calculateLifetime(params);
}

private calculateTenures({
Expand Down Expand Up @@ -149,36 +142,22 @@ export class Household {
};
}

private calculateLifetime(
incomeYearly: number,
{
incomeGrowthPerYear,
affordabilityThresholdIncomePercentage,
yearsForecast,
}: ForecastParameters
) {
let incomeYearlyIterative = incomeYearly;
let affordabilityThresholdIncomeIterative =
incomeYearlyIterative * affordabilityThresholdIncomePercentage;

const lifetime: Lifetime = [
{
incomeYearly: incomeYearlyIterative,
affordabilityThresholdIncome: affordabilityThresholdIncomeIterative,
},
];

for (let i = 0; i < yearsForecast - 1; i++) {
incomeYearlyIterative = incomeYearlyIterative * (1 + incomeGrowthPerYear);
affordabilityThresholdIncomeIterative =
incomeYearlyIterative * affordabilityThresholdIncomePercentage;

lifetime.push({
incomeYearly: incomeYearlyIterative,
affordabilityThresholdIncome: affordabilityThresholdIncomeIterative,
});
private calculateLifetime(params: ConstructorParams): Lifetime {
const lifetimeParams: LifetimeParams = {
marketPurchase: this.tenure.marketPurchase,
marketRent: this.tenure.marketRent,
fairholdLandPurchase: this.tenure.fairholdLandPurchase,
fairholdLandRent: this.tenure.fairholdLandRent,
property: this.property,
propertyPriceGrowthPerYear: params.forecastParameters.propertyPriceGrowthPerYear,
constructionPriceGrowthPerYear: params.forecastParameters.constructionPriceGrowthPerYear,
rentGrowthPerYear: params.forecastParameters.rentGrowthPerYear,
yearsForecast: params.forecastParameters.yearsForecast,
maintenanceCostPercentage: params.forecastParameters.maintenanceCostPercentage,
incomeGrowthPerYear: params.forecastParameters.incomeGrowthPerYear,
affordabilityThresholdIncomePercentage: params.forecastParameters.affordabilityThresholdIncomePercentage,
incomeYearly: this.incomeYearly,
};
return new Lifetime(lifetimeParams);
}

return lifetime;
}
}
}
Loading
Loading