Skip to content

Commit 8171874

Browse files
committed
feat: Beefed up debt log
1 parent b47f3db commit 8171874

14 files changed

Lines changed: 3034 additions & 492 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
namespace CompoundCalc.Models.Requests;
2+
3+
public sealed class DebtStrategyRequest
4+
{
5+
public DebtStrategyRequest(decimal monthlyBudget, IReadOnlyCollection<DebtStrategyDebtRequest> debts)
6+
{
7+
MonthlyBudget = monthlyBudget;
8+
Debts = debts ?? throw new ArgumentNullException(nameof(debts));
9+
10+
Validate();
11+
}
12+
13+
public decimal MonthlyBudget { get; }
14+
15+
public IReadOnlyCollection<DebtStrategyDebtRequest> Debts { get; }
16+
17+
private void Validate()
18+
{
19+
if (MonthlyBudget <= 0m)
20+
{
21+
throw new ArgumentOutOfRangeException(nameof(MonthlyBudget), "Monthly budget must be greater than zero.");
22+
}
23+
24+
if (Debts.Count is < 1 or > 50)
25+
{
26+
throw new ArgumentOutOfRangeException(nameof(Debts), "Provide between 1 and 50 debts.");
27+
}
28+
}
29+
}
30+
31+
public sealed class DebtStrategyDebtRequest
32+
{
33+
public DebtStrategyDebtRequest(
34+
string clientDebtId,
35+
string name,
36+
decimal currentBalance,
37+
decimal annualAprPercent,
38+
decimal minimumPayment)
39+
{
40+
if (string.IsNullOrWhiteSpace(clientDebtId))
41+
{
42+
throw new ArgumentException("Debt id is required.", nameof(clientDebtId));
43+
}
44+
45+
if (string.IsNullOrWhiteSpace(name))
46+
{
47+
throw new ArgumentException("Debt name is required.", nameof(name));
48+
}
49+
50+
if (currentBalance <= 0m)
51+
{
52+
throw new ArgumentOutOfRangeException(nameof(currentBalance), "Current balance must be greater than zero.");
53+
}
54+
55+
if (annualAprPercent < 0m || annualAprPercent > 100m)
56+
{
57+
throw new ArgumentOutOfRangeException(nameof(annualAprPercent), "Annual APR percent must be between 0 and 100.");
58+
}
59+
60+
if (minimumPayment <= 0m)
61+
{
62+
throw new ArgumentOutOfRangeException(nameof(minimumPayment), "Minimum payment must be greater than zero.");
63+
}
64+
65+
ClientDebtId = clientDebtId.Trim();
66+
Name = name.Trim();
67+
CurrentBalance = currentBalance;
68+
AnnualAprPercent = annualAprPercent;
69+
MinimumPayment = minimumPayment;
70+
}
71+
72+
public string ClientDebtId { get; }
73+
74+
public string Name { get; }
75+
76+
public decimal CurrentBalance { get; }
77+
78+
public decimal AnnualAprPercent { get; }
79+
80+
public decimal MinimumPayment { get; }
81+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
namespace CompoundCalc.Models.Responses;
2+
3+
public sealed record DebtStrategyResult(
4+
decimal MonthlyBudget,
5+
decimal TotalMinimumPayment,
6+
string RecommendedStrategy,
7+
DebtStrategyPlanResult Snowball,
8+
DebtStrategyPlanResult Avalanche,
9+
string CalculationVersion);
10+
11+
public sealed record DebtStrategyPlanResult(
12+
string Strategy,
13+
int MonthsToPayoff,
14+
decimal TotalPaid,
15+
decimal TotalInterestPaid,
16+
string TotalPaidDisplay,
17+
string TotalInterestDisplay,
18+
string FinalPayoffDateLabel,
19+
IReadOnlyList<DebtStrategyPayoffOrderItem> PayoffOrder,
20+
IReadOnlyList<DebtStrategyMonthResult> Timeline);
21+
22+
public sealed record DebtStrategyPayoffOrderItem(
23+
string ClientDebtId,
24+
string Name,
25+
int PayoffMonth,
26+
decimal StartingBalance,
27+
decimal AnnualAprPercent);
28+
29+
public sealed record DebtStrategyMonthResult(
30+
int MonthNumber,
31+
decimal StartingBalance,
32+
decimal InterestCharged,
33+
decimal PaymentApplied,
34+
decimal EndingBalance,
35+
IReadOnlyList<DebtStrategyMonthDebtResult> Debts);
36+
37+
public sealed record DebtStrategyMonthDebtResult(
38+
string ClientDebtId,
39+
string Name,
40+
decimal StartingBalance,
41+
decimal InterestCharged,
42+
decimal PaymentApplied,
43+
decimal MinimumPaymentApplied,
44+
decimal ExtraPaymentApplied,
45+
decimal EndingBalance,
46+
bool IsTargeted,
47+
bool IsPaidOffThisMonth);

0 commit comments

Comments
 (0)