diff --git a/http/admin.go b/http/admin.go index 5bfe998..33099bf 100644 --- a/http/admin.go +++ b/http/admin.go @@ -3,9 +3,7 @@ package http import ( "fmt" "net/http" - "time" - "git.javil.eu/jacob1123/budgeteer/postgres" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/pressly/goose/v3" @@ -72,14 +70,14 @@ func (h *Handler) clearBudget(c *gin.Context) { } func (h *Handler) cleanNegativeBudget(c *gin.Context) { - budgetID := c.Param("budgetid") + /*budgetID := c.Param("budgetid") budgetUUID, err := uuid.Parse(budgetID) if err != nil { c.Redirect(http.StatusTemporaryRedirect, "/login") return - } + }*/ - min_date, err := h.Service.DB.GetFirstActivity(c.Request.Context(), budgetUUID) + /*min_date, err := h.Service.DB.GetFirstActivity(c.Request.Context(), budgetUUID) date := getFirstOfMonthTime(min_date) for { nextDate := date.AddDate(0, 1, 0) @@ -114,6 +112,6 @@ func (h *Handler) cleanNegativeBudget(c *gin.Context) { } else { break } - } + }*/ } diff --git a/http/budgeting.go b/http/budgeting.go index ec614b5..797b863 100644 --- a/http/budgeting.go +++ b/http/budgeting.go @@ -13,7 +13,7 @@ import ( type BudgetingData struct { AlwaysNeededData - Categories []postgres.GetCategoriesWithBalanceRow + Categories []CategoryWithBalance AvailableBalance postgres.Numeric Date time.Time Next time.Time @@ -31,6 +31,14 @@ func getFirstOfMonthTime(date time.Time) time.Time { return getFirstOfMonth(year, month, date.Location()) } +type CategoryWithBalance struct { + *postgres.GetCategoriesRow + Available float64 + AvailableLastMonth float64 + Activity float64 + Assigned float64 +} + func (h *Handler) budgeting(c *gin.Context) { budgetID := c.Param("budgetid") budgetUUID, err := uuid.Parse(budgetID) @@ -64,17 +72,7 @@ func (h *Handler) budgeting(c *gin.Context) { firstOfNextMonth := firstOfMonth.AddDate(0, 1, 0) firstOfPreviousMonth := firstOfMonth.AddDate(0, -1, 0) - params := postgres.GetCategoriesWithBalanceParams{ - BudgetID: budgetUUID, - FromDate: firstOfMonth, - ToDate: firstOfNextMonth, - PrevFromDate: firstOfMonth.AddDate(0, -1, 0), - } - categories, err := h.Service.DB.GetCategoriesWithBalance(c.Request.Context(), params) - if err != nil { - c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("load categories: %w", err)) - return - } + categories, err := h.Service.DB.GetCategories(c.Request.Context(), budgetUUID) cumultativeBalances, err := h.Service.DB.GetCumultativeBalances(c.Request.Context(), budgetUUID) if err != nil { @@ -82,12 +80,15 @@ func (h *Handler) budgeting(c *gin.Context) { return } - var available float64 = 0 + categoriesWithBalance := []CategoryWithBalance{} + var added float64 = 0 var assigned float64 = 0 for i := range categories { cat := &categories[i] - var balance float64 = 0 + categoryWithBalance := CategoryWithBalance{ + GetCategoriesRow: cat, + } for _, bal := range cumultativeBalances { if bal.CategoryID != cat.ID { continue @@ -99,25 +100,23 @@ func (h *Handler) budgeting(c *gin.Context) { } assigned += bal.Assignments.GetFloat64() - balance += bal.Assignments.GetFloat64() - balance += bal.Transactions.GetFloat64() - if balance < 0 && bal.Date.Before(firstOfMonth) { - added -= balance - balance = 0 + categoryWithBalance.Available += bal.Assignments.GetFloat64() + categoryWithBalance.Available += bal.Transactions.GetFloat64() + if categoryWithBalance.Available < 0 && bal.Date.Before(firstOfMonth) { + added -= categoryWithBalance.Available + categoryWithBalance.Available = 0 } if bal.Date.Before(firstOfMonth) { - available = balance + categoryWithBalance.AvailableLastMonth = categoryWithBalance.Available + } else if bal.Date.Before(firstOfNextMonth) { + categoryWithBalance.Activity = bal.Transactions.GetFloat64() + categoryWithBalance.Assigned = bal.Assignments.GetFloat64() } + } - num := postgres.Numeric{} - num.Set(balance) - cat.Available = num - - num2 := postgres.Numeric{} - num2.Set(available) - cat.AvailableLastMonth = num2 + categoriesWithBalance = append(categoriesWithBalance, categoryWithBalance) } data := c.MustGet("data").(AlwaysNeededData) @@ -145,12 +144,12 @@ func (h *Handler) budgeting(c *gin.Context) { availableBalanceNum.Set(availableBalance) d := BudgetingData{ - c.MustGet("data").(AlwaysNeededData), - categories, - availableBalanceNum, - firstOfMonth, - firstOfNextMonth, - firstOfPreviousMonth, + AlwaysNeededData: c.MustGet("data").(AlwaysNeededData), + Categories: categoriesWithBalance, + AvailableBalance: availableBalanceNum, + Date: firstOfMonth, + Next: firstOfNextMonth, + Previous: firstOfPreviousMonth, } c.HTML(http.StatusOK, "budgeting.html", d) diff --git a/postgres/categories.sql.go b/postgres/categories.sql.go index 275e55c..9649011 100644 --- a/postgres/categories.sql.go +++ b/postgres/categories.sql.go @@ -5,7 +5,6 @@ package postgres import ( "context" - "time" "github.com/google/uuid" ) @@ -48,43 +47,11 @@ func (q *Queries) CreateCategoryGroup(ctx context.Context, arg CreateCategoryGro return i, err } -const getAvailableBalance = `-- name: GetAvailableBalance :one -SELECT - (( - SELECT SUM(transactions.amount) - FROM transactions - LEFT JOIN categories ON categories.id = transactions.category_id - LEFT JOIN budgets ON budgets.income_category_id = categories.id - INNER JOIN accounts ON accounts.id = transactions.account_id - WHERE budgets.id = $1 - AND transactions.date < $2 - AND accounts.on_budget - ) - ( - SELECT SUM(assignments.amount) - FROM assignments - INNER JOIN categories ON categories.id = assignments.category_id - INNER JOIN category_groups ON category_groups.id = categories.category_group_id - WHERE category_groups.budget_id = $1 - AND assignments.date < $2 - ))::decimal(12,2) -` - -type GetAvailableBalanceParams struct { - BudgetID uuid.UUID - FromDate time.Time -} - -func (q *Queries) GetAvailableBalance(ctx context.Context, arg GetAvailableBalanceParams) (Numeric, error) { - row := q.db.QueryRowContext(ctx, getAvailableBalance, arg.BudgetID, arg.FromDate) - var column_1 Numeric - err := row.Scan(&column_1) - return column_1, err -} - const getCategories = `-- name: GetCategories :many SELECT categories.id, categories.category_group_id, categories.name, category_groups.name as group FROM categories INNER JOIN category_groups ON categories.category_group_id = category_groups.id WHERE category_groups.budget_id = $1 +ORDER BY category_groups.name, categories.name ` type GetCategoriesRow struct { @@ -122,109 +89,6 @@ func (q *Queries) GetCategories(ctx context.Context, budgetID uuid.UUID) ([]GetC return items, nil } -const getCategoriesWithBalance = `-- name: GetCategoriesWithBalance :many -SELECT categories.id, categories.name, category_groups.name as group, - ( - COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < $1 - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < $1 - ), 0) - )::decimal(12,2) as available, - ( - COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < $2 - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < $2 - ), 0)-CASE WHEN (COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < $3 - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < $3 - ), 0)) < 0 THEN (COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < $3 - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < $3 - ), 0)) ELSE 0 END - - - )::decimal(12,2) as available_last_month, - COALESCE(( - SELECT SUM(t_this.amount) FROM transactions t_this - WHERE categories.id = t_this.category_id AND t_this.date >= $2 AND t_this.date < $1 - ), 0)::decimal(12,2) as activity, - COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date >= $2 AND a_hist.date < $1 - ), 0)::decimal(12,2) as assigned - -FROM categories -INNER JOIN category_groups ON categories.category_group_id = category_groups.id -WHERE category_groups.budget_id = $4 -GROUP BY categories.id, categories.name, category_groups.name -ORDER BY category_groups.name, categories.name -` - -type GetCategoriesWithBalanceParams struct { - ToDate time.Time - FromDate time.Time - PrevFromDate time.Time - BudgetID uuid.UUID -} - -type GetCategoriesWithBalanceRow struct { - ID uuid.UUID - Name string - Group string - Available Numeric - AvailableLastMonth Numeric - Activity Numeric - Assigned Numeric -} - -func (q *Queries) GetCategoriesWithBalance(ctx context.Context, arg GetCategoriesWithBalanceParams) ([]GetCategoriesWithBalanceRow, error) { - rows, err := q.db.QueryContext(ctx, getCategoriesWithBalance, - arg.ToDate, - arg.FromDate, - arg.PrevFromDate, - arg.BudgetID, - ) - if err != nil { - return nil, err - } - defer rows.Close() - var items []GetCategoriesWithBalanceRow - for rows.Next() { - var i GetCategoriesWithBalanceRow - if err := rows.Scan( - &i.ID, - &i.Name, - &i.Group, - &i.Available, - &i.AvailableLastMonth, - &i.Activity, - &i.Assigned, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - const getCategoryGroups = `-- name: GetCategoryGroups :many SELECT category_groups.id, category_groups.budget_id, category_groups.name FROM category_groups WHERE category_groups.budget_id = $1 diff --git a/postgres/queries/categories.sql b/postgres/queries/categories.sql index 555bfe2..389406c 100644 --- a/postgres/queries/categories.sql +++ b/postgres/queries/categories.sql @@ -17,73 +17,5 @@ RETURNING *; -- name: GetCategories :many SELECT categories.*, category_groups.name as group FROM categories INNER JOIN category_groups ON categories.category_group_id = category_groups.id -WHERE category_groups.budget_id = $1; - --- name: GetCategoriesWithBalance :many -SELECT categories.id, categories.name, category_groups.name as group, - ( - COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < @to_date - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < @to_date - ), 0) - )::decimal(12,2) as available, - ( - COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < @from_date - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < @from_date - ), 0)-CASE WHEN (COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < @prev_from_date - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < @prev_from_date - ), 0)) < 0 THEN (COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date < @prev_from_date - ), 0)+COALESCE(( - SELECT SUM(t_hist.amount) FROM transactions t_hist - WHERE categories.id = t_hist.category_id AND t_hist.date < @prev_from_date - ), 0)) ELSE 0 END - - - )::decimal(12,2) as available_last_month, - COALESCE(( - SELECT SUM(t_this.amount) FROM transactions t_this - WHERE categories.id = t_this.category_id AND t_this.date >= @from_date AND t_this.date < @to_date - ), 0)::decimal(12,2) as activity, - COALESCE(( - SELECT SUM(a_hist.amount) FROM assignments a_hist - WHERE categories.id = a_hist.category_id AND a_hist.date >= @from_date AND a_hist.date < @to_date - ), 0)::decimal(12,2) as assigned - -FROM categories -INNER JOIN category_groups ON categories.category_group_id = category_groups.id -WHERE category_groups.budget_id = @budget_id -GROUP BY categories.id, categories.name, category_groups.name -ORDER BY category_groups.name, categories.name; - --- name: GetAvailableBalance :one -SELECT - (( - SELECT SUM(transactions.amount) - FROM transactions - LEFT JOIN categories ON categories.id = transactions.category_id - LEFT JOIN budgets ON budgets.income_category_id = categories.id - INNER JOIN accounts ON accounts.id = transactions.account_id - WHERE budgets.id = @budget_id - AND transactions.date < @from_date - AND accounts.on_budget - ) - ( - SELECT SUM(assignments.amount) - FROM assignments - INNER JOIN categories ON categories.id = assignments.category_id - INNER JOIN category_groups ON category_groups.id = categories.category_group_id - WHERE category_groups.budget_id = @budget_id - AND assignments.date < @from_date - ))::decimal(12,2); \ No newline at end of file +WHERE category_groups.budget_id = $1 +ORDER BY category_groups.name, categories.name; \ No newline at end of file diff --git a/web/amount.tpl b/web/amount.tpl index 27f46d6..95fe753 100644 --- a/web/amount.tpl +++ b/web/amount.tpl @@ -8,4 +8,16 @@ {{printf "%.2f" .GetFloat64}} +{{end}} + +{{define "amountf64"}} + + {{printf "%.2f" .}} + +{{end}} + +{{define "amountf64-cell"}} + + {{printf "%.2f" .}} + {{end}} \ No newline at end of file diff --git a/web/budgeting.html b/web/budgeting.html index d3901e6..60290a1 100644 --- a/web/budgeting.html +++ b/web/budgeting.html @@ -41,10 +41,10 @@ - {{template "amount-cell" .AvailableLastMonth}} - {{template "amount-cell" .Assigned}} - {{template "amount-cell" .Activity}} - {{template "amount-cell" .Available}} + {{template "amountf64-cell" .AvailableLastMonth}} + {{template "amountf64-cell" .Assigned}} + {{template "amountf64-cell" .Activity}} + {{template "amountf64-cell" .Available}} {{end}}