From 6bac09a38e63a880c13c2210ae1e869b7f860086 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Mon, 27 Dec 2021 23:38:30 +0000 Subject: [PATCH] Implement update and delete for transactions --- http/http.go | 1 + http/transaction.go | 74 ++++++++++++++++++++++++------- postgres/queries/transactions.sql | 14 ++++++ postgres/transactions.sql.go | 44 ++++++++++++++++++ web/transaction.html | 6 +-- 5 files changed, 120 insertions(+), 19 deletions(-) diff --git a/http/http.go b/http/http.go index 47212da..1716f94 100644 --- a/http/http.go +++ b/http/http.go @@ -86,6 +86,7 @@ func (h *Handler) Serve() { transaction := authenticated.Group("/transaction") transaction.POST("/new", h.newTransaction) + transaction.POST("/:transactionid", h.newTransaction) transaction.POST("/import/ynab", h.importYNAB) router.Run(":1323") diff --git a/http/transaction.go b/http/transaction.go index d57266f..966e5b1 100644 --- a/http/transaction.go +++ b/http/transaction.go @@ -24,9 +24,26 @@ func getUUID(c *gin.Context, name string) (uuid.UUID, error) { return id, nil } -func getNullUUID(c *gin.Context, name string) (uuid.NullUUID, error) { +func getNullUUIDFromParam(c *gin.Context, name string) (uuid.NullUUID, error) { + value := c.Param(name) + if value == "" { + return uuid.NullUUID{}, nil + } + + id, err := uuid.Parse(value) + if err != nil { + return uuid.NullUUID{}, fmt.Errorf("not a valid uuid: %w", err) + } + + return uuid.NullUUID{ + UUID: id, + Valid: true, + }, nil +} + +func getNullUUIDFromForm(c *gin.Context, name string) (uuid.NullUUID, error) { value, succ := c.GetPostForm(name) - if !succ { + if !succ || value == "" { return uuid.NullUUID{}, nil } @@ -45,13 +62,13 @@ func (h *Handler) newTransaction(c *gin.Context) { transactionMemo, _ := c.GetPostForm("memo") transactionAccountID, err := getUUID(c, "account_id") if err != nil { - c.AbortWithError(http.StatusNotAcceptable, err) + c.AbortWithError(http.StatusNotAcceptable, fmt.Errorf("account_id: %w", err)) return } - transactionCategoryID, err := getNullUUID(c, "category_id") + transactionCategoryID, err := getNullUUIDFromForm(c, "category_id") if err != nil { - c.AbortWithError(http.StatusNotAcceptable, err) + c.AbortWithError(http.StatusNotAcceptable, fmt.Errorf("category_id: %w", err)) return } @@ -75,17 +92,42 @@ func (h *Handler) newTransaction(c *gin.Context) { amount := postgres.Numeric{} amount.Set(transactionAmount) - new := postgres.CreateTransactionParams{ - Memo: transactionMemo, - Date: transactionDateValue, - Amount: amount, - AccountID: transactionAccountID, - PayeeID: uuid.NullUUID{}, - CategoryID: transactionCategoryID, - } - _, err = h.Service.CreateTransaction(c.Request.Context(), new) + + transactionUUID, err := getNullUUIDFromParam(c, "transactionid") if err != nil { - c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create transaction: %w", err)) - return + + } + if !transactionUUID.Valid { + new := postgres.CreateTransactionParams{ + Memo: transactionMemo, + Date: transactionDateValue, + Amount: amount, + AccountID: transactionAccountID, + PayeeID: uuid.NullUUID{}, + CategoryID: transactionCategoryID, + } + _, err = h.Service.CreateTransaction(c.Request.Context(), new) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create transaction: %w", err)) + return + } + } else { + _, delete := c.GetPostForm("delete") + if delete { + h.Service.DeleteTransaction(c.Request.Context(), transactionUUID.UUID) + } + update := postgres.UpdateTransactionParams{ + Memo: transactionMemo, + Date: transactionDateValue, + Amount: amount, + AccountID: transactionAccountID, + PayeeID: uuid.NullUUID{}, + CategoryID: transactionCategoryID, + } + err = h.Service.UpdateTransaction(c.Request.Context(), update) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("update transaction: %w", err)) + return + } } } diff --git a/postgres/queries/transactions.sql b/postgres/queries/transactions.sql index 9e67259..2bef52a 100644 --- a/postgres/queries/transactions.sql +++ b/postgres/queries/transactions.sql @@ -8,6 +8,20 @@ INSERT INTO transactions VALUES ($1, $2, $3, $4, $5, $6) RETURNING *; +-- name: UpdateTransaction :exec +UPDATE transactions +SET date = $1, + memo = $2, + amount = $3, + account_id = $4, + payee_id = $5, + category_id = $6 +WHERE id = $7; + +-- name: DeleteTransaction :exec +DELETE FROM transactions +WHERE id = $1; + -- name: GetTransactionsForBudget :many SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, accounts.name as account, COALESCE(payees.name, '') as payee, COALESCE(category_groups.name, '') as category_group, COALESCE(categories.name, '') as category diff --git a/postgres/transactions.sql.go b/postgres/transactions.sql.go index c3aacc3..dfd568e 100644 --- a/postgres/transactions.sql.go +++ b/postgres/transactions.sql.go @@ -63,6 +63,16 @@ func (q *Queries) DeleteAllTransactions(ctx context.Context, budgetID uuid.UUID) return result.RowsAffected() } +const deleteTransaction = `-- name: DeleteTransaction :exec +DELETE FROM transactions +WHERE id = $1 +` + +func (q *Queries) DeleteTransaction(ctx context.Context, id uuid.UUID) error { + _, err := q.db.ExecContext(ctx, deleteTransaction, id) + return err +} + const getTransaction = `-- name: GetTransaction :one SELECT id, date, memo, amount, account_id, category_id, payee_id FROM transactions WHERE id = $1 @@ -228,3 +238,37 @@ func (q *Queries) GetTransactionsForBudget(ctx context.Context, budgetID uuid.UU } return items, nil } + +const updateTransaction = `-- name: UpdateTransaction :exec +UPDATE transactions +SET date = $1, + memo = $2, + amount = $3, + account_id = $4, + payee_id = $5, + category_id = $6 +WHERE id = $7 +` + +type UpdateTransactionParams struct { + Date time.Time + Memo string + Amount Numeric + AccountID uuid.UUID + PayeeID uuid.NullUUID + CategoryID uuid.NullUUID + ID uuid.UUID +} + +func (q *Queries) UpdateTransaction(ctx context.Context, arg UpdateTransactionParams) error { + _, err := q.db.ExecContext(ctx, updateTransaction, + arg.Date, + arg.Memo, + arg.Amount, + arg.AccountID, + arg.PayeeID, + arg.CategoryID, + arg.ID, + ) + return err +} diff --git a/web/transaction.html b/web/transaction.html index 73144e4..3b2a17b 100644 --- a/web/transaction.html +++ b/web/transaction.html @@ -28,7 +28,7 @@ -
+