From 2ca3328f0fa2d561568914fe5c7f2d26fdaec88c Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Sun, 24 Apr 2022 19:40:44 +0000 Subject: [PATCH] Implement backend --- postgres/queries/transactions.sql | 10 ++++- postgres/transactions.sql.go | 66 +++++++++++++++++++++++++++++++ server/account.go | 35 ++++++++++++++++ server/http.go | 1 + 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/postgres/queries/transactions.sql b/postgres/queries/transactions.sql index e39e3e2..6e7b981 100644 --- a/postgres/queries/transactions.sql +++ b/postgres/queries/transactions.sql @@ -61,4 +61,12 @@ LEFT JOIn accounts AS otherGroupAccount WHERE transactions.category_id IS NULL AND accounts.on_budget AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget) -AND accounts.budget_id = $1; \ No newline at end of file +AND accounts.budget_id = $1; + +-- name: GetFilteredTransactions :many +SELECT transactions.* +FROM display_transactions AS transactions +WHERE (@filter_category::boolean OR transactions.category_id = @category_id) +AND (@filter_account::boolean OR transactions.account_id = @account_id) +AND (@filter_payee::boolean OR transactions.payee_id = @payee_id) +AND transactions.budget_id = @budget_id; \ No newline at end of file diff --git a/postgres/transactions.sql.go b/postgres/transactions.sql.go index f110a70..1792af1 100644 --- a/postgres/transactions.sql.go +++ b/postgres/transactions.sql.go @@ -117,6 +117,72 @@ func (q *Queries) GetAllTransactionsForBudget(ctx context.Context, budgetID uuid return items, nil } +const getFilteredTransactions = `-- name: GetFilteredTransactions :many +SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, transactions.group_id, transactions.status, transactions.account, transactions.payee_id, transactions.category_id, transactions.payee, transactions.category_group, transactions.category, transactions.transfer_account, transactions.budget_id, transactions.account_id +FROM display_transactions AS transactions +WHERE ($1::boolean OR transactions.category_id = $2) +AND ($3::boolean OR transactions.account_id = $4) +AND ($5::boolean OR transactions.payee_id = $6) +AND transactions.budget_id = $7 +` + +type GetFilteredTransactionsParams struct { + FilterCategory bool + CategoryID uuid.NullUUID + FilterAccount bool + AccountID uuid.UUID + FilterPayee bool + PayeeID uuid.NullUUID + BudgetID uuid.UUID +} + +func (q *Queries) GetFilteredTransactions(ctx context.Context, arg GetFilteredTransactionsParams) ([]DisplayTransaction, error) { + rows, err := q.db.QueryContext(ctx, getFilteredTransactions, + arg.FilterCategory, + arg.CategoryID, + arg.FilterAccount, + arg.AccountID, + arg.FilterPayee, + arg.PayeeID, + arg.BudgetID, + ) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DisplayTransaction + for rows.Next() { + var i DisplayTransaction + if err := rows.Scan( + &i.ID, + &i.Date, + &i.Memo, + &i.Amount, + &i.GroupID, + &i.Status, + &i.Account, + &i.PayeeID, + &i.CategoryID, + &i.Payee, + &i.CategoryGroup, + &i.Category, + &i.TransferAccount, + &i.BudgetID, + &i.AccountID, + ); 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 getProblematicTransactions = `-- name: GetProblematicTransactions :many SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, transactions.group_id, transactions.status, transactions.account, transactions.payee_id, transactions.category_id, transactions.payee, transactions.category_group, transactions.category, transactions.transfer_account, transactions.budget_id, transactions.account_id FROM display_transactions AS transactions diff --git a/server/account.go b/server/account.go index 758ada8..9c81a76 100644 --- a/server/account.go +++ b/server/account.go @@ -8,6 +8,41 @@ import ( "github.com/google/uuid" ) +type FilterTransactionsRequest struct { + CategoryID string `json:"category_id"` + PayeeID string `json:"payee_id"` + AccountID string `json:"account_id"` +} + +func (h *Handler) filteredTransactions(c *gin.Context) { + budgetID := c.Param("budgetid") + budgetUUID, err := uuid.Parse(budgetID) + if err != nil { + c.AbortWithError(http.StatusBadRequest, err) + return + } + + var request FilterTransactionsRequest + err = c.BindJSON(&request) + if err != nil { + c.AbortWithError(http.StatusBadRequest, err) + return + } + + params := postgres.GetFilteredTransactionsParams{ + BudgetID: budgetUUID, + CategoryID: uuid.NullUUID{}, + FilterCategory: true, + } + transactions, err := h.Service.GetFilteredTransactions(c.Request.Context(), params) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + return + } + + c.JSON(http.StatusOK, TransactionsResponse{nil, transactions}) +} + func (h *Handler) problematicTransactions(c *gin.Context) { budgetID := c.Param("budgetid") budgetUUID, err := uuid.Parse(budgetID) diff --git a/server/http.go b/server/http.go index de5f7c8..67e51ba 100644 --- a/server/http.go +++ b/server/http.go @@ -68,6 +68,7 @@ func (h *Handler) LoadRoutes(router *gin.Engine) { budget.GET("/:budgetid/autocomplete/accounts", h.autocompleteAccounts) budget.GET("/:budgetid/autocomplete/categories", h.autocompleteCategories) budget.GET("/:budgetid/problematic-transactions", h.problematicTransactions) + budget.GET("/:budgetid/filtered-transactions", h.filteredTransactions) budget.DELETE("/:budgetid", h.deleteBudget) budget.POST("/:budgetid/import/ynab", h.importYNAB) budget.POST("/:budgetid/export/ynab/transactions", h.exportYNABTransactions)