109 lines
3.2 KiB
Go
109 lines
3.2 KiB
Go
package meals
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"slices"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/core/handler"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces/params"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/model/external/stwbremen"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/model/resources"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/util"
|
|
)
|
|
|
|
type MealsHandler struct {
|
|
interfaces.ResourceHandler
|
|
interfaces.GetHandler
|
|
|
|
QueryClient interfaces.QueryClient[[]stwbremen.Meal]
|
|
}
|
|
|
|
func (h *MealsHandler) Get(ctx context.Context, name string, params params.Container) (*interfaces.ResourceList, error) {
|
|
// Read parameters
|
|
date, err := params.GetValue(handler.ParamDate)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to parse date parameter: %w", err)
|
|
}
|
|
|
|
restaurant, err := params.GetValue(handler.ParamRestaurant)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to parse restaurant parameter: %w", err)
|
|
}
|
|
|
|
// Build query
|
|
query := "page('meals').children.filterBy('printonly', 0)"
|
|
if date != "" {
|
|
parsed, err := time.Parse(time.DateOnly, date.(string))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to parse date parameter: %w", err)
|
|
}
|
|
query += fmt.Sprintf(".filterBy('date', '%s')", parsed.Format(time.DateOnly))
|
|
}
|
|
if restaurant != "" {
|
|
query += fmt.Sprintf(".filterBy('location', '%s')", restaurant.(string))
|
|
}
|
|
if name != "" {
|
|
query += fmt.Sprintf(".filterBy('id', 'meals/%s')", name)
|
|
}
|
|
|
|
// Run query
|
|
meals, err := h.QueryClient.Get(ctx,
|
|
query,
|
|
`{"title":true,"id":"page.id","ingredients":"page.ingredients.toObject","prices":"page.prices.toObject","location":true,"counter":true,"date":true,"mealadds":true,"mark":true,"frei3":true,"printonly":true,"kombicategory":true,"categories":"page.categories.split"}`,
|
|
false,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("querying menu failed: %w", err)
|
|
}
|
|
|
|
// Transform to meal resource
|
|
items := util.Transform(*meals, func(i *stwbremen.Meal) *resources.Meal {
|
|
d, err := resources.MealFromDTO(*i)
|
|
if err != nil {
|
|
return &resources.Meal{}
|
|
}
|
|
|
|
return d
|
|
})
|
|
|
|
// Sort by date, restaurant and title - need to apply stable sorts in reverse order to achieve this
|
|
slices.SortFunc(items, func(a, b *resources.Meal) int {
|
|
return strings.Compare(a.Title, b.Title)
|
|
})
|
|
slices.SortStableFunc(items, func(a, b *resources.Meal) int {
|
|
return strings.Compare(a.RestaurantID, b.RestaurantID)
|
|
})
|
|
slices.SortStableFunc(items, func(a, b *resources.Meal) int {
|
|
return a.Date.Compare(b.Date)
|
|
})
|
|
|
|
// Return
|
|
return &interfaces.ResourceList{
|
|
ItemKind: resources.ResourceMeal,
|
|
Items: util.Transform(items, func(i **resources.Meal) interfaces.Resource { return *i }),
|
|
}, nil
|
|
}
|
|
|
|
func (h *MealsHandler) GetParametersForVerb(verb interfaces.Verb) []params.Registration {
|
|
return []params.Registration{
|
|
{
|
|
Name: handler.ParamDate,
|
|
ShortHand: "d",
|
|
Description: "Meal date",
|
|
DefaultFunc: func() string { return "" },
|
|
ParseFunc: params.ParseString,
|
|
},
|
|
{
|
|
Name: handler.ParamRestaurant,
|
|
ShortHand: "r",
|
|
Description: "Select a restaurant",
|
|
DefaultFunc: func() string { return "" },
|
|
ParseFunc: params.ParseString,
|
|
},
|
|
}
|
|
}
|