/* eslint-disable @typescript-eslint/ban-types */ import { Injectable } from '@nestjs/common' import { isEmpty } from 'lodash' import { classToPlain, plainToClass } from 'class-transformer' import { MealGroup, MealItem, Menu } from '../models' import { HttpService } from '../services/http' import { BaseRepository } from './base.repository' const FIND_BY_GOAL_AND_RESTRICTIONS = ` query menus($goalId: uuid!, $restrictionIds: [uuid!]) { menu(limit: 10, where: {goal_id: {_eq: $goalId}, menu_restrictions: {restriction_id: {_in: $restrictionIds}}, active: {_eq: true}, reference_food_plan_id: {_is_null: true}}) { id } } ` const FIND_BY_GOAL = ` query menus($goalId: uuid!) { menu(limit: 10, where: {goal_id: {_eq: $goalId}, _not:{menu_restrictions: {}}, active: {_eq: true}, reference_food_plan_id: {_is_null: true}}) { id } } ` const GET = ` query menu($id: uuid!) { menu_by_pk(id: $id) { active goal_id id title meal_groups { menu_id orientations meal_type_id food_record_id id food_plan_id } } } ` const CREATE_WITH_RELATIONSHIPS = ` mutation createWithRelationships($object: menu_insert_input!) { insert_menu_one(object: $object) { id } } ` @Injectable() export class MenuRepository extends BaseRepository { constructor(protected readonly httpService: HttpService) { super(httpService, 'menu') } async findBy(goalId: string, restrictionIds: string[]): Promise { const variables = isEmpty(restrictionIds) ? { goalId } : { goalId, restrictionIds } const query = isEmpty(restrictionIds) ? FIND_BY_GOAL : FIND_BY_GOAL_AND_RESTRICTIONS const { data } = await this.fetchGraphQL({ body: { query, variables }, }) return data.menu.map((menu: any) => plainToClass(Menu, menu)) } async get(id: string): Promise { const { data } = await this.fetchGraphQL({ body: { query: GET, variables: { id } }, }) return data.menu_by_pk ? plainToClass(Menu, { ...data.menu_by_pk, meal_groups: (data.menu_by_pk.meal_groups || []).map(meal_group => plainToClass(MealGroup, meal_group)), }) : null } async createWithRelationships(menu: Menu): Promise { const plainObject = classToPlain(menu) const object = { ...plainObject, meal_groups: { data: plainObject.meal_groups.map((mealGroup: MealGroup) => this.mapMealGroup(mealGroup)), }, } const { data } = await this.fetchGraphQL({ body: { query: CREATE_WITH_RELATIONSHIPS, variables: { object } }, }) return data?.insert_menu_one?.id } private mapMealGroup(mealGroup: MealGroup): object { return { ...mealGroup, meals: { data: mealGroup.meals.map(mealItems => ({ id: mealItems.id, items: { data: mealItems.items.map(item => this.mapMealItem(item)), }, })), }, } } private mapMealItem(mealItem: MealItem): object { return { ...mealItem, substitutes: { data: mealItem.substitutes.map(substitute => this.mapMealItem(substitute)), }, ingredients: { data: mealItem.ingredients.map(ingredient => this.mapMealItem(ingredient)), }, } } }