diff --git a/pkg/invoices.go b/pkg/invoices.go index b19b638..07bf53a 100644 --- a/pkg/invoices.go +++ b/pkg/invoices.go @@ -20,6 +20,8 @@ import ( "time" ) +const removedProductSuffix = ".removed" + type InvoiceEntry struct { Slug string Date time.Time @@ -553,16 +555,17 @@ func mustWriteInvoicesPdf(r *http.Request, slugs []string) []byte { } type invoiceForm struct { - locale *Locale - company *Company - Number string - InvoiceStatus *SelectField - Customer *SelectField - Date *InputField - Notes *InputField - PaymentMethod *SelectField - Tags *TagsField - Products []*invoiceProductForm + locale *Locale + company *Company + Number string + InvoiceStatus *SelectField + Customer *SelectField + Date *InputField + Notes *InputField + PaymentMethod *SelectField + Tags *TagsField + Products []*invoiceProductForm + RemovedProduct *invoiceProductForm } func newInvoiceForm(ctx context.Context, conn *Conn, locale *Locale, company *Company) *invoiceForm { @@ -665,6 +668,25 @@ func (form *invoiceForm) Update() { } } +func (form *invoiceForm) RemoveProduct(index int) { + products := form.Products + form.Products = nil + for n, product := range products { + if n == index { + form.RemovedProduct = product + } else { + if n != len(form.Products) { + product.Index = len(form.Products) + product.Rename() + } + form.Products = append(form.Products, product) + } + } + if form.RemovedProduct != nil { + form.RemovedProduct.RenameWithSuffix(removedProductSuffix) + } +} + const selectProductBySlug = ` select '' , product_id @@ -708,6 +730,23 @@ func (form *invoiceForm) mustAddProductsFromQuery(ctx context.Context, conn *Con } } +func (form *invoiceForm) InsertProduct(product *invoiceProductForm) { + replaced := false + for n, existing := range form.Products { + if existing.Quantity.Val == "" || existing.Quantity.Val == "0" { + product.Index = n + form.Products[n] = product + replaced = true + break + } + } + if !replaced { + product.Index = len(form.Products) + form.Products = append(form.Products, product) + } + product.Rename() +} + func (form *invoiceForm) MustFillFromDatabase(ctx context.Context, conn *Conn, slug string) bool { var invoiceId int selectedInvoiceStatus := form.InvoiceStatus.Selected @@ -834,7 +873,9 @@ func newInvoiceProductForm(index int, company *Company, locale *Locale, taxOptio } func (form *invoiceProductForm) Rename() { - suffix := "." + strconv.Itoa(form.Index) + form.RenameWithSuffix("." + strconv.Itoa(form.Index)) +} +func (form *invoiceProductForm) RenameWithSuffix(suffix string) { form.InvoiceProductId.Name = "product.invoice_product_id" + suffix form.ProductId.Name = "product.id" + suffix form.Name.Name = "product.name" + suffix @@ -1018,7 +1059,8 @@ func handleInvoiceAction(w http.ResponseWriter, r *http.Request, action string, http.Error(w, err.Error(), http.StatusForbidden) return } - switch r.Form.Get("action") { + actionField := r.Form.Get("action") + switch actionField { case "update": form.Update() w.WriteHeader(http.StatusOK) @@ -1030,8 +1072,31 @@ func handleInvoiceAction(w http.ResponseWriter, r *http.Request, action string, form.AddProducts(r.Context(), conn, r.Form["slug"]) w.WriteHeader(http.StatusOK) renderForm(w, r, form) + case "restore-product": + restoredProduct := newInvoiceProductForm(0, company, locale, mustGetTaxOptions(r.Context(), conn, company)) + restoredProduct.RenameWithSuffix(removedProductSuffix) + if err := restoredProduct.Parse(r); err != nil { + panic(err) + } + form.InsertProduct(restoredProduct) + form.Update() + w.WriteHeader(http.StatusOK) + renderForm(w, r, form) default: - http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) + prefix := "remove-product." + if strings.HasPrefix(actionField, prefix) { + index, err := strconv.Atoi(actionField[len(prefix):]) + if err != nil { + http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) + } else { + form.RemoveProduct(index) + form.Update() + w.WriteHeader(http.StatusOK) + renderForm(w, r, form) + } + } else { + http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest) + } } } diff --git a/web/template/form.gohtml b/web/template/form.gohtml index 6235c76..3421438 100644 --- a/web/template/form.gohtml +++ b/web/template/form.gohtml @@ -145,13 +145,13 @@ {{ define "invoice-product-form" -}} {{- /*gotype: dev.tandem.ws/tandem/numerus/pkg.invoiceProductForm*/ -}}