Skip to content

Commit f31e7ec

Browse files
committed
feat: add overspent for month calculation
1 parent 872c69d commit f31e7ec

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

pkg/models/budget.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,25 @@ func (b Budget) TotalBudgeted() (decimal.Decimal, error) {
140140

141141
return budgeted.Decimal, nil
142142
}
143+
144+
// Overspent calculates overspend for a specific month.
145+
func (b Budget) Overspent(month time.Time) (decimal.Decimal, error) {
146+
var envelopes []Envelope
147+
err := database.DB.
148+
Joins("Category", database.DB.Where(&Category{CategoryCreate: CategoryCreate{BudgetID: b.ID}})).
149+
Find(&envelopes).
150+
Error
151+
if err != nil {
152+
return decimal.Zero, err
153+
}
154+
155+
var overspent decimal.Decimal
156+
for _, envelope := range envelopes {
157+
spent := envelope.Spent(month)
158+
if spent.IsNegative() {
159+
overspent = overspent.Add(spent.Neg())
160+
}
161+
}
162+
163+
return overspent, nil
164+
}

pkg/models/budget_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
148148

149149
outgoingTransactionBank := models.Transaction{
150150
TransactionCreate: models.TransactionCreate{
151+
Date: marchFifteenthTwentyTwentyTwo,
151152
BudgetID: budget.ID,
152153
EnvelopeID: &envelope.ID,
153154
SourceAccountID: bankAccount.ID,
@@ -162,6 +163,7 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
162163

163164
outgoingTransactionCash := models.Transaction{
164165
TransactionCreate: models.TransactionCreate{
166+
Date: marchFifteenthTwentyTwentyTwo,
165167
BudgetID: budget.ID,
166168
EnvelopeID: &envelope.ID,
167169
SourceAccountID: cashAccount.ID,
@@ -204,12 +206,22 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
204206
// Verify total budgeted for used budget
205207
budgeted, err := budget.TotalBudgeted()
206208
assert.Nil(suite.T(), err)
207-
assert.True(suite.T(), budgeted.Equal(decimal.NewFromFloat(42)), "Income is %s, should be 42", income)
209+
assert.True(suite.T(), budgeted.Equal(decimal.NewFromFloat(42)), "Budgeted is %s, should be 42", budgeted)
208210

209211
// Verify total budgeted for empty budget
210212
budgeted, err = emptyBudget.TotalBudgeted()
211213
assert.Nil(suite.T(), err)
212-
assert.True(suite.T(), budgeted.IsZero(), "Income is %s, should be 0", income)
214+
assert.True(suite.T(), budgeted.IsZero(), "Budgeted is %s, should be 0", budgeted)
215+
216+
// Verify overspent calculation for month without spend
217+
overpent, err := budget.Overspent(time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC))
218+
assert.Nil(suite.T(), err)
219+
assert.True(suite.T(), overpent.IsZero(), "Overspent is %s, should be 0", overpent)
220+
221+
// Verify overspent calculation for month with spend
222+
overpent, err = budget.Overspent(marchFifteenthTwentyTwentyTwo)
223+
assert.Nil(suite.T(), err)
224+
assert.True(suite.T(), overpent.Equal(decimal.NewFromFloat(110.62)), "Overspent is %s, should be 110.62", overpent)
213225
}
214226

215227
func (suite *TestSuiteEnv) TestMonthIncomeNoTransactions() {

0 commit comments

Comments
 (0)