Skip to content

Commit 872c69d

Browse files
committed
feat: add total budgeted sum calculation
1 parent d44057b commit 872c69d

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

pkg/models/budget.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,27 @@ func (b Budget) TotalIncome() (decimal.Decimal, error) {
116116

117117
return income.Decimal, nil
118118
}
119+
120+
// TotalBudgeted calculates the total sum that has been budgeted over all time.
121+
func (b Budget) TotalBudgeted() (decimal.Decimal, error) {
122+
var budgeted decimal.NullDecimal
123+
err := database.DB.
124+
Select("SUM(amount)").
125+
Joins("JOIN envelopes ON allocations.envelope_id = envelopes.id AND envelopes.deleted_at IS NULL").
126+
Joins("JOIN categories ON envelopes.category_id = categories.id AND categories.deleted_at IS NULL").
127+
Joins("JOIN budgets ON categories.budget_id = budgets.id AND budgets.deleted_at IS NULL").
128+
Where("budgets.id = ?", b.ID).
129+
Table("allocations").
130+
Find(&budgeted).
131+
Error
132+
if err != nil {
133+
return decimal.Zero, err
134+
}
135+
136+
// If no transactions are found, the value is nil
137+
if !budgeted.Valid {
138+
return decimal.NewFromFloat(0), nil
139+
}
140+
141+
return budgeted.Decimal, nil
142+
}

pkg/models/budget_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,30 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
9090
suite.Assert().Fail("Resource could not be saved", err)
9191
}
9292

93+
allocation1 := models.Allocation{
94+
AllocationCreate: models.AllocationCreate{
95+
EnvelopeID: envelope.ID,
96+
Amount: decimal.NewFromFloat(17.42),
97+
Month: time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC),
98+
},
99+
}
100+
err = database.DB.Save(&allocation1).Error
101+
if err != nil {
102+
suite.Assert().Fail("Resource could not be saved", err)
103+
}
104+
105+
allocation2 := models.Allocation{
106+
AllocationCreate: models.AllocationCreate{
107+
EnvelopeID: envelope.ID,
108+
Amount: decimal.NewFromFloat(24.58),
109+
Month: time.Date(2022, 2, 1, 0, 0, 0, 0, time.UTC),
110+
},
111+
}
112+
err = database.DB.Save(&allocation2).Error
113+
if err != nil {
114+
suite.Assert().Fail("Resource could not be saved", err)
115+
}
116+
93117
salaryTransaction := models.Transaction{
94118
TransactionCreate: models.TransactionCreate{
95119
Date: marchFifteenthTwentyTwentyTwo,
@@ -176,6 +200,16 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
176200
income, err = emptyBudget.TotalIncome()
177201
assert.Nil(suite.T(), err)
178202
assert.True(suite.T(), income.IsZero(), "Income is %s, should be 0", income)
203+
204+
// Verify total budgeted for used budget
205+
budgeted, err := budget.TotalBudgeted()
206+
assert.Nil(suite.T(), err)
207+
assert.True(suite.T(), budgeted.Equal(decimal.NewFromFloat(42)), "Income is %s, should be 42", income)
208+
209+
// Verify total budgeted for empty budget
210+
budgeted, err = emptyBudget.TotalBudgeted()
211+
assert.Nil(suite.T(), err)
212+
assert.True(suite.T(), budgeted.IsZero(), "Income is %s, should be 0", income)
179213
}
180214

181215
func (suite *TestSuiteEnv) TestMonthIncomeNoTransactions() {
@@ -201,3 +235,15 @@ func (suite *TestSuiteEnv) TestTotalIncomeNoTransactions() {
201235
assert.Nil(suite.T(), err)
202236
assert.True(suite.T(), income.IsZero(), "Income is %s, should be 0", income)
203237
}
238+
239+
func (suite *TestSuiteEnv) TestTotalBudgetedNoTransactions() {
240+
budget := models.Budget{}
241+
err := database.DB.Save(&budget).Error
242+
if err != nil {
243+
suite.Assert().Fail("Resource could not be saved", err)
244+
}
245+
246+
budgeted, err := budget.TotalBudgeted()
247+
assert.Nil(suite.T(), err)
248+
assert.True(suite.T(), budgeted.IsZero(), "Income is %s, should be 0", budgeted)
249+
}

0 commit comments

Comments
 (0)