diff options
Diffstat (limited to 'gui/src/types/balanceToBudgetRatio.ts')
| -rw-r--r-- | gui/src/types/balanceToBudgetRatio.ts | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/gui/src/types/balanceToBudgetRatio.ts b/gui/src/types/balanceToBudgetRatio.ts new file mode 100644 index 0000000..2f8000c --- /dev/null +++ b/gui/src/types/balanceToBudgetRatio.ts @@ -0,0 +1,83 @@ +import { Budget } from "./budget"; +import Currency from "./currency/currency"; + +class BalanceToBudgetRatio { + toString(): string { + return this._ratio?.toFixed(2) ?? ""; + } + + public readonly recommendedAction: "arrears" | "save" | "spend" | null; + public readonly normalisedRatio: number | null; + + private constructor( + private readonly _ratio: number | null, + private readonly _normalisationFactor: number, + ) { + if (this._ratio === null) { + this.normalisedRatio = null; + this.recommendedAction = null; + return; + } + + this.normalisedRatio = this._ratio * this._normalisationFactor; + + if (this._ratio < 0) { + this.recommendedAction = "arrears"; + } else if (this._ratio >= 1) { + this.recommendedAction = "spend"; + } else { + this.recommendedAction = "save"; + } + } + + static new(balance: Currency, budget: Budget | null) { + if (budget === null || budget.quantity === 0 || budget.quantity === -0) { + return null; + } + + return new BalanceToBudgetRatio( + balance.valueOf() / budget.quantity.valueOf(), + 1, + ); + } + + static makeNormaliser( + ...balanceToBudgetRatios: (BalanceToBudgetRatio | null)[] + ): (r: BalanceToBudgetRatio | null) => BalanceToBudgetRatio { + const validRatios = balanceToBudgetRatios.filter( + (r) => + r && + r._ratio && + !isNaN(r._ratio) && + Infinity > r._ratio && + -Infinity < r._ratio, + ); + + const maxAbsRatio = Math.max( + ...validRatios.map((r) => Math.abs(r?._ratio ?? 0)), + ); + + const normalisationFactor = 1 / maxAbsRatio; + return (r) => + new BalanceToBudgetRatio(r?._ratio ?? null, normalisationFactor); + } + + static compare( + lhs: BalanceToBudgetRatio | null, + rhs: BalanceToBudgetRatio | null, + ): number { + if (lhs === null || lhs._ratio === null) { + if (rhs === null || rhs._ratio === null) { + return 0; + } + return 1; + } + if (rhs === null || rhs._ratio === null) { + return -1; + } + + return rhs._ratio - lhs._ratio; + } +} + +export { BalanceToBudgetRatio }; |
