From 0d4fb124b4bc2bcbc746b5e73ae83ad5ff06beb3 Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Mon, 27 Feb 2023 13:13:28 +0100 Subject: [PATCH] =?UTF-8?q?Keep=20all=20=E2=80=9Cnew=20invoice=20actions?= =?UTF-8?q?=E2=80=9D=20on=20the=20same=20/new=20URI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/invoices.go | 75 ++++++++++++++------------- pkg/router.go | 2 +- web/template/invoices/new.gohtml | 6 ++- web/template/invoices/products.gohtml | 5 +- 4 files changed, 48 insertions(+), 40 deletions(-) diff --git a/pkg/invoices.go b/pkg/invoices.go index 2d767cc..0a2e9cc 100644 --- a/pkg/invoices.go +++ b/pkg/invoices.go @@ -262,28 +262,16 @@ func HandleAddInvoice(w http.ResponseWriter, r *http.Request, _ httprouter.Param http.Error(w, err.Error(), http.StatusForbidden) return } - switch r.Form.Get("action") { - case "update": - form.Update() - w.WriteHeader(http.StatusOK) + if !form.Validate() { + w.WriteHeader(http.StatusUnprocessableEntity) mustRenderNewInvoiceForm(w, r, form) - case "products": - w.WriteHeader(http.StatusOK) - mustRenderNewInvoiceProductsForm(w, r, form) - case "add": - if !form.Validate() { - w.WriteHeader(http.StatusUnprocessableEntity) - mustRenderNewInvoiceForm(w, r, form) - return - } - slug := conn.MustGetText(r.Context(), "", "select add_invoice($1, $2, $3, $4, $5, $6)", company.Id, form.Number, form.Date, form.Customer, form.Notes, NewInvoiceProductArray(form.Products)) - http.Redirect(w, r, companyURI(company, "/invoices/"+slug), http.StatusSeeOther) - default: - http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) + return } + slug := conn.MustGetText(r.Context(), "", "select add_invoice($1, $2, $3, $4, $5, $6)", company.Id, form.Number, form.Date, form.Customer, form.Notes, NewInvoiceProductArray(form.Products)) + http.Redirect(w, r, companyURI(company, "/invoices/"+slug), http.StatusSeeOther) } -func HandleAddProductsToInvoice(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { +func HandleNewInvoiceAction(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { locale := getLocale(r) conn := getConn(r) company := mustGetCompany(r) @@ -292,25 +280,25 @@ func HandleAddProductsToInvoice(w http.ResponseWriter, r *http.Request, _ httpro http.Error(w, err.Error(), http.StatusBadRequest) return } - - index := len(form.Products) - productsId := r.Form["id"] - rows := conn.MustQuery(r.Context(), "select product_id, name, description, to_price(price, decimal_digits), 1 as quantity, 0 as discount, array_remove(array_agg(tax_id), null) from product join company using (company_id) join currency using (currency_code) left join product_tax using (product_id) where product_id = any ($1) group by product_id, name, description, price, decimal_digits", productsId) - defer rows.Close() - for rows.Next() { - product := newInvoiceProductForm(index, company, locale, form.Tax.Options) - if err := rows.Scan(product.ProductId, product.Name, product.Description, product.Price, product.Quantity, product.Discount, product.Tax); err != nil { - panic(err) - } - form.Products = append(form.Products, product) - index++ + if err := verifyCsrfTokenValid(r); err != nil { + http.Error(w, err.Error(), http.StatusForbidden) + return } - if rows.Err() != nil { - panic(rows.Err()) + switch r.Form.Get("action") { + case "update": + form.Update() + w.WriteHeader(http.StatusOK) + mustRenderNewInvoiceForm(w, r, form) + case "select-products": + w.WriteHeader(http.StatusOK) + mustRenderNewInvoiceProductsForm(w, r, form) + case "add-products": + form.AddProducts(r.Context(), conn, r.Form["id"]) + w.WriteHeader(http.StatusOK) + mustRenderNewInvoiceForm(w, r, form) + default: + http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) } - - w.WriteHeader(http.StatusOK) - mustRenderNewInvoiceForm(w, r, form) } type invoiceForm struct { @@ -412,6 +400,23 @@ func (form *invoiceForm) Update() { } } +func (form *invoiceForm) AddProducts(ctx context.Context, conn *Conn, productsId []string) { + index := len(form.Products) + rows := conn.MustQuery(ctx, "select product_id, name, description, to_price(price, decimal_digits), 1 as quantity, 0 as discount, array_remove(array_agg(tax_id), null) from product join company using (company_id) join currency using (currency_code) left join product_tax using (product_id) where product_id = any ($1) group by product_id, name, description, price, decimal_digits", productsId) + defer rows.Close() + for rows.Next() { + product := newInvoiceProductForm(index, form.company, form.locale, form.Tax.Options) + if err := rows.Scan(product.ProductId, product.Name, product.Description, product.Price, product.Quantity, product.Discount, product.Tax); err != nil { + panic(err) + } + form.Products = append(form.Products, product) + index++ + } + if rows.Err() != nil { + panic(rows.Err()) + } +} + func mustGetTaxOptions(ctx context.Context, conn *Conn, company *Company) []*SelectOption { return MustGetOptions(ctx, conn, "select tax_id::text, name from tax where company_id = $1 order by name", company.Id) } diff --git a/pkg/router.go b/pkg/router.go index eabc6d3..6362526 100644 --- a/pkg/router.go +++ b/pkg/router.go @@ -25,7 +25,7 @@ func NewRouter(db *Db) http.Handler { companyRouter.GET("/invoices", IndexInvoices) companyRouter.POST("/invoices", HandleAddInvoice) companyRouter.GET("/invoices/:slug", ServeInvoice) - companyRouter.POST("/invoices/new/products", HandleAddProductsToInvoice) + companyRouter.POST("/invoices/new", HandleNewInvoiceAction) companyRouter.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { mustRenderAppTemplate(w, r, "dashboard.gohtml", nil) }) diff --git a/web/template/invoices/new.gohtml b/web/template/invoices/new.gohtml index 6f41353..aa9a30f 100644 --- a/web/template/invoices/new.gohtml +++ b/web/template/invoices/new.gohtml @@ -55,9 +55,11 @@
- - diff --git a/web/template/invoices/products.gohtml b/web/template/invoices/products.gohtml index e6c9678..a7e700d 100644 --- a/web/template/invoices/products.gohtml +++ b/web/template/invoices/products.gohtml @@ -13,7 +13,7 @@

{{(pgettext "Add Products to Invoice" "title")}}

-
+ {{ csrfToken }} {{- with .Form }} @@ -61,7 +61,8 @@
- +