Use slugs too to select invoice products without JavaScript
The product search returns a list of products using its slug as the “external key”, because i do not want people seeing the id in links, and the search product list is just a different rendering of the product index table. However, now i had two almost identical select queries for product, one using the product_id and the other its slug, the former intended for the form to select products using checkboxes—the one non-JavaScript users see—and the latter for the product search. Using the slug in both forms i can now simplify the code and have a single query.
This commit is contained in:
parent
f2a0cd7d94
commit
a06bc3df58
|
@ -437,13 +437,13 @@ func mustRenderNewInvoiceProductsForm(w http.ResponseWriter, r *http.Request, ac
|
|||
}
|
||||
|
||||
func mustGetProductChoices(ctx context.Context, conn *Conn, company *Company) []*productChoice {
|
||||
rows := conn.MustQuery(ctx, "select product.product_id, product.name, to_price(price, decimal_digits) from product join company using (company_id) join currency using (currency_code) where company_id = $1 order by name", company.Id)
|
||||
rows := conn.MustQuery(ctx, "select product.slug, product.name, to_price(price, decimal_digits) from product join company using (company_id) join currency using (currency_code) where company_id = $1 order by name", company.Id)
|
||||
defer rows.Close()
|
||||
|
||||
var choices []*productChoice
|
||||
for rows.Next() {
|
||||
entry := &productChoice{}
|
||||
if err := rows.Scan(&entry.Id, &entry.Name, &entry.Price); err != nil {
|
||||
if err := rows.Scan(&entry.Slug, &entry.Name, &entry.Price); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
choices = append(choices, entry)
|
||||
|
@ -462,7 +462,7 @@ type newInvoiceProductsPage struct {
|
|||
}
|
||||
|
||||
type productChoice struct {
|
||||
Id int
|
||||
Slug string
|
||||
Name string
|
||||
Price string
|
||||
}
|
||||
|
@ -664,8 +664,29 @@ func (form *invoiceForm) Update() {
|
|||
}
|
||||
}
|
||||
|
||||
func (form *invoiceForm) AddProducts(ctx context.Context, conn *Conn, productsId []string) {
|
||||
form.mustAddProductsFromQuery(ctx, conn, "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)
|
||||
const selectProductBySlug = `
|
||||
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.slug = any ($1)
|
||||
group by product_id
|
||||
, name
|
||||
, description
|
||||
, price
|
||||
, decimal_digits
|
||||
`
|
||||
|
||||
func (form *invoiceForm) AddProducts(ctx context.Context, conn *Conn, productsSlug []string) {
|
||||
form.mustAddProductsFromQuery(ctx, conn, selectProductBySlug, productsSlug)
|
||||
}
|
||||
|
||||
func (form *invoiceForm) mustAddProductsFromQuery(ctx context.Context, conn *Conn, sql string, args ...interface{}) {
|
||||
|
@ -864,25 +885,8 @@ func (form *invoiceProductForm) Update() {
|
|||
}
|
||||
|
||||
func (form *invoiceProductForm) MustFillFromDatabase(ctx context.Context, conn *Conn, slug string) bool {
|
||||
return !notFoundErrorOrPanic(conn.QueryRow(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.slug = $1
|
||||
group by product_id
|
||||
, name
|
||||
, description
|
||||
, price
|
||||
, decimal_digits
|
||||
`, slug).Scan(
|
||||
return !notFoundErrorOrPanic(conn.QueryRow(ctx, selectProductBySlug, []string{slug}).Scan(
|
||||
form.InvoiceProductId,
|
||||
form.ProductId,
|
||||
form.Name,
|
||||
form.Description,
|
||||
|
@ -1006,7 +1010,7 @@ func handleInvoiceAction(w http.ResponseWriter, r *http.Request, action string,
|
|||
w.WriteHeader(http.StatusOK)
|
||||
mustRenderNewInvoiceProductsForm(w, r, action, form)
|
||||
case "add-products":
|
||||
form.AddProducts(r.Context(), conn, r.Form["id"])
|
||||
form.AddProducts(r.Context(), conn, r.Form["slug"])
|
||||
w.WriteHeader(http.StatusOK)
|
||||
renderForm(w, r, form)
|
||||
default:
|
||||
|
|
|
@ -52,10 +52,10 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
{{ with .Products }}
|
||||
{{- range $product, $key := . }}
|
||||
{{- range . }}
|
||||
<tr>
|
||||
<td><input type="checkbox" name="id" id="new-product-id-{{$key}}" value="{{.Id}}"></td>
|
||||
<td><label for="new-product-id-{{$key}}">{{ .Name }}</label></td>
|
||||
<td><input type="checkbox" name="slug" id="product-{{ .Slug }}" value="{{.Slug}}"></td>
|
||||
<td><label for="product-{{ .Slug }}">{{ .Name }}</label></td>
|
||||
<td class="numeric">{{ .Price | formatPrice }}</td>
|
||||
</tr>
|
||||
{{- end }}
|
||||
|
|
Loading…
Reference in New Issue