diff --git a/server/budgeting.go b/server/budgeting.go index 9c65d85..01e9b45 100644 --- a/server/budgeting.go +++ b/server/budgeting.go @@ -1,6 +1,7 @@ package server import ( + "context" "fmt" "net/http" "time" @@ -56,22 +57,29 @@ func (h *Handler) budgetingForMonth(c *gin.Context) { firstOfMonth, err := getDate(c) if err != nil { - c.Redirect(http.StatusTemporaryRedirect, "/budget/"+budgetUUID.String()) - return - } - - categories, err := h.Service.GetCategories(c.Request.Context(), budgetUUID) - if err != nil { - c.AbortWithError(http.StatusInternalServerError, err) + c.Redirect(http.StatusTemporaryRedirect, "/budget/"+budget.ID.String()) return } firstOfNextMonth := firstOfMonth.AddDate(0, 1, 0) - cumultativeBalances, err := h.Service.GetCumultativeBalances(c.Request.Context(), budgetUUID) + data, err := h.prepareBudgeting(c.Request.Context(), budget, firstOfNextMonth, firstOfMonth) if err != nil { - c.AbortWithStatusJSON(http.StatusInternalServerError, ErrorResponse{fmt.Sprintf("error loading balances: %s", err)}) + c.AbortWithError(http.StatusInternalServerError, err) return } + c.JSON(http.StatusOK, data) +} + +func (h *Handler) prepareBudgeting(ctx context.Context, budget postgres.Budget, firstOfNextMonth time.Time, firstOfMonth time.Time) (BudgetingForMonthResponse, error) { + categories, err := h.Service.GetCategories(ctx, budget.ID) + if err != nil { + return BudgetingForMonthResponse{}, fmt.Errorf("error loading categories: %w", err) + } + + cumultativeBalances, err := h.Service.GetCumultativeBalances(ctx, budget.ID) + if err != nil { + return BudgetingForMonthResponse{}, fmt.Errorf("error loading balances: %w", err) + } categoriesWithBalance, moneyUsed := h.calculateBalances( budget, firstOfNextMonth, firstOfMonth, categories, cumultativeBalances) @@ -86,16 +94,19 @@ func (h *Handler) budgetingForMonth(c *gin.Context) { cat.AvailableLastMonth = availableBalance } - data := struct { - Categories []CategoryWithBalance - AvailableBalance numeric.Numeric - }{categoriesWithBalance, availableBalance} - c.JSON(http.StatusOK, data) + data := BudgetingForMonthResponse{categoriesWithBalance, availableBalance} + return data, nil +} + +type BudgetingForMonthResponse struct { + Categories []CategoryWithBalance + AvailableBalance numeric.Numeric } func (*Handler) getAvailableBalance(budget postgres.Budget, moneyUsed numeric.Numeric, cumultativeBalances []postgres.GetCumultativeBalancesRow, - firstOfNextMonth time.Time) numeric.Numeric { + firstOfNextMonth time.Time, +) numeric.Numeric { availableBalance := moneyUsed for _, bal := range cumultativeBalances { @@ -149,7 +160,8 @@ func (h *Handler) returnBudgetingData(c *gin.Context, budgetUUID uuid.UUID) { func (h *Handler) calculateBalances(budget postgres.Budget, firstOfNextMonth time.Time, firstOfMonth time.Time, categories []postgres.GetCategoriesRow, - cumultativeBalances []postgres.GetCumultativeBalancesRow) ([]CategoryWithBalance, numeric.Numeric) { + cumultativeBalances []postgres.GetCumultativeBalancesRow, +) ([]CategoryWithBalance, numeric.Numeric) { categoriesWithBalance := []CategoryWithBalance{} moneyUsed2 := numeric.Zero() @@ -168,7 +180,8 @@ func (h *Handler) calculateBalances(budget postgres.Budget, func (*Handler) CalculateCategoryBalances(cat *postgres.GetCategoriesRow, cumultativeBalances []postgres.GetCumultativeBalancesRow, firstOfNextMonth time.Time, - moneyUsed *numeric.Numeric, firstOfMonth time.Time, budget postgres.Budget) CategoryWithBalance { + moneyUsed *numeric.Numeric, firstOfMonth time.Time, budget postgres.Budget, +) CategoryWithBalance { categoryWithBalance := NewCategoryWithBalance(cat) for _, bal := range cumultativeBalances { if bal.CategoryID != cat.ID { diff --git a/server/main_test.go b/server/main_test.go index 6c1eadd..10f3505 100644 --- a/server/main_test.go +++ b/server/main_test.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "testing" + "time" "git.javil.eu/jacob1123/budgeteer/bcrypt" "git.javil.eu/jacob1123/budgeteer/config" @@ -68,8 +69,7 @@ func TestMain(t *testing.T) { handler.DoYNABImport(ctx, t, budget) - // import from YNAB - + handler.CheckAvailableBalance(ctx, t, budget) // check available balance // check categories @@ -77,6 +77,24 @@ func TestMain(t *testing.T) { // check accounts } +func (h Handler) CheckAvailableBalance(ctx context.Context, t *testing.T, budget *postgres.Budget) { + loc := time.Now().Location() + first := time.Date(2022, 1, 1, 0, 0, 0, 0, loc) + firstOfNextMonth := time.Date(2022, 2, 1, 0, 0, 0, 0, loc) + data, err := h.prepareBudgeting(ctx, *budget, firstOfNextMonth, first) + if err != nil { + fmt.Println(err) + t.Fail() + return + } + + if data.AvailableBalance.GetFloat64() != -115170.56 { + fmt.Println("Available balance is wrong:") + t.Fail() + return + } +} + func (h Handler) DoYNABImport(ctx context.Context, t *testing.T, budget *postgres.Budget) { t.Helper() budgetID := budget.ID