Skip to content

Commit ef25f40

Browse files
committed
fix: total budgeted sum only until the end of the month
The total budgeted amount is used for the calculation of the sum available to budget. Therefore, only transactions before the end of the month in question may be added to the calculation.
1 parent f31e7ec commit ef25f40

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

pkg/models/budget.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,20 @@ func (b Budget) TotalIncome() (decimal.Decimal, error) {
117117
return income.Decimal, nil
118118
}
119119

120-
// TotalBudgeted calculates the total sum that has been budgeted over all time.
121-
func (b Budget) TotalBudgeted() (decimal.Decimal, error) {
120+
// TotalBudgeted calculates the total sum that has been budgeted before a specific month.
121+
func (b Budget) TotalBudgeted(month time.Time) (decimal.Decimal, error) {
122+
// Only use the year and month values, everything else is reset to the start
123+
// Add a month to also factor in all allocations in the requested month
124+
month = time.Date(month.Year(), month.AddDate(0, 1, 0).Month(), 1, 0, 0, 0, 0, time.UTC)
125+
122126
var budgeted decimal.NullDecimal
123127
err := database.DB.
124128
Select("SUM(amount)").
125129
Joins("JOIN envelopes ON allocations.envelope_id = envelopes.id AND envelopes.deleted_at IS NULL").
126130
Joins("JOIN categories ON envelopes.category_id = categories.id AND categories.deleted_at IS NULL").
127131
Joins("JOIN budgets ON categories.budget_id = budgets.id AND budgets.deleted_at IS NULL").
128132
Where("budgets.id = ?", b.ID).
133+
Where("allocations.month < date(?) ", month).
129134
Table("allocations").
130135
Find(&budgeted).
131136
Error

pkg/models/budget_test.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,30 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
114114
suite.Assert().Fail("Resource could not be saved", err)
115115
}
116116

117+
allocationCurrentMonth := models.Allocation{
118+
AllocationCreate: models.AllocationCreate{
119+
EnvelopeID: envelope.ID,
120+
Amount: decimal.NewFromFloat(25),
121+
Month: marchFifteenthTwentyTwentyTwo,
122+
},
123+
}
124+
err = database.DB.Save(&allocationCurrentMonth).Error
125+
if err != nil {
126+
suite.Assert().Fail("Resource could not be saved", err)
127+
}
128+
129+
allocationFuture := models.Allocation{
130+
AllocationCreate: models.AllocationCreate{
131+
EnvelopeID: envelope.ID,
132+
Amount: decimal.NewFromFloat(24.58),
133+
Month: time.Date(2170, 2, 1, 0, 0, 0, 0, time.UTC),
134+
},
135+
}
136+
err = database.DB.Save(&allocationFuture).Error
137+
if err != nil {
138+
suite.Assert().Fail("Resource could not be saved", err)
139+
}
140+
117141
salaryTransaction := models.Transaction{
118142
TransactionCreate: models.TransactionCreate{
119143
Date: marchFifteenthTwentyTwentyTwo,
@@ -204,12 +228,12 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
204228
assert.True(suite.T(), income.IsZero(), "Income is %s, should be 0", income)
205229

206230
// Verify total budgeted for used budget
207-
budgeted, err := budget.TotalBudgeted()
231+
budgeted, err := budget.TotalBudgeted(marchFifteenthTwentyTwentyTwo)
208232
assert.Nil(suite.T(), err)
209-
assert.True(suite.T(), budgeted.Equal(decimal.NewFromFloat(42)), "Budgeted is %s, should be 42", budgeted)
233+
assert.True(suite.T(), budgeted.Equal(decimal.NewFromFloat(67)), "Budgeted is %s, should be 67", budgeted)
210234

211235
// Verify total budgeted for empty budget
212-
budgeted, err = emptyBudget.TotalBudgeted()
236+
budgeted, err = emptyBudget.TotalBudgeted(marchFifteenthTwentyTwentyTwo)
213237
assert.Nil(suite.T(), err)
214238
assert.True(suite.T(), budgeted.IsZero(), "Budgeted is %s, should be 0", budgeted)
215239

@@ -255,7 +279,7 @@ func (suite *TestSuiteEnv) TestTotalBudgetedNoTransactions() {
255279
suite.Assert().Fail("Resource could not be saved", err)
256280
}
257281

258-
budgeted, err := budget.TotalBudgeted()
282+
budgeted, err := budget.TotalBudgeted(time.Date(1913, 8, 3, 0, 0, 0, 0, time.UTC))
259283
assert.Nil(suite.T(), err)
260284
assert.True(suite.T(), budgeted.IsZero(), "Income is %s, should be 0", budgeted)
261285
}

0 commit comments

Comments
 (0)