I’ve removed the total amount because it is very difficult to get it with pagination, and customer never saw it (it was from Numerus), thus they won’t miss it—i hope.
125 lines
3.2 KiB
Go
125 lines
3.2 KiB
Go
package invoice
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"dev.tandem.ws/tandem/camper/pkg/auth"
|
|
"dev.tandem.ws/tandem/camper/pkg/database"
|
|
"dev.tandem.ws/tandem/camper/pkg/form"
|
|
"dev.tandem.ws/tandem/camper/pkg/locale"
|
|
)
|
|
|
|
type filterForm struct {
|
|
company *auth.Company
|
|
Customer *form.Select
|
|
InvoiceStatus *form.Select
|
|
InvoiceNumber *form.Input
|
|
FromDate *form.Input
|
|
ToDate *form.Input
|
|
Cursor *form.Cursor
|
|
}
|
|
|
|
func newFilterForm(ctx context.Context, conn *database.Conn, company *auth.Company, locale *locale.Locale) *filterForm {
|
|
return &filterForm{
|
|
company: company,
|
|
Customer: &form.Select{
|
|
Name: "customer",
|
|
Options: mustGetContactOptions(ctx, conn, company),
|
|
},
|
|
InvoiceStatus: &form.Select{
|
|
Name: "invoice_status",
|
|
Options: mustGetInvoiceStatusOptions(ctx, conn, locale),
|
|
},
|
|
InvoiceNumber: &form.Input{
|
|
Name: "number",
|
|
},
|
|
FromDate: &form.Input{
|
|
Name: "from_date",
|
|
},
|
|
ToDate: &form.Input{
|
|
Name: "to_date",
|
|
},
|
|
Cursor: &form.Cursor{
|
|
Name: "cursor",
|
|
PerPage: 25,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (f *filterForm) Parse(r *http.Request) error {
|
|
if err := r.ParseForm(); err != nil {
|
|
return err
|
|
}
|
|
f.Customer.FillValue(r)
|
|
f.InvoiceStatus.FillValue(r)
|
|
f.InvoiceNumber.FillValue(r)
|
|
f.FromDate.FillValue(r)
|
|
f.ToDate.FillValue(r)
|
|
f.Cursor.FillValue(r)
|
|
return nil
|
|
}
|
|
|
|
func (f *filterForm) BuildQuery(args []interface{}) (string, []interface{}) {
|
|
var where []string
|
|
appendWhere := func(expression string, value interface{}) {
|
|
args = append(args, value)
|
|
where = append(where, fmt.Sprintf(expression, len(args)))
|
|
}
|
|
maybeAppendWhere := func(expression string, value string, conv func(string) interface{}) {
|
|
if value != "" {
|
|
if conv == nil {
|
|
appendWhere(expression, value)
|
|
} else {
|
|
appendWhere(expression, conv(value))
|
|
}
|
|
}
|
|
}
|
|
|
|
appendWhere("invoice.company_id = $%d", f.company.ID)
|
|
maybeAppendWhere("contact_id = $%d", f.Customer.String(), func(v string) interface{} {
|
|
customerId, _ := strconv.Atoi(f.Customer.Selected[0])
|
|
return customerId
|
|
})
|
|
maybeAppendWhere("invoice.invoice_status = $%d", f.InvoiceStatus.String(), nil)
|
|
maybeAppendWhere("invoice_number = $%d", f.InvoiceNumber.Val, nil)
|
|
maybeAppendWhere("invoice_date >= $%d", f.FromDate.Val, nil)
|
|
maybeAppendWhere("invoice_date <= $%d", f.ToDate.Val, nil)
|
|
|
|
if f.Paginated() {
|
|
params := f.Cursor.Params()
|
|
if len(params) == 2 {
|
|
where = append(where, fmt.Sprintf("(invoice_date, invoice_number) < ($%d, $%d)", len(args)+1, len(args)+2))
|
|
args = append(args, params[0])
|
|
args = append(args, params[1])
|
|
}
|
|
}
|
|
|
|
return strings.Join(where, ") AND ("), args
|
|
}
|
|
|
|
func (f *filterForm) buildCursor(customers []*IndexEntry) []*IndexEntry {
|
|
return form.BuildCursor(f.Cursor, customers, func(entry *IndexEntry) []string {
|
|
return []string{entry.Date.Format(database.ISODateFormat), entry.Number}
|
|
})
|
|
}
|
|
|
|
func (f *filterForm) HasValue() bool {
|
|
return (len(f.Customer.Selected) > 0 && f.Customer.Selected[0] != "") ||
|
|
(len(f.InvoiceStatus.Selected) > 0 && f.InvoiceStatus.Selected[0] != "") ||
|
|
f.InvoiceNumber.Val != "" ||
|
|
f.FromDate.Val != "" ||
|
|
f.ToDate.Val != ""
|
|
}
|
|
|
|
func (f *filterForm) PerPage() int {
|
|
return f.Cursor.PerPage
|
|
}
|
|
|
|
func (f *filterForm) Paginated() bool {
|
|
return f.Cursor.Pagination
|
|
}
|