Skip to content

Commit

Permalink
chore: separate component calculation for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
zz-hh-aa committed Nov 29, 2024
1 parent b59f360 commit e226d9b
Showing 1 changed file with 27 additions and 23 deletions.
50 changes: 27 additions & 23 deletions app/models/Property.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as math from "mathjs";
import { BED_WEIGHTS_AND_CAPS, MAINTENANCE_LEVELS, HOUSE_BREAKDOWN_PERCENTAGES } from "./constants";
import { houseBreakdownType, componentBreakdownType } from "./constants";
import { houseBreakdownType } from "./constants";
/**
* Number of decimal places to use when rounding numerical values
*/
Expand All @@ -25,6 +24,13 @@ export type HouseType = (typeof HOUSE_TYPES)[number];

export type MaintenancePercentage = (typeof MAINTENANCE_LEVELS)[number]

export type ComponentCalculation = {
newComponentValue: number;
depreciationFactor: number;
maintenanceAddition: number;
depreciatedComponentValue: number;
}

export class Property {
postcode: string;
houseType: HouseType;
Expand Down Expand Up @@ -89,32 +95,28 @@ export class Property {

let depreciatedBuildPrice = 0;

for (const [key, value] of Object.entries(HOUSE_BREAKDOWN_PERCENTAGES) as [keyof houseBreakdownType, componentBreakdownType][]) {
// New component is calculated as a percentage of newBuildPrice
const newComponentValue = this.newBuildPrice * value.percentageOfHouse

// Calculate depreciation
const depreciationFactor = 1 - (value.depreciationPercentageYearly * this.age);

// Calculate maintenance spend (which counters depreciation)
const maintenanceAddition = (key === 'foundations' || key === 'structureEnvelope') ? 0 :
MAINTENANCE_LEVELS[0] * this.newBuildPrice * this.age * value.percentOfMaintenanceYearly;

// Use both depreciationFactor and maintenanceAddition to calculate final depreciatedComponentValue
const depreciatedComponentValue = parseFloat(((newComponentValue * depreciationFactor) + maintenanceAddition).toFixed(PRECISION));
// Calculate for each component using the public method
for (const key of Object.keys(HOUSE_BREAKDOWN_PERCENTAGES) as (keyof houseBreakdownType)[]) {
const result = this.calculateComponentValue(
key,
this.newBuildPrice,
this.age,
MAINTENANCE_LEVELS[0]
);

depreciatedBuildPrice += math.max(depreciatedComponentValue, 0) // Add depreciatedComponentValue to depreciatedBuildPrice, or 0 if value is negative
}
depreciatedBuildPrice += result.depreciatedComponentValue;
}
depreciatedBuildPrice = parseFloat(depreciatedBuildPrice.toFixed(PRECISION))
return depreciatedBuildPrice;
};

return depreciatedBuildPrice;
}

public calculateComponentValue(
componentKey: keyof houseBreakdownType,
newBuildPrice: number,
age: number,
maintenanceLevel: number
) {
): ComponentCalculation {
const component = HOUSE_BREAKDOWN_PERCENTAGES[componentKey];

// Calculate new component value
Expand All @@ -130,14 +132,16 @@ export class Property {
: maintenanceLevel * newBuildPrice * age * component.percentOfMaintenanceYearly;

// Calculate final value
const depreciatedComponentValue =
let depreciatedComponentValue =
(newComponentValue * depreciationFactor) + maintenanceAddition;


depreciatedComponentValue < 0 ? depreciatedComponentValue = 0 : depreciatedComponentValue

return {
newComponentValue,
depreciationFactor,
maintenanceAddition,
depreciatedComponentValue: Math.max(depreciatedComponentValue, 0)
depreciatedComponentValue
};
}

Expand Down

0 comments on commit e226d9b

Please sign in to comment.