Skip to content

Commit 69436f2

Browse files
committed
fix: overspent now adds transactions without envelope
1 parent ef25f40 commit 69436f2

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

pkg/models/budget.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ func (b Budget) TotalBudgeted(month time.Time) (decimal.Decimal, error) {
148148

149149
// Overspent calculates overspend for a specific month.
150150
func (b Budget) Overspent(month time.Time) (decimal.Decimal, error) {
151+
// Only use the year and month values, everything else is reset to the start
152+
// Add a month to also factor in all allocations in the requested month
153+
month = time.Date(month.Year(), month.Month(), 1, 0, 0, 0, 0, time.UTC)
154+
151155
var envelopes []Envelope
152156
err := database.DB.
153157
Joins("Category", database.DB.Where(&Category{CategoryCreate: CategoryCreate{BudgetID: b.ID}})).
@@ -165,5 +169,30 @@ func (b Budget) Overspent(month time.Time) (decimal.Decimal, error) {
165169
}
166170
}
167171

172+
var noEnvelopeSum decimal.NullDecimal
173+
err = database.DB.
174+
Select("SUM(amount)").
175+
Joins("JOIN accounts source_account ON transactions.source_account_id = source_account.id AND source_account.deleted_at IS NULL").
176+
Joins("JOIN accounts destination_account ON transactions.destination_account_id = destination_account.id AND destination_account.deleted_at IS NULL").
177+
Where("source_account.external = 0").
178+
Where("destination_account.external = 1").
179+
Where("transactions.envelope_id IS NULL").
180+
Where("transactions.date < date(?) ", month.AddDate(0, 1, 0)).
181+
Where(&Transaction{
182+
TransactionCreate: TransactionCreate{
183+
BudgetID: b.ID,
184+
},
185+
}).
186+
Table("transactions").
187+
Find(&noEnvelopeSum).
188+
Error
189+
if err != nil {
190+
return decimal.Zero, err
191+
}
192+
193+
if noEnvelopeSum.Valid {
194+
overspent = overspent.Add(noEnvelopeSum.Decimal)
195+
}
196+
168197
return overspent, nil
169198
}

pkg/models/budget_test.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,23 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
200200
suite.Assert().Fail("Resource could not be saved", err)
201201
}
202202

203+
overspendTransaction := models.Transaction{
204+
TransactionCreate: models.TransactionCreate{
205+
Date: marchFifteenthTwentyTwentyTwo,
206+
BudgetID: budget.ID,
207+
SourceAccountID: cashAccount.ID,
208+
DestinationAccountID: groceryAccount.ID,
209+
Amount: decimal.NewFromFloat(20),
210+
},
211+
}
212+
err = database.DB.Save(&overspendTransaction).Error
213+
if err != nil {
214+
suite.Assert().Fail("Resource could not be saved", err)
215+
}
216+
203217
budget = budget.WithCalculations()
204218

205-
shouldBalance := decimal.NewFromFloat(5489.38)
219+
shouldBalance := decimal.NewFromFloat(5469.38)
206220
assert.True(suite.T(), budget.Balance.Equal(shouldBalance), "Balance for budget is not correct. Should be %s, is %s", shouldBalance, budget.Balance)
207221

208222
// Verify income for used budget in March
@@ -238,14 +252,14 @@ func (suite *TestSuiteEnv) TestBudgetCalculations() {
238252
assert.True(suite.T(), budgeted.IsZero(), "Budgeted is %s, should be 0", budgeted)
239253

240254
// Verify overspent calculation for month without spend
241-
overpent, err := budget.Overspent(time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC))
255+
overspent, err := budget.Overspent(time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC))
242256
assert.Nil(suite.T(), err)
243-
assert.True(suite.T(), overpent.IsZero(), "Overspent is %s, should be 0", overpent)
257+
assert.True(suite.T(), overspent.IsZero(), "Overspent is %s, should be 0", overspent)
244258

245259
// Verify overspent calculation for month with spend
246-
overpent, err = budget.Overspent(marchFifteenthTwentyTwentyTwo)
260+
overspent, err = budget.Overspent(marchFifteenthTwentyTwentyTwo)
247261
assert.Nil(suite.T(), err)
248-
assert.True(suite.T(), overpent.Equal(decimal.NewFromFloat(110.62)), "Overspent is %s, should be 110.62", overpent)
262+
assert.True(suite.T(), overspent.Equal(decimal.NewFromFloat(130.62)), "Overspent is %s, should be 130.62", overspent)
249263
}
250264

251265
func (suite *TestSuiteEnv) TestMonthIncomeNoTransactions() {

0 commit comments

Comments
 (0)