diff --git a/internal/handlers/web/invoices.go b/internal/handlers/web/invoices.go index 26902c2..f3ed3b6 100644 --- a/internal/handlers/web/invoices.go +++ b/internal/handlers/web/invoices.go @@ -12,6 +12,22 @@ import ( "strings" ) +type StatusButton struct { + Status string + Label string + Class string + ConfirmText string +} + +var statusButtons = []StatusButton{ + {"draft", "Draft Invoice", "success-button", "Are you sure you want to draft this invoice?"}, + {"ok", "Ok Invoice", "success-button", "Are you sure you want to mark this invoice as OK?"}, + {"fail", "Fail Invoice", "caution-button", "Are you sure you want to fail this invoice?"}, + {"pending", "Pending Invoice", "caution-button", "Are you sure you want to mark this invoice as pending?"}, + {"processed", "Process Invoice", "warning-button", "Are you sure you want to process this invoice?"}, + {"void", "Void Invoice", "warning-button", "Are you sure you want to void this invoice?"}, +} + func InvoicesHandler(w http.ResponseWriter, r *http.Request) { session, ok := r.Context().Value("session").(*api.Session) if !ok { @@ -85,6 +101,11 @@ func handleInvoiceSearch(w http.ResponseWriter, r *http.Request, session *api.Se // log.Printf("Invoice found: %+v", invoice) + if invoice != nil { + // Add the buttons to display + invoice["buttons"] = getInvoiceStatusButtons(invoice["id"].(string), invoice["status"].(string)) + } + tmpl := template.Must(template.ParseFiles("templates/partials/invoice_search_results.html")) err = tmpl.ExecuteTemplate(w, "invoice_search_results", invoice) if err != nil { @@ -93,6 +114,43 @@ func handleInvoiceSearch(w http.ResponseWriter, r *http.Request, session *api.Se } } +func getInvoiceStatusButtons(invoiceID, currentStatus string) []map[string]string { + var buttons []map[string]string + + switch currentStatus { + case "processed": + // Only allow voiding for processed invoices + for _, button := range statusButtons { + if button.Status == "void" { + buttons = append(buttons, map[string]string{ + "Action": fmt.Sprintf("/%s-invoice/%s", button.Status, invoiceID), + "Label": button.Label, + "Class": button.Class, + "ConfirmText": button.ConfirmText, + }) + break + } + } + case "void": + // No buttons for voided invoices + return buttons + default: + // For all other statuses, show all buttons except the current status + for _, button := range statusButtons { + if button.Status != currentStatus { + buttons = append(buttons, map[string]string{ + "Action": fmt.Sprintf("/%s-invoice/%s", button.Status, invoiceID), + "Label": button.Label, + "Class": button.Class, + "ConfirmText": button.ConfirmText, + }) + } + } + } + + return buttons +} + func UpdateInvoiceStatusHandler(w http.ResponseWriter, r *http.Request) { session, ok := r.Context().Value("session").(*api.Session) if !ok { diff --git a/templates/partials/invoice_search_results.html b/templates/partials/invoice_search_results.html index 70fee26..7bc0b6c 100644 --- a/templates/partials/invoice_search_results.html +++ b/templates/partials/invoice_search_results.html @@ -1,65 +1,30 @@ {{define "invoice_search_results"}} {{if .Error}}
-

{{.ErrorMsg}}

+ {{.ErrorMsg}}

Search term: "{{.SearchTerm}}"

{{else if .NotFound}}
-

{{.ErrorMsg}}

+ {{.ErrorMsg}}

Search term: "{{.SearchTerm}}"

{{else if .invoiceNumber}}

Invoice Details

-{{if and (or (ne .status "void") (ne .status "processed")) (or (eq .status -"draft") (eq .status "ok") (eq .status "pending_accounting") (eq .status -"failed") )}} + +{{range .buttons}} - - - -{{end}} {{if and (ne .status "void") (ne .status "processed")}} - - {{end}} +

Invoice Number: {{.invoiceNumber}}

Total Price: ${{.totalPrice}}

Status: {{.status}}

+ {{with .customer}}

Customer: {{.name}}

{{end}} {{with .job}}