From 46d727c650379b668f4c5dafb94d4de53bb4c8c8 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Tue, 1 Feb 2022 21:08:37 +0000 Subject: [PATCH] Try to implement autocomplete for payees --- http/budgeting.go | 22 ++++++++++++++++++++++ http/http.go | 1 + postgres/payees.sql.go | 34 ++++++++++++++++++++++++++++++++++ postgres/queries/payees.sql | 8 +++++++- web/src/pages/Account.vue | 24 ++++++++++++++++++++---- 5 files changed, 84 insertions(+), 5 deletions(-) diff --git a/http/budgeting.go b/http/budgeting.go index 2cd6018..9023aaa 100644 --- a/http/budgeting.go +++ b/http/budgeting.go @@ -60,6 +60,28 @@ func getDate(c *gin.Context) (time.Time, error) { return getFirstOfMonth(year, month, time.Now().Location()), nil } +func (h *Handler) autocompletePayee(c *gin.Context) { + budgetID := c.Param("budgetid") + budgetUUID, err := uuid.Parse(budgetID) + if err != nil { + c.AbortWithError(http.StatusBadRequest, fmt.Errorf("budgetid missing from URL")) + return + } + + query := c.Request.URL.Query().Get("s") + searchParams := postgres.SearchPayeesParams{ + BudgetID: budgetUUID, + Search: query + "%", + } + payees, err := h.Service.SearchPayees(c.Request.Context(), searchParams) + if err != nil { + c.AbortWithError(http.StatusInternalServerError, err) + return + } + + c.JSON(http.StatusOK, payees) +} + func (h *Handler) budgeting(c *gin.Context) { budgetID := c.Param("budgetid") budgetUUID, err := uuid.Parse(budgetID) diff --git a/http/http.go b/http/http.go index 97257df..3cb78c5 100644 --- a/http/http.go +++ b/http/http.go @@ -66,6 +66,7 @@ func (h *Handler) Serve() { authenticated.GET("/account/:accountid/transactions", h.transactionsForAccount) authenticated.GET("/admin/clear-database", h.clearDatabase) authenticated.GET("/budget/:budgetid", h.budgeting) + authenticated.GET("/budget/:budgetid/autocomplete/payees", h.autocompletePayee) authenticated.DELETE("/budget/:budgetid", h.deleteBudget) authenticated.POST("/budget/:budgetid/import/ynab", h.importYNAB) authenticated.POST("/budget/:budgetid/settings/clear", h.clearBudget) diff --git a/postgres/payees.sql.go b/postgres/payees.sql.go index 34f036a..d17572c 100644 --- a/postgres/payees.sql.go +++ b/postgres/payees.sql.go @@ -56,3 +56,37 @@ func (q *Queries) GetPayees(ctx context.Context, budgetID uuid.UUID) ([]Payee, e } return items, nil } + +const searchPayees = `-- name: SearchPayees :many +SELECT payees.id, payees.budget_id, payees.name FROM payees +WHERE payees.budget_id = $1 +AND payees.name LIKE $2 +` + +type SearchPayeesParams struct { + BudgetID uuid.UUID + Search string +} + +func (q *Queries) SearchPayees(ctx context.Context, arg SearchPayeesParams) ([]Payee, error) { + rows, err := q.db.QueryContext(ctx, searchPayees, arg.BudgetID, arg.Search) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Payee + for rows.Next() { + var i Payee + if err := rows.Scan(&i.ID, &i.BudgetID, &i.Name); 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 +} diff --git a/postgres/queries/payees.sql b/postgres/queries/payees.sql index c421005..97cc97e 100644 --- a/postgres/queries/payees.sql +++ b/postgres/queries/payees.sql @@ -7,4 +7,10 @@ RETURNING *; -- name: GetPayees :many SELECT payees.* FROM payees WHERE payees.budget_id = $1 -ORDER BY name; \ No newline at end of file +ORDER BY name; + +-- name: SearchPayees :many +SELECT payees.* FROM payees +WHERE payees.budget_id = @budget_id +AND payees.name LIKE @search; +--ORDER BY levenshtein(payees.name, $2); \ No newline at end of file diff --git a/web/src/pages/Account.vue b/web/src/pages/Account.vue index 862f1b7..7ae1087 100644 --- a/web/src/pages/Account.vue +++ b/web/src/pages/Account.vue @@ -6,12 +6,27 @@ export default defineComponent({ return { TransactionDate: new Date().toISOString().substring(0, 10), Payee: "", + SearchPayees: null, + Category: "", + Memo: "", + Amount: 0 } }, props: ["budgetid", "accountid"], + watch: { + SearchPayees() { + GetPayees(this.$data.SearchPayees); + } + }, methods: { saveTransaction(e : MouseEvent) { e.preventDefault(); + }, + GetPayees() { + fetch("/api/v1/budget/" + this.$store.getters.CurrentBudget.ID + "/autocomplete/payees?s=" + this.$data.SearchPayees, { + headers: this.$store.getters.AuthHeaders + }) .then(x=>x.json()) + .then(x => console.log(x)); } } }) @@ -32,16 +47,17 @@ export default defineComponent({ - + + - + - + - +