Move booking filter form struct into a separate file
This commit is contained in:
parent
e5253f9adb
commit
50548c29ab
|
@ -243,124 +243,6 @@ func (page bookingIndex) MustRender(w http.ResponseWriter, r *http.Request, user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type filterForm struct {
|
|
||||||
locale *locale.Locale
|
|
||||||
company *auth.Company
|
|
||||||
perPage int
|
|
||||||
pagination bool
|
|
||||||
HolderName *form.Input
|
|
||||||
BookingStatus *form.Select
|
|
||||||
FromDate *form.Input
|
|
||||||
ToDate *form.Input
|
|
||||||
Cursor *form.Input
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFilterForm(ctx context.Context, conn *database.Conn, company *auth.Company, locale *locale.Locale) *filterForm {
|
|
||||||
return &filterForm{
|
|
||||||
locale: locale,
|
|
||||||
company: company,
|
|
||||||
perPage: 25,
|
|
||||||
HolderName: &form.Input{
|
|
||||||
Name: "holder_name",
|
|
||||||
},
|
|
||||||
BookingStatus: &form.Select{
|
|
||||||
Name: "booking_status",
|
|
||||||
Options: mustGetBookingStatusOptions(ctx, conn, locale),
|
|
||||||
},
|
|
||||||
FromDate: &form.Input{
|
|
||||||
Name: "from_date",
|
|
||||||
},
|
|
||||||
ToDate: &form.Input{
|
|
||||||
Name: "to_date",
|
|
||||||
},
|
|
||||||
Cursor: &form.Input{
|
|
||||||
Name: "cursor",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustGetBookingStatusOptions(ctx context.Context, conn *database.Conn, locale *locale.Locale) []*form.Option {
|
|
||||||
return form.MustGetOptions(ctx, conn, `
|
|
||||||
select booking_status.booking_status
|
|
||||||
, isi18n.name
|
|
||||||
from booking_status
|
|
||||||
join booking_status_i18n isi18n using(booking_status)
|
|
||||||
where isi18n.lang_tag = $1
|
|
||||||
and booking_status <> 'created'
|
|
||||||
order by booking_status`, locale.Language)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *filterForm) Parse(r *http.Request) error {
|
|
||||||
if err := r.ParseForm(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.HolderName.FillValue(r)
|
|
||||||
f.BookingStatus.FillValue(r)
|
|
||||||
f.FromDate.FillValue(r)
|
|
||||||
f.ToDate.FillValue(r)
|
|
||||||
f.Cursor.FillValue(r)
|
|
||||||
f.pagination = f.Cursor.Val != ""
|
|
||||||
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("booking.company_id = $%d", f.company.ID)
|
|
||||||
maybeAppendWhere("booking.holder_name ILIKE $%d", f.HolderName.Val, func(v string) interface{} {
|
|
||||||
return "%" + v + "%"
|
|
||||||
})
|
|
||||||
if len(f.BookingStatus.Selected) == 0 {
|
|
||||||
where = append(where, "booking.booking_status <> 'created'")
|
|
||||||
} else {
|
|
||||||
maybeAppendWhere("booking.booking_status = $%d", f.BookingStatus.String(), nil)
|
|
||||||
}
|
|
||||||
maybeAppendWhere("lower(stay) >= $%d", f.FromDate.Val, nil)
|
|
||||||
maybeAppendWhere("lower(stay) <= $%d", f.ToDate.Val, nil)
|
|
||||||
|
|
||||||
if f.Cursor.Val != "" {
|
|
||||||
params := strings.Split(f.Cursor.Val, ";")
|
|
||||||
if len(params) == 2 {
|
|
||||||
where = append(where, fmt.Sprintf("(lower(stay), booking_id) < ($%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(bookings []*bookingEntry) []*bookingEntry {
|
|
||||||
if len(bookings) <= f.perPage {
|
|
||||||
f.Cursor.Val = ""
|
|
||||||
return bookings
|
|
||||||
}
|
|
||||||
bookings = bookings[:f.perPage]
|
|
||||||
last := bookings[f.perPage-1]
|
|
||||||
f.Cursor.Val = fmt.Sprintf("%s;%d", last.ArrivalDate.Format(database.ISODateFormat), last.ID)
|
|
||||||
return bookings
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *filterForm) HasValue() bool {
|
|
||||||
return f.HolderName.Val != "" ||
|
|
||||||
(len(f.BookingStatus.Selected) > 0 && f.BookingStatus.Selected[0] != "") ||
|
|
||||||
f.FromDate.Val != "" ||
|
|
||||||
f.ToDate.Val != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type adminBookingForm struct {
|
type adminBookingForm struct {
|
||||||
*bookingForm
|
*bookingForm
|
||||||
ID int
|
ID int
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
package booking
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"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 {
|
||||||
|
locale *locale.Locale
|
||||||
|
company *auth.Company
|
||||||
|
perPage int
|
||||||
|
pagination bool
|
||||||
|
HolderName *form.Input
|
||||||
|
BookingStatus *form.Select
|
||||||
|
FromDate *form.Input
|
||||||
|
ToDate *form.Input
|
||||||
|
Cursor *form.Input
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFilterForm(ctx context.Context, conn *database.Conn, company *auth.Company, locale *locale.Locale) *filterForm {
|
||||||
|
return &filterForm{
|
||||||
|
locale: locale,
|
||||||
|
company: company,
|
||||||
|
perPage: 25,
|
||||||
|
HolderName: &form.Input{
|
||||||
|
Name: "holder_name",
|
||||||
|
},
|
||||||
|
BookingStatus: &form.Select{
|
||||||
|
Name: "booking_status",
|
||||||
|
Options: mustGetBookingStatusOptions(ctx, conn, locale),
|
||||||
|
},
|
||||||
|
FromDate: &form.Input{
|
||||||
|
Name: "from_date",
|
||||||
|
},
|
||||||
|
ToDate: &form.Input{
|
||||||
|
Name: "to_date",
|
||||||
|
},
|
||||||
|
Cursor: &form.Input{
|
||||||
|
Name: "cursor",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustGetBookingStatusOptions(ctx context.Context, conn *database.Conn, locale *locale.Locale) []*form.Option {
|
||||||
|
return form.MustGetOptions(ctx, conn, `
|
||||||
|
select booking_status.booking_status
|
||||||
|
, isi18n.name
|
||||||
|
from booking_status
|
||||||
|
join booking_status_i18n isi18n using(booking_status)
|
||||||
|
where isi18n.lang_tag = $1
|
||||||
|
and booking_status <> 'created'
|
||||||
|
order by booking_status`, locale.Language)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterForm) Parse(r *http.Request) error {
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.HolderName.FillValue(r)
|
||||||
|
f.BookingStatus.FillValue(r)
|
||||||
|
f.FromDate.FillValue(r)
|
||||||
|
f.ToDate.FillValue(r)
|
||||||
|
f.Cursor.FillValue(r)
|
||||||
|
f.pagination = f.Cursor.Val != ""
|
||||||
|
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("booking.company_id = $%d", f.company.ID)
|
||||||
|
maybeAppendWhere("booking.holder_name ILIKE $%d", f.HolderName.Val, func(v string) interface{} {
|
||||||
|
return "%" + v + "%"
|
||||||
|
})
|
||||||
|
if len(f.BookingStatus.Selected) == 0 {
|
||||||
|
where = append(where, "booking.booking_status <> 'created'")
|
||||||
|
} else {
|
||||||
|
maybeAppendWhere("booking.booking_status = $%d", f.BookingStatus.String(), nil)
|
||||||
|
}
|
||||||
|
maybeAppendWhere("lower(stay) >= $%d", f.FromDate.Val, nil)
|
||||||
|
maybeAppendWhere("lower(stay) <= $%d", f.ToDate.Val, nil)
|
||||||
|
|
||||||
|
if f.Cursor.Val != "" {
|
||||||
|
params := strings.Split(f.Cursor.Val, ";")
|
||||||
|
if len(params) == 2 {
|
||||||
|
where = append(where, fmt.Sprintf("(lower(stay), booking_id) < ($%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(bookings []*bookingEntry) []*bookingEntry {
|
||||||
|
if len(bookings) <= f.perPage {
|
||||||
|
f.Cursor.Val = ""
|
||||||
|
return bookings
|
||||||
|
}
|
||||||
|
bookings = bookings[:f.perPage]
|
||||||
|
last := bookings[f.perPage-1]
|
||||||
|
f.Cursor.Val = fmt.Sprintf("%s;%d", last.ArrivalDate.Format(database.ISODateFormat), last.ID)
|
||||||
|
return bookings
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *filterForm) HasValue() bool {
|
||||||
|
return f.HolderName.Val != "" ||
|
||||||
|
(len(f.BookingStatus.Selected) > 0 && f.BookingStatus.Selected[0] != "") ||
|
||||||
|
f.FromDate.Val != "" ||
|
||||||
|
f.ToDate.Val != ""
|
||||||
|
}
|
Loading…
Reference in New Issue