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