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
|
||
|
}
|