From 570e0eadd7a72e6496d817e343d03049f34cec45 Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 27 Sep 2024 18:25:07 +0200 Subject: [PATCH 1/7] start catalogue service and BFF --- .../remote.catalogue.controller.ts | 18 +++++++ libs/services/common/src/index.ts | 1 + libs/services/common/src/lib/container.ts | 6 ++- .../common/src/lib/offer/catalogue.service.ts | 9 +++- .../src/lib/offer/catalogueRemoteService.ts | 52 +++++++++++++++++++ .../src/lib/offer/catalogueServiceWorkflow.ts | 45 ++++++++++++++++ 6 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts create mode 100644 libs/services/common/src/lib/offer/catalogueRemoteService.ts create mode 100644 libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts diff --git a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts new file mode 100644 index 0000000..3a041d4 --- /dev/null +++ b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts @@ -0,0 +1,18 @@ +import { Body, Controller, Get, HttpCode, Param, Post } from '@nestjs/common'; +import { ApiProperty, ApiTags } from '@nestjs/swagger'; +import { container } from '@spos/services/common'; +import { CatalogueServiceWorkflow, TYPES } from "@spos/services/common"; + + +@Controller('remoteCatalogue') +@ApiTags('remoteCatalogue') +export class RemoteGroupController { + constructor( + @inject(TYPES.CatalogueService) private catalogueService: CatalogueService + ) {} + + @Get('filteredCatalog') + async getFilteredCatalog(@Query('offerName') offerName: string) { + return this.catalogueService.getFilteredCatalog(offerName); + } +} \ No newline at end of file diff --git a/libs/services/common/src/index.ts b/libs/services/common/src/index.ts index b2d3906..7a36c56 100644 --- a/libs/services/common/src/index.ts +++ b/libs/services/common/src/index.ts @@ -9,3 +9,4 @@ export * from './lib/types'; export * from './lib/group/groupCreate.dto'; export * from './lib/group/groupServiceWorkflow'; export * from './lib/bff.container'; +export * from './lib/offer/catalogueServiceWorkflow'; diff --git a/libs/services/common/src/lib/container.ts b/libs/services/common/src/lib/container.ts index 2db79fe..aadefc6 100644 --- a/libs/services/common/src/lib/container.ts +++ b/libs/services/common/src/lib/container.ts @@ -6,8 +6,9 @@ import { TYPES } from "./types"; import { MenuApiService } from "./apis/menuApiService"; import { OfferService } from "./offer/offer.service"; import { GroupServiceWorkflow } from "./group/groupServiceWorkflow"; -import { CatalogService } from "./offer/catalogue.service"; +import { CatalogueService } from "./offer/catalogue.service"; import { GroupService } from "./group/groupService"; +import { CatalogueServiceWorkflow } from "./offer/catalogueServiceWorkflow"; const container = new Container(); container.bind(TYPES.GroupService).to(GroupServiceWorkflow).inSingletonScope(); @@ -15,6 +16,7 @@ container.bind(TYPES.TableService).to(TableService).inSingletonSco container.bind(TYPES.DiningApiService).to(DiningApiService).inSingletonScope(); container.bind(TYPES.MenuApiService).to(MenuApiService).inSingletonScope(); container.bind(TYPES.OfferService).to(OfferService).inSingletonScope(); -container.bind(TYPES.CatalogService).to(CatalogService).inSingletonScope(); +//container.bind(TYPES.CatalogService).to(CatalogService).inSingletonScope(); +container.bind(TYPES.CatalogService).to(CatalogueServiceWorkflow).inSingletonScope(); export { container }; diff --git a/libs/services/common/src/lib/offer/catalogue.service.ts b/libs/services/common/src/lib/offer/catalogue.service.ts index 1bba148..d5934c9 100644 --- a/libs/services/common/src/lib/offer/catalogue.service.ts +++ b/libs/services/common/src/lib/offer/catalogue.service.ts @@ -5,12 +5,17 @@ import { OfferService } from "./offer.service"; import { MenuItem } from "@spos/clients-menu"; -type CategorizedCatalog = { +export type CategorizedCatalog = { [category: string]: MenuItem[] }; +export interface CatalogueService { + getFilteredCatalog(offerName: string): Promise; + getFullItemFromItemIdsArray(idList: string[]): Promise; +} + @injectable() -export class CatalogService { +export class CatalogService implements CatalogueService{ constructor( @inject(TYPES.MenuApiService) private menuApiService: MenuApiService, @inject(TYPES.OfferService) private offerService: OfferService diff --git a/libs/services/common/src/lib/offer/catalogueRemoteService.ts b/libs/services/common/src/lib/offer/catalogueRemoteService.ts new file mode 100644 index 0000000..b937d6d --- /dev/null +++ b/libs/services/common/src/lib/offer/catalogueRemoteService.ts @@ -0,0 +1,52 @@ +import { inject, injectable } from 'inversify'; +import { TYPES } from '../types'; +import { MenuApiService } from '../apis/menuApiService'; +import { OfferService } from './offer.service'; +import { CategorizedCatalog, CatalogueService } from './catalogue.service'; +import { MenuItem } from "@spos/clients-menu"; + +@injectable() +export class CatalogueServiceWorkflow implements CatalogueService { + + private catalogCache: { [offerName: string]: CategorizedCatalog } = {}; + + constructor( + @inject(TYPES.MenuApiService) private menuApiService: MenuApiService, + @inject(TYPES.OfferService) private offerService: OfferService + ) {} + + async getFilteredCatalog(offerName: string): Promise { + if (this.catalogCache[offerName]) { + return this.catalogCache[offerName]; + } + + const offer = await this.offerService.getOffers().then(response => + response.find(element => element.name?.toLowerCase() === offerName?.toLowerCase()) + ); + + if (!offer) return {}; + + const availableCatalog = (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( + item => offer.availableItems.includes(item._id) + ); + + const categorizedCatalog: CategorizedCatalog = {}; + + availableCatalog.forEach(element => { + if (!categorizedCatalog[element.category]) { + categorizedCatalog[element.category] = []; + } + categorizedCatalog[element.category].push(element); + }); + + this.catalogCache[offerName] = categorizedCatalog; + + return categorizedCatalog; + } + + async getFullItemFromItemIdsArray(idList: string[]): Promise { + return (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( + item => idList.includes(item._id) + ); + } +} diff --git a/libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts b/libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts new file mode 100644 index 0000000..04118db --- /dev/null +++ b/libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts @@ -0,0 +1,45 @@ +import { inject, injectable } from 'inversify'; +import { TYPES } from '../types'; +import { MenuApiService } from '../apis/menuApiService'; +import { OfferService } from './offer.service'; +import { CategorizedCatalog, CatalogueService } from './catalogue.service'; +import { MenuItem } from "@spos/clients-menu"; + + +@injectable() +export class CatalogueServiceWorkflow implements CatalogueService { + + private menuApiService = new MenuApiService(); + private offerService = new OfferService(); + + + + async getFilteredCatalog(offerName: string): Promise { + const offer = await this.offerService.getOffers().then(response => + response.find(element => element.name?.toLowerCase() === offerName?.toLowerCase()) + ); + + if (!offer) return {}; + + const availableCatalog = (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( + item => offer.availableItems.includes(item._id) + ); + + const categorizedCatalog: CategorizedCatalog = {}; + + availableCatalog.forEach(element => { + if (!categorizedCatalog[element.category]) { + categorizedCatalog[element.category] = []; + } + categorizedCatalog[element.category].push(element); + }); + + return categorizedCatalog; + } + + async getFullItemFromItemIdsArray(idList: string[]): Promise { + return (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( + item => idList.includes(item._id) + ); + } +} From 61e04f25dbf9fbec3cd8147b53a73ee344dfa9da Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 27 Sep 2024 22:16:32 +0200 Subject: [PATCH 2/7] remote.catalogue.controller.ts --- .../remote.catalogue.controller.ts | 23 +++++++++++-------- libs/services/common/src/lib/container.ts | 2 +- libs/services/common/src/lib/types.ts | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts index 3a041d4..5746d54 100644 --- a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts +++ b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts @@ -1,18 +1,23 @@ -import { Body, Controller, Get, HttpCode, Param, Post } from '@nestjs/common'; +import { Body, Controller, Get, HttpCode, Param, Post, Query } from '@nestjs/common'; import { ApiProperty, ApiTags } from '@nestjs/swagger'; import { container } from '@spos/services/common'; -import { CatalogueServiceWorkflow, TYPES } from "@spos/services/common"; - +import { CatalogueServiceWorkflow,CatalogueService, TYPES,CategorizedCatalog } from "@spos/services/common"; +import { MenuItem } from '@spos/clients-menu'; +export class CategorizedCatalogDto implements CategorizedCatalog { + @ApiProperty({ type: () => [MenuItemDto], isArray: true }) + [category: string]: MenuItemDto[]; +} @Controller('remoteCatalogue') @ApiTags('remoteCatalogue') export class RemoteGroupController { - constructor( - @inject(TYPES.CatalogueService) private catalogueService: CatalogueService - ) {} - @Get('filteredCatalog') - async getFilteredCatalog(@Query('offerName') offerName: string) { - return this.catalogueService.getFilteredCatalog(offerName); + async getFilteredCatalog(@Query('offerName') offerName: string): Promise { + return container.get(TYPES.CatalogueService).getFilteredCatalog(offerName); + } + @Get('items') + async getFullItemFromItemIdsArray(@Query('ids') ids: string): Promise { + const idList = ids.split(','); + return container.get(TYPES.CatalogueService).getFullItemFromItemIdsArray(idList); } } \ No newline at end of file diff --git a/libs/services/common/src/lib/container.ts b/libs/services/common/src/lib/container.ts index aadefc6..b3e1f9f 100644 --- a/libs/services/common/src/lib/container.ts +++ b/libs/services/common/src/lib/container.ts @@ -17,6 +17,6 @@ container.bind(TYPES.DiningApiService).to(DiningApiService).in container.bind(TYPES.MenuApiService).to(MenuApiService).inSingletonScope(); container.bind(TYPES.OfferService).to(OfferService).inSingletonScope(); //container.bind(TYPES.CatalogService).to(CatalogService).inSingletonScope(); -container.bind(TYPES.CatalogService).to(CatalogueServiceWorkflow).inSingletonScope(); +container.bind(TYPES.CatalogueService).to(CatalogueServiceWorkflow).inSingletonScope(); export { container }; diff --git a/libs/services/common/src/lib/types.ts b/libs/services/common/src/lib/types.ts index 4f114b9..1566a6a 100644 --- a/libs/services/common/src/lib/types.ts +++ b/libs/services/common/src/lib/types.ts @@ -4,7 +4,7 @@ export const TYPES = { DiningApiService: Symbol.for('DiningApiService'), MenuApiService: Symbol.for('MenuApiService'), OfferService: Symbol.for('OfferService'), - CatalogService: Symbol.for('CatalogService'), + CatalogueService: Symbol.for('CatalogueService'), BackendBffApiService: Symbol.for('BackendBffApiService'), }; From 1ebbea8c0e81fe6092e659bb41e005914688fe53 Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 27 Sep 2024 22:38:08 +0200 Subject: [PATCH 3/7] MenuItemsDto --- .../remote.catalogue.controller.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts index 5746d54..fc3cadb 100644 --- a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts +++ b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts @@ -2,12 +2,33 @@ import { Body, Controller, Get, HttpCode, Param, Post, Query } from '@nestjs/com import { ApiProperty, ApiTags } from '@nestjs/swagger'; import { container } from '@spos/services/common'; import { CatalogueServiceWorkflow,CatalogueService, TYPES,CategorizedCatalog } from "@spos/services/common"; -import { MenuItem } from '@spos/clients-menu'; +import { MenuItem, MenuItemCategoryEnum } from '@spos/clients-menu'; + +export class MenuItemDto implements MenuItem { + @ApiProperty() + '_id': string; + + @ApiProperty() + 'fullName': string; + + @ApiProperty() + 'shortName': string; + + @ApiProperty() + 'price': number; + + @ApiProperty({ enum: MenuItemCategoryEnum }) + 'category': MenuItemCategoryEnum; + + @ApiProperty() + 'image': string; + } export class CategorizedCatalogDto implements CategorizedCatalog { @ApiProperty({ type: () => [MenuItemDto], isArray: true }) [category: string]: MenuItemDto[]; } + @Controller('remoteCatalogue') @ApiTags('remoteCatalogue') export class RemoteGroupController { From fdbab5bf0ead47fa9904ed23422944f493ac5b97 Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 27 Sep 2024 22:54:18 +0200 Subject: [PATCH 4/7] remote.catalogue.controller.ts --- .../remote.catalogue.controller.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts index fc3cadb..35db8df 100644 --- a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts +++ b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts @@ -1,7 +1,7 @@ -import { Body, Controller, Get, HttpCode, Param, Post, Query } from '@nestjs/common'; +import { Controller, Get, Query } from '@nestjs/common'; import { ApiProperty, ApiTags } from '@nestjs/swagger'; import { container } from '@spos/services/common'; -import { CatalogueServiceWorkflow,CatalogueService, TYPES,CategorizedCatalog } from "@spos/services/common"; +import { CatalogueService, TYPES, CategorizedCatalog } from "@spos/services/common"; import { MenuItem, MenuItemCategoryEnum } from '@spos/clients-menu'; export class MenuItemDto implements MenuItem { @@ -22,20 +22,22 @@ export class MenuItemDto implements MenuItem { @ApiProperty() 'image': string; - } +} -export class CategorizedCatalogDto implements CategorizedCatalog { - @ApiProperty({ type: () => [MenuItemDto], isArray: true }) - [category: string]: MenuItemDto[]; +export class CategorizedCatalogDto { + @ApiProperty({ type: 'object', additionalProperties: { type: 'array', items: { $ref: '#/components/schemas/MenuItemDto' } } }) + categories: Record; } @Controller('remoteCatalogue') @ApiTags('remoteCatalogue') -export class RemoteGroupController { +export class RemoteCatalogueController { @Get('filteredCatalog') async getFilteredCatalog(@Query('offerName') offerName: string): Promise { - return container.get(TYPES.CatalogueService).getFilteredCatalog(offerName); + const catalog = await container.get(TYPES.CatalogueService).getFilteredCatalog(offerName); + return { categories: catalog }; } + @Get('items') async getFullItemFromItemIdsArray(@Query('ids') ids: string): Promise { const idList = ids.split(','); From 301f1430a6f2b5bd1507fc238b47e8759118eeee Mon Sep 17 00:00:00 2001 From: Anna Date: Sat, 28 Sep 2024 11:16:55 +0200 Subject: [PATCH 5/7] api essai --- apps/backend-bff/src/app/app.module.ts | 3 +- libs/clients/bff/openapi.json | 2 +- .../src/lib/apis/backendBffApiService.ts | 1 + .../src/lib/offer/catalogueRemoteService.ts | 52 ------------------- .../src/lib/commandsR/orderingChoices.tsx | 4 +- 5 files changed, 6 insertions(+), 56 deletions(-) diff --git a/apps/backend-bff/src/app/app.module.ts b/apps/backend-bff/src/app/app.module.ts index 737a3d7..6a6cb9b 100644 --- a/apps/backend-bff/src/app/app.module.ts +++ b/apps/backend-bff/src/app/app.module.ts @@ -3,10 +3,11 @@ import { Module } from '@nestjs/common'; import { AppController } from './test/app.controller'; import { AppService } from './test/app.service'; import { RemoteGroupController } from "./remoteGroup/remote.group.controller"; +import { RemoteCatalogueController } from './remoteCatalogue/remote.catalogue.controller'; @Module({ imports: [], - controllers: [AppController, RemoteGroupController], + controllers: [AppController, RemoteGroupController,RemoteCatalogueController], providers: [AppService], }) export class AppModule {} diff --git a/libs/clients/bff/openapi.json b/libs/clients/bff/openapi.json index c7561b1..2a1efba 100644 --- a/libs/clients/bff/openapi.json +++ b/libs/clients/bff/openapi.json @@ -1 +1 @@ -{"openapi":"3.0.0","paths":{"/api/test":{"get":{"operationId":"AppController_getData","parameters":[],"responses":{"200":{"description":""}}}},"/api/remoteGroup":{"get":{"operationId":"RemoteGroupController_getGroups","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}}},"tags":["remoteGroup"]},"post":{"operationId":"RemoteGroupController_addGroup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroupCreateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteGroup/{id}":{"get":{"operationId":"RemoteGroupController_getGroup","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}}},"info":{"title":"BFF API","description":"Backend For Frontend API","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"TableDto":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["id","number","customerCount"]},"AnnotatedGroup":{"type":"object","properties":{"id":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/TableDto"}},"offer":{"type":"string"}},"required":["id","tables","offer"]},"AnnotatedCreateTableDto":{"type":"object","properties":{"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["number","customerCount"]},"AnnotatedGroupCreateDto":{"type":"object","properties":{"offer":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedCreateTableDto"}}},"required":["offer","tables"]}}}} \ No newline at end of file +{"openapi":"3.0.0","paths":{"/api/test":{"get":{"operationId":"AppController_getData","parameters":[],"responses":{"200":{"description":""}}}},"/api/remoteGroup":{"get":{"operationId":"RemoteGroupController_getGroups","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}}},"tags":["remoteGroup"]},"post":{"operationId":"RemoteGroupController_addGroup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroupCreateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteGroup/{id}":{"get":{"operationId":"RemoteGroupController_getGroup","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteCatalogue/filteredCatalog":{"get":{"operationId":"RemoteCatalogueController_getFilteredCatalog","parameters":[{"name":"offerName","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategorizedCatalogDto"}}}}},"tags":["remoteCatalogue"]}},"/api/remoteCatalogue/items":{"get":{"operationId":"RemoteCatalogueController_getFullItemFromItemIdsArray","parameters":[{"name":"ids","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemDto"}}}}}},"tags":["remoteCatalogue"]}}},"info":{"title":"BFF API","description":"Backend For Frontend API","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"TableDto":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["id","number","customerCount"]},"AnnotatedGroup":{"type":"object","properties":{"id":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/TableDto"}},"offer":{"type":"string"}},"required":["id","tables","offer"]},"AnnotatedCreateTableDto":{"type":"object","properties":{"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["number","customerCount"]},"AnnotatedGroupCreateDto":{"type":"object","properties":{"offer":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedCreateTableDto"}}},"required":["offer","tables"]},"CategorizedCatalogDto":{"type":"object","properties":{"categories":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemDto"}}}},"required":["categories"]},"MenuItemDto":{"type":"object","properties":{"_id":{"type":"string"},"fullName":{"type":"string"},"shortName":{"type":"string"},"price":{"type":"number"},"category":{"type":"string","enum":["STARTER","MAIN","DESSERT","BEVERAGE"]},"image":{"type":"string"}},"required":["_id","fullName","shortName","price","category","image"]}}}} \ No newline at end of file diff --git a/libs/services/common/src/lib/apis/backendBffApiService.ts b/libs/services/common/src/lib/apis/backendBffApiService.ts index 0525336..0e503c0 100644 --- a/libs/services/common/src/lib/apis/backendBffApiService.ts +++ b/libs/services/common/src/lib/apis/backendBffApiService.ts @@ -11,4 +11,5 @@ export class BackendBffApiService { getRemoteGroupApi() { return this.remoteGroupApi; } + } diff --git a/libs/services/common/src/lib/offer/catalogueRemoteService.ts b/libs/services/common/src/lib/offer/catalogueRemoteService.ts index b937d6d..e69de29 100644 --- a/libs/services/common/src/lib/offer/catalogueRemoteService.ts +++ b/libs/services/common/src/lib/offer/catalogueRemoteService.ts @@ -1,52 +0,0 @@ -import { inject, injectable } from 'inversify'; -import { TYPES } from '../types'; -import { MenuApiService } from '../apis/menuApiService'; -import { OfferService } from './offer.service'; -import { CategorizedCatalog, CatalogueService } from './catalogue.service'; -import { MenuItem } from "@spos/clients-menu"; - -@injectable() -export class CatalogueServiceWorkflow implements CatalogueService { - - private catalogCache: { [offerName: string]: CategorizedCatalog } = {}; - - constructor( - @inject(TYPES.MenuApiService) private menuApiService: MenuApiService, - @inject(TYPES.OfferService) private offerService: OfferService - ) {} - - async getFilteredCatalog(offerName: string): Promise { - if (this.catalogCache[offerName]) { - return this.catalogCache[offerName]; - } - - const offer = await this.offerService.getOffers().then(response => - response.find(element => element.name?.toLowerCase() === offerName?.toLowerCase()) - ); - - if (!offer) return {}; - - const availableCatalog = (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( - item => offer.availableItems.includes(item._id) - ); - - const categorizedCatalog: CategorizedCatalog = {}; - - availableCatalog.forEach(element => { - if (!categorizedCatalog[element.category]) { - categorizedCatalog[element.category] = []; - } - categorizedCatalog[element.category].push(element); - }); - - this.catalogCache[offerName] = categorizedCatalog; - - return categorizedCatalog; - } - - async getFullItemFromItemIdsArray(idList: string[]): Promise { - return (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( - item => idList.includes(item._id) - ); - } -} diff --git a/libs/ui/common/src/lib/commandsR/orderingChoices.tsx b/libs/ui/common/src/lib/commandsR/orderingChoices.tsx index ff47e69..9ab801d 100644 --- a/libs/ui/common/src/lib/commandsR/orderingChoices.tsx +++ b/libs/ui/common/src/lib/commandsR/orderingChoices.tsx @@ -4,7 +4,7 @@ import './orderingChoices.css'; import { useCarts } from './stores/cart'; import { useQuery } from '@tanstack/react-query'; import { ContainerContext } from '../containerHook/containerContext'; -import { CatalogService, TYPES } from '@spos/services/common'; +import { CatalogueService, TYPES } from '@spos/services/common'; interface OrderingChoicesProps { tableNumber: number, @@ -31,7 +31,7 @@ export function OrderingChoices(props: Readonly) { } = useQuery({ queryKey: ['catalog'], queryFn: async () => { - const catalogService : CatalogService = container.get(TYPES.CatalogService); + const catalogService : CatalogueService = container.get(TYPES.CatalogueService); console.log('', catalogService); return catalogService.getFilteredCatalog(props.offerType); }, From fb357038dbe8a35689bd00160b1f2131106cdd36 Mon Sep 17 00:00:00 2001 From: Anna Date: Sat, 28 Sep 2024 12:16:20 +0200 Subject: [PATCH 6/7] catalogue --- .../remote.catalogue.controller.ts | 15 +- libs/clients/bff/openapi.json | 303 +++++++++++++++++- libs/clients/bff/src/.openapi-generator/FILES | 3 + libs/clients/bff/src/api.ts | 1 + .../bff/src/api/remote-catalogue-api.ts | 228 +++++++++++++ .../bff/src/models/categorized-catalog-dto.ts | 33 ++ libs/clients/bff/src/models/index.ts | 2 + libs/clients/bff/src/models/menu-item-dto.ts | 70 ++++ .../src/lib/apis/backendBffApiService.ts | 6 +- .../common/src/lib/offer/catalogue.service.ts | 38 --- 10 files changed, 653 insertions(+), 46 deletions(-) create mode 100644 libs/clients/bff/src/api/remote-catalogue-api.ts create mode 100644 libs/clients/bff/src/models/categorized-catalog-dto.ts create mode 100644 libs/clients/bff/src/models/menu-item-dto.ts diff --git a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts index 35db8df..00b8868 100644 --- a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts +++ b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts @@ -6,22 +6,22 @@ import { MenuItem, MenuItemCategoryEnum } from '@spos/clients-menu'; export class MenuItemDto implements MenuItem { @ApiProperty() - '_id': string; + _id : string; @ApiProperty() - 'fullName': string; + fullName : string; @ApiProperty() - 'shortName': string; + shortName : string; @ApiProperty() - 'price': number; + price : number; @ApiProperty({ enum: MenuItemCategoryEnum }) - 'category': MenuItemCategoryEnum; + category : MenuItemCategoryEnum; @ApiProperty() - 'image': string; + image : string; } export class CategorizedCatalogDto { @@ -34,10 +34,13 @@ export class CategorizedCatalogDto { export class RemoteCatalogueController { @Get('filteredCatalog') async getFilteredCatalog(@Query('offerName') offerName: string): Promise { + console.log('offerName:', offerName); const catalog = await container.get(TYPES.CatalogueService).getFilteredCatalog(offerName); + console.log('catalog:', catalog); return { categories: catalog }; } + @Get('items') async getFullItemFromItemIdsArray(@Query('ids') ids: string): Promise { const idList = ids.split(','); diff --git a/libs/clients/bff/openapi.json b/libs/clients/bff/openapi.json index 2a1efba..b493b8b 100644 --- a/libs/clients/bff/openapi.json +++ b/libs/clients/bff/openapi.json @@ -1 +1,302 @@ -{"openapi":"3.0.0","paths":{"/api/test":{"get":{"operationId":"AppController_getData","parameters":[],"responses":{"200":{"description":""}}}},"/api/remoteGroup":{"get":{"operationId":"RemoteGroupController_getGroups","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}}},"tags":["remoteGroup"]},"post":{"operationId":"RemoteGroupController_addGroup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroupCreateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteGroup/{id}":{"get":{"operationId":"RemoteGroupController_getGroup","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteCatalogue/filteredCatalog":{"get":{"operationId":"RemoteCatalogueController_getFilteredCatalog","parameters":[{"name":"offerName","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategorizedCatalogDto"}}}}},"tags":["remoteCatalogue"]}},"/api/remoteCatalogue/items":{"get":{"operationId":"RemoteCatalogueController_getFullItemFromItemIdsArray","parameters":[{"name":"ids","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemDto"}}}}}},"tags":["remoteCatalogue"]}}},"info":{"title":"BFF API","description":"Backend For Frontend API","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"TableDto":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["id","number","customerCount"]},"AnnotatedGroup":{"type":"object","properties":{"id":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/TableDto"}},"offer":{"type":"string"}},"required":["id","tables","offer"]},"AnnotatedCreateTableDto":{"type":"object","properties":{"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["number","customerCount"]},"AnnotatedGroupCreateDto":{"type":"object","properties":{"offer":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedCreateTableDto"}}},"required":["offer","tables"]},"CategorizedCatalogDto":{"type":"object","properties":{"categories":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemDto"}}}},"required":["categories"]},"MenuItemDto":{"type":"object","properties":{"_id":{"type":"string"},"fullName":{"type":"string"},"shortName":{"type":"string"},"price":{"type":"number"},"category":{"type":"string","enum":["STARTER","MAIN","DESSERT","BEVERAGE"]},"image":{"type":"string"}},"required":["_id","fullName","shortName","price","category","image"]}}}} \ No newline at end of file +{ + "openapi": "3.0.0", + "paths": { + "/api/test": { + "get": { + "operationId": "AppController_getData", + "parameters": [], + "responses": { + "200": { + "description": "" + } + } + } + }, + "/api/remoteGroup": { + "get": { + "operationId": "RemoteGroupController_getGroups", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotatedGroup" + } + } + } + } + } + }, + "tags": [ + "remoteGroup" + ] + }, + "post": { + "operationId": "RemoteGroupController_addGroup", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AnnotatedGroupCreateDto" + } + } + } + }, + "responses": { + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AnnotatedGroup" + } + } + } + } + }, + "tags": [ + "remoteGroup" + ] + } + }, + "/api/remoteGroup/{id}": { + "get": { + "operationId": "RemoteGroupController_getGroup", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AnnotatedGroup" + } + } + } + } + }, + "tags": [ + "remoteGroup" + ] + } + }, + "/api/remoteCatalogue/filteredCatalog": { + "get": { + "operationId": "RemoteCatalogueController_getFilteredCatalog", + "parameters": [ + { + "name": "offerName", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CategorizedCatalogDto" + } + } + } + } + }, + "tags": [ + "remoteCatalogue" + ] + } + }, + "/api/remoteCatalogue/items": { + "get": { + "operationId": "RemoteCatalogueController_getFullItemFromItemIdsArray", + "parameters": [ + { + "name": "ids", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MenuItemDto" + } + } + } + } + } + }, + "tags": [ + "remoteCatalogue" + ] + } + } + }, + "info": { + "title": "BFF API", + "description": "Backend For Frontend API", + "version": "1.0", + "contact": {} + }, + "tags": [], + "servers": [], + "components": { + "schemas": { + "TableDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "number": { + "type": "number" + }, + "customerCount": { + "type": "number" + } + }, + "required": [ + "id", + "number", + "customerCount" + ] + }, + "AnnotatedGroup": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "tables": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TableDto" + } + }, + "offer": { + "type": "string" + } + }, + "required": [ + "id", + "tables", + "offer" + ] + }, + "AnnotatedCreateTableDto": { + "type": "object", + "properties": { + "number": { + "type": "number" + }, + "customerCount": { + "type": "number" + } + }, + "required": [ + "number", + "customerCount" + ] + }, + "AnnotatedGroupCreateDto": { + "type": "object", + "properties": { + "offer": { + "type": "string" + }, + "tables": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotatedCreateTableDto" + } + } + }, + "required": [ + "offer", + "tables" + ] + }, + "CategorizedCatalogDto": { + "type": "object", + "properties": { + "categories": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MenuItemDto" + } + } + } + }, + "required": [ + "categories" + ] + }, + "MenuItemDto": { + "type": "object", + "properties": { + "_id": { + "type": "string" + }, + "fullName": { + "type": "string" + }, + "shortName": { + "type": "string" + }, + "price": { + "type": "number" + }, + "category": { + "type": "string", + "enum": [ + "STARTER", + "MAIN", + "DESSERT", + "BEVERAGE" + ] + }, + "image": { + "type": "string" + } + }, + "required": [ + "_id", + "fullName", + "shortName", + "price", + "category", + "image" + ] + } + } + } +} \ No newline at end of file diff --git a/libs/clients/bff/src/.openapi-generator/FILES b/libs/clients/bff/src/.openapi-generator/FILES index 211b248..b5fffac 100644 --- a/libs/clients/bff/src/.openapi-generator/FILES +++ b/libs/clients/bff/src/.openapi-generator/FILES @@ -2,6 +2,7 @@ .openapi-generator-ignore api.ts api/default-api.ts +api/remote-catalogue-api.ts api/remote-group-api.ts base.ts common.ts @@ -10,5 +11,7 @@ index.ts models/annotated-create-table-dto.ts models/annotated-group-create-dto.ts models/annotated-group.ts +models/categorized-catalog-dto.ts models/index.ts +models/menu-item-dto.ts models/table-dto.ts diff --git a/libs/clients/bff/src/api.ts b/libs/clients/bff/src/api.ts index 33252f9..2db3fc1 100644 --- a/libs/clients/bff/src/api.ts +++ b/libs/clients/bff/src/api.ts @@ -15,5 +15,6 @@ export * from './api/default-api'; +export * from './api/remote-catalogue-api'; export * from './api/remote-group-api'; diff --git a/libs/clients/bff/src/api/remote-catalogue-api.ts b/libs/clients/bff/src/api/remote-catalogue-api.ts new file mode 100644 index 0000000..164b5e0 --- /dev/null +++ b/libs/clients/bff/src/api/remote-catalogue-api.ts @@ -0,0 +1,228 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * BFF API + * Backend For Frontend API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CategorizedCatalogDto } from '../models'; +// @ts-ignore +import type { MenuItemDto } from '../models'; +/** + * RemoteCatalogueApi - axios parameter creator + * @export + */ +export const RemoteCatalogueApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {string} offerName + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + remoteCatalogueControllerGetFilteredCatalog: async (offerName: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'offerName' is not null or undefined + assertParamExists('remoteCatalogueControllerGetFilteredCatalog', 'offerName', offerName) + const localVarPath = `/api/remoteCatalogue/filteredCatalog`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (offerName !== undefined) { + localVarQueryParameter['offerName'] = offerName; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {string} ids + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + remoteCatalogueControllerGetFullItemFromItemIdsArray: async (ids: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'ids' is not null or undefined + assertParamExists('remoteCatalogueControllerGetFullItemFromItemIdsArray', 'ids', ids) + const localVarPath = `/api/remoteCatalogue/items`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + if (ids !== undefined) { + localVarQueryParameter['ids'] = ids; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * RemoteCatalogueApi - functional programming interface + * @export + */ +export const RemoteCatalogueApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = RemoteCatalogueApiAxiosParamCreator(configuration) + return { + /** + * + * @param {string} offerName + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async remoteCatalogueControllerGetFilteredCatalog(offerName: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.remoteCatalogueControllerGetFilteredCatalog(offerName, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['RemoteCatalogueApi.remoteCatalogueControllerGetFilteredCatalog']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {string} ids + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async remoteCatalogueControllerGetFullItemFromItemIdsArray(ids: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + const localVarAxiosArgs = await localVarAxiosParamCreator.remoteCatalogueControllerGetFullItemFromItemIdsArray(ids, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['RemoteCatalogueApi.remoteCatalogueControllerGetFullItemFromItemIdsArray']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * RemoteCatalogueApi - factory interface + * @export + */ +export const RemoteCatalogueApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = RemoteCatalogueApiFp(configuration) + return { + /** + * + * @param {RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalogRequest} requestParameters Request parameters. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + remoteCatalogueControllerGetFilteredCatalog(requestParameters: RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalogRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.remoteCatalogueControllerGetFilteredCatalog(requestParameters.offerName, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArrayRequest} requestParameters Request parameters. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + remoteCatalogueControllerGetFullItemFromItemIdsArray(requestParameters: RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArrayRequest, options?: RawAxiosRequestConfig): AxiosPromise> { + return localVarFp.remoteCatalogueControllerGetFullItemFromItemIdsArray(requestParameters.ids, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * Request parameters for remoteCatalogueControllerGetFilteredCatalog operation in RemoteCatalogueApi. + * @export + * @interface RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalogRequest + */ +export interface RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalogRequest { + /** + * + * @type {string} + * @memberof RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalog + */ + readonly offerName: string +} + +/** + * Request parameters for remoteCatalogueControllerGetFullItemFromItemIdsArray operation in RemoteCatalogueApi. + * @export + * @interface RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArrayRequest + */ +export interface RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArrayRequest { + /** + * + * @type {string} + * @memberof RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArray + */ + readonly ids: string +} + +/** + * RemoteCatalogueApi - object-oriented interface + * @export + * @class RemoteCatalogueApi + * @extends {BaseAPI} + */ +export class RemoteCatalogueApi extends BaseAPI { + /** + * + * @param {RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalogRequest} requestParameters Request parameters. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RemoteCatalogueApi + */ + public remoteCatalogueControllerGetFilteredCatalog(requestParameters: RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalogRequest, options?: RawAxiosRequestConfig) { + return RemoteCatalogueApiFp(this.configuration).remoteCatalogueControllerGetFilteredCatalog(requestParameters.offerName, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArrayRequest} requestParameters Request parameters. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof RemoteCatalogueApi + */ + public remoteCatalogueControllerGetFullItemFromItemIdsArray(requestParameters: RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArrayRequest, options?: RawAxiosRequestConfig) { + return RemoteCatalogueApiFp(this.configuration).remoteCatalogueControllerGetFullItemFromItemIdsArray(requestParameters.ids, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/libs/clients/bff/src/models/categorized-catalog-dto.ts b/libs/clients/bff/src/models/categorized-catalog-dto.ts new file mode 100644 index 0000000..0fcfdc6 --- /dev/null +++ b/libs/clients/bff/src/models/categorized-catalog-dto.ts @@ -0,0 +1,33 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * BFF API + * Backend For Frontend API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { MenuItemDto } from './menu-item-dto'; + +/** + * + * @export + * @interface CategorizedCatalogDto + */ +export interface CategorizedCatalogDto { + /** + * + * @type {{ [key: string]: Array; }} + * @memberof CategorizedCatalogDto + */ + 'categories': { [key: string]: Array; }; +} + diff --git a/libs/clients/bff/src/models/index.ts b/libs/clients/bff/src/models/index.ts index 8019dd7..faebdd1 100644 --- a/libs/clients/bff/src/models/index.ts +++ b/libs/clients/bff/src/models/index.ts @@ -1,4 +1,6 @@ export * from './annotated-create-table-dto'; export * from './annotated-group'; export * from './annotated-group-create-dto'; +export * from './categorized-catalog-dto'; +export * from './menu-item-dto'; export * from './table-dto'; diff --git a/libs/clients/bff/src/models/menu-item-dto.ts b/libs/clients/bff/src/models/menu-item-dto.ts new file mode 100644 index 0000000..aa91912 --- /dev/null +++ b/libs/clients/bff/src/models/menu-item-dto.ts @@ -0,0 +1,70 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * BFF API + * Backend For Frontend API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface MenuItemDto + */ +export interface MenuItemDto { + /** + * + * @type {string} + * @memberof MenuItemDto + */ + '_id': string; + /** + * + * @type {string} + * @memberof MenuItemDto + */ + 'fullName': string; + /** + * + * @type {string} + * @memberof MenuItemDto + */ + 'shortName': string; + /** + * + * @type {number} + * @memberof MenuItemDto + */ + 'price': number; + /** + * + * @type {string} + * @memberof MenuItemDto + */ + 'category': MenuItemDtoCategoryEnum; + /** + * + * @type {string} + * @memberof MenuItemDto + */ + 'image': string; +} + +export const MenuItemDtoCategoryEnum = { + Starter: 'STARTER', + Main: 'MAIN', + Dessert: 'DESSERT', + Beverage: 'BEVERAGE' +} as const; + +export type MenuItemDtoCategoryEnum = typeof MenuItemDtoCategoryEnum[keyof typeof MenuItemDtoCategoryEnum]; + + diff --git a/libs/services/common/src/lib/apis/backendBffApiService.ts b/libs/services/common/src/lib/apis/backendBffApiService.ts index 0e503c0..531bbdc 100644 --- a/libs/services/common/src/lib/apis/backendBffApiService.ts +++ b/libs/services/common/src/lib/apis/backendBffApiService.ts @@ -1,5 +1,5 @@ import { injectable } from "inversify"; -import { Configuration, RemoteGroupApi } from "@spos/clients-bff"; +import { Configuration, RemoteGroupApi , RemoteCatalogueApi} from "@spos/clients-bff"; @injectable() export class BackendBffApiService { @@ -7,9 +7,13 @@ export class BackendBffApiService { basePath: "http://localhost:3000", }); private remoteGroupApi = new RemoteGroupApi(this.configuration); + private remoteCatalogueApi = new RemoteCatalogueApi(this.configuration); getRemoteGroupApi() { return this.remoteGroupApi; } + getRemoteCatalogueApi() { + return this.remoteGroupApi; + } } diff --git a/libs/services/common/src/lib/offer/catalogue.service.ts b/libs/services/common/src/lib/offer/catalogue.service.ts index d5934c9..3b12bac 100644 --- a/libs/services/common/src/lib/offer/catalogue.service.ts +++ b/libs/services/common/src/lib/offer/catalogue.service.ts @@ -13,41 +13,3 @@ export interface CatalogueService { getFilteredCatalog(offerName: string): Promise; getFullItemFromItemIdsArray(idList: string[]): Promise; } - -@injectable() -export class CatalogService implements CatalogueService{ - constructor( - @inject(TYPES.MenuApiService) private menuApiService: MenuApiService, - @inject(TYPES.OfferService) private offerService: OfferService - ) {} - - async getFilteredCatalog(offerName: string) { - const offer = await this.offerService.getOffers().then(response => - response.find(element => element.name?.toLowerCase() === offerName?.toLowerCase()) - ); - - if (!offer) return {}; - - const availableCatalog = (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( - item => offer.availableItems.includes(item._id) - ); - - const categorizedCatalog: CategorizedCatalog = {}; - - availableCatalog.forEach(element => { - if (!categorizedCatalog[element.category]) { - categorizedCatalog[element.category] = []; - } - categorizedCatalog[element.category].push(element); - }); - - return categorizedCatalog; - } - - - async getFullItemFromItemIdsArray(idList: string[]) { - return (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( - item => idList.includes(item._id) - ); - } -} From 27b31b9277aa63030648f898585b38cfc02ea959 Mon Sep 17 00:00:00 2001 From: Anna Date: Sat, 28 Sep 2024 13:08:45 +0200 Subject: [PATCH 7/7] Catalogue Remote --- .../remote.catalogue.controller.ts | 5 ++-- libs/clients/bff/openapi.json | 2 +- libs/clients/bff/src/.openapi-generator/FILES | 1 + .../bff/src/api/remote-catalogue-api.ts | 14 +++++----- .../src/lib/apis/backendBffApiService.ts | 2 +- libs/services/common/src/lib/bff.container.ts | 6 +++-- .../common/src/lib/offer/catalogue.service.ts | 1 + .../src/lib/offer/catalogueRemoteService.ts | 26 +++++++++++++++++++ .../src/lib/offer/catalogueServiceWorkflow.ts | 6 +++-- 9 files changed, 47 insertions(+), 16 deletions(-) diff --git a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts index 00b8868..64b04a0 100644 --- a/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts +++ b/apps/backend-bff/src/app/remoteCatalogue/remote.catalogue.controller.ts @@ -42,8 +42,7 @@ export class RemoteCatalogueController { @Get('items') - async getFullItemFromItemIdsArray(@Query('ids') ids: string): Promise { - const idList = ids.split(','); - return container.get(TYPES.CatalogueService).getFullItemFromItemIdsArray(idList); + async getFullItemFromItemIdsArray(@Query('ids') ids: string[]): Promise { + return container.get(TYPES.CatalogueService).getFullItemFromItemIdsArray(ids); } } \ No newline at end of file diff --git a/libs/clients/bff/openapi.json b/libs/clients/bff/openapi.json index a14c827..1f78c54 100644 --- a/libs/clients/bff/openapi.json +++ b/libs/clients/bff/openapi.json @@ -1 +1 @@ -{"openapi":"3.0.0","paths":{"/api/test":{"get":{"operationId":"AppController_getData","parameters":[],"responses":{"200":{"description":""}}}},"/api/remoteGroup":{"get":{"operationId":"RemoteGroupController_getGroups","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}}},"tags":["remoteGroup"]},"post":{"operationId":"RemoteGroupController_addGroup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroupCreateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteGroup/{id}":{"get":{"operationId":"RemoteGroupController_getGroup","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteTable":{"get":{"operationId":"RemoteTableController_getFreeTables","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedTableWithOrderDto"}}}}}},"tags":["remoteTable"]},"post":{"operationId":"RemoteTableController_closeAllTables","parameters":[],"responses":{"201":{"description":""}},"tags":["remoteTable"]}}},"info":{"title":"BFF API","description":"Backend For Frontend API","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"TableDto":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["id","number","customerCount"]},"AnnotatedGroup":{"type":"object","properties":{"id":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/TableDto"}},"offer":{"type":"string"}},"required":["id","tables","offer"]},"AnnotatedCreateTableDto":{"type":"object","properties":{"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["number","customerCount"]},"AnnotatedGroupCreateDto":{"type":"object","properties":{"offer":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedCreateTableDto"}}},"required":["offer","tables"]},"AnnotatedTableWithOrderDto":{"type":"object","properties":{"_id":{"type":"string"},"number":{"type":"number"},"tableOrderId":{"type":"string"},"taken":{"type":"boolean"}},"required":["_id","number","tableOrderId","taken"]}}}} \ No newline at end of file +{"openapi":"3.0.0","paths":{"/api/test":{"get":{"operationId":"AppController_getData","parameters":[],"responses":{"200":{"description":""}}}},"/api/remoteGroup":{"get":{"operationId":"RemoteGroupController_getGroups","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}}},"tags":["remoteGroup"]},"post":{"operationId":"RemoteGroupController_addGroup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroupCreateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteGroup/{id}":{"get":{"operationId":"RemoteGroupController_getGroup","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnotatedGroup"}}}}},"tags":["remoteGroup"]}},"/api/remoteTable":{"get":{"operationId":"RemoteTableController_getFreeTables","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedTableWithOrderDto"}}}}}},"tags":["remoteTable"]},"post":{"operationId":"RemoteTableController_closeAllTables","parameters":[],"responses":{"201":{"description":""}},"tags":["remoteTable"]}},"/api/remoteCatalogue/filteredCatalog":{"get":{"operationId":"RemoteCatalogueController_getFilteredCatalog","parameters":[{"name":"offerName","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategorizedCatalogDto"}}}}},"tags":["remoteCatalogue"]}},"/api/remoteCatalogue/items":{"get":{"operationId":"RemoteCatalogueController_getFullItemFromItemIdsArray","parameters":[{"name":"ids","required":true,"in":"query","schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemDto"}}}}}},"tags":["remoteCatalogue"]}}},"info":{"title":"BFF API","description":"Backend For Frontend API","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"TableDto":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["id","number","customerCount"]},"AnnotatedGroup":{"type":"object","properties":{"id":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/TableDto"}},"offer":{"type":"string"}},"required":["id","tables","offer"]},"AnnotatedCreateTableDto":{"type":"object","properties":{"number":{"type":"number"},"customerCount":{"type":"number"}},"required":["number","customerCount"]},"AnnotatedGroupCreateDto":{"type":"object","properties":{"offer":{"type":"string"},"tables":{"type":"array","items":{"$ref":"#/components/schemas/AnnotatedCreateTableDto"}}},"required":["offer","tables"]},"AnnotatedTableWithOrderDto":{"type":"object","properties":{"_id":{"type":"string"},"number":{"type":"number"},"tableOrderId":{"type":"string"},"taken":{"type":"boolean"}},"required":["_id","number","tableOrderId","taken"]},"CategorizedCatalogDto":{"type":"object","properties":{"categories":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/MenuItemDto"}}}},"required":["categories"]},"MenuItemDto":{"type":"object","properties":{"_id":{"type":"string"},"fullName":{"type":"string"},"shortName":{"type":"string"},"price":{"type":"number"},"category":{"type":"string","enum":["STARTER","MAIN","DESSERT","BEVERAGE"]},"image":{"type":"string"}},"required":["_id","fullName","shortName","price","category","image"]}}}} \ No newline at end of file diff --git a/libs/clients/bff/src/.openapi-generator/FILES b/libs/clients/bff/src/.openapi-generator/FILES index c3e21f7..d950796 100644 --- a/libs/clients/bff/src/.openapi-generator/FILES +++ b/libs/clients/bff/src/.openapi-generator/FILES @@ -13,6 +13,7 @@ models/annotated-create-table-dto.ts models/annotated-group-create-dto.ts models/annotated-group.ts models/annotated-table-with-order-dto.ts +models/categorized-catalog-dto.ts models/index.ts models/menu-item-dto.ts models/table-dto.ts diff --git a/libs/clients/bff/src/api/remote-catalogue-api.ts b/libs/clients/bff/src/api/remote-catalogue-api.ts index 164b5e0..292218c 100644 --- a/libs/clients/bff/src/api/remote-catalogue-api.ts +++ b/libs/clients/bff/src/api/remote-catalogue-api.ts @@ -69,11 +69,11 @@ export const RemoteCatalogueApiAxiosParamCreator = function (configuration?: Con }, /** * - * @param {string} ids + * @param {Array} ids * @param {*} [options] Override http request option. * @throws {RequiredError} */ - remoteCatalogueControllerGetFullItemFromItemIdsArray: async (ids: string, options: RawAxiosRequestConfig = {}): Promise => { + remoteCatalogueControllerGetFullItemFromItemIdsArray: async (ids: Array, options: RawAxiosRequestConfig = {}): Promise => { // verify required parameter 'ids' is not null or undefined assertParamExists('remoteCatalogueControllerGetFullItemFromItemIdsArray', 'ids', ids) const localVarPath = `/api/remoteCatalogue/items`; @@ -88,7 +88,7 @@ export const RemoteCatalogueApiAxiosParamCreator = function (configuration?: Con const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; - if (ids !== undefined) { + if (ids) { localVarQueryParameter['ids'] = ids; } @@ -127,11 +127,11 @@ export const RemoteCatalogueApiFp = function(configuration?: Configuration) { }, /** * - * @param {string} ids + * @param {Array} ids * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async remoteCatalogueControllerGetFullItemFromItemIdsArray(ids: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { + async remoteCatalogueControllerGetFullItemFromItemIdsArray(ids: Array, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise>> { const localVarAxiosArgs = await localVarAxiosParamCreator.remoteCatalogueControllerGetFullItemFromItemIdsArray(ids, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['RemoteCatalogueApi.remoteCatalogueControllerGetFullItemFromItemIdsArray']?.[localVarOperationServerIndex]?.url; @@ -190,10 +190,10 @@ export interface RemoteCatalogueApiRemoteCatalogueControllerGetFilteredCatalogRe export interface RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArrayRequest { /** * - * @type {string} + * @type {Array} * @memberof RemoteCatalogueApiRemoteCatalogueControllerGetFullItemFromItemIdsArray */ - readonly ids: string + readonly ids: Array } /** diff --git a/libs/services/common/src/lib/apis/backendBffApiService.ts b/libs/services/common/src/lib/apis/backendBffApiService.ts index 3104d6e..d5b2ce1 100644 --- a/libs/services/common/src/lib/apis/backendBffApiService.ts +++ b/libs/services/common/src/lib/apis/backendBffApiService.ts @@ -18,7 +18,7 @@ export class BackendBffApiService { return this.remoteTableApi; } getRemoteCatalogueApi() { - return this.remoteGroupApi; + return this.remoteCatalogueApi; } } diff --git a/libs/services/common/src/lib/bff.container.ts b/libs/services/common/src/lib/bff.container.ts index 5b53901..647f337 100644 --- a/libs/services/common/src/lib/bff.container.ts +++ b/libs/services/common/src/lib/bff.container.ts @@ -8,7 +8,9 @@ import { GroupService } from "./group/groupService"; import { BackendBffApiService } from "./apis/backendBffApiService"; import { GroupRemoteService } from "./group/groupRemoteService"; import { TableRemoteService } from "./table/tableRemoteService"; -import { CatalogService } from "./offer/catalogue.service"; +import { CatalogueService } from "./offer/catalogue.service"; +import { CatalogueServiceWorkflow } from "./offer/catalogueServiceWorkflow"; +import { CatalogueRemoteService } from "./offer/catalogueRemoteService"; const bffContainer = new Container(); bffContainer.bind(TYPES.BackendBffApiService).to(BackendBffApiService).inSingletonScope(); @@ -17,5 +19,5 @@ bffContainer.bind(TYPES.TableService).to(TableRemoteService).inSin bffContainer.bind(TYPES.DiningApiService).to(DiningApiService).inSingletonScope(); bffContainer.bind(TYPES.MenuApiService).to(MenuApiService).inSingletonScope(); bffContainer.bind(TYPES.OfferService).to(OfferService).inSingletonScope(); -bffContainer.bind(TYPES.CatalogService).to(CatalogService).inSingletonScope(); +bffContainer.bind(TYPES.CatalogueService).to(CatalogueRemoteService).inSingletonScope(); export { bffContainer }; diff --git a/libs/services/common/src/lib/offer/catalogue.service.ts b/libs/services/common/src/lib/offer/catalogue.service.ts index 3b12bac..b72fc59 100644 --- a/libs/services/common/src/lib/offer/catalogue.service.ts +++ b/libs/services/common/src/lib/offer/catalogue.service.ts @@ -9,6 +9,7 @@ export type CategorizedCatalog = { [category: string]: MenuItem[] }; + export interface CatalogueService { getFilteredCatalog(offerName: string): Promise; getFullItemFromItemIdsArray(idList: string[]): Promise; diff --git a/libs/services/common/src/lib/offer/catalogueRemoteService.ts b/libs/services/common/src/lib/offer/catalogueRemoteService.ts index e69de29..391249a 100644 --- a/libs/services/common/src/lib/offer/catalogueRemoteService.ts +++ b/libs/services/common/src/lib/offer/catalogueRemoteService.ts @@ -0,0 +1,26 @@ +import { inject, injectable } from 'inversify'; +import { BackendBffApiService } from '../apis/backendBffApiService'; +import { TYPES } from "../types"; +import { logger } from "../logger"; +import { CatalogueService, CategorizedCatalog } from './catalogue.service'; +import { MenuItem } from '@spos/clients-menu'; + + +@injectable() +export class CatalogueRemoteService implements CatalogueService { + constructor( @inject(TYPES.BackendBffApiService) private backendBffApiService: BackendBffApiService) { + + } + @logger + async getFilteredCatalog(offerName: string): Promise { + return (await this.backendBffApiService.getRemoteCatalogueApi().remoteCatalogueControllerGetFilteredCatalog({offerName})).data.categories; + } + @logger + async getFullItemFromItemIdsArray(idList: string[]): Promise { + return (await this.backendBffApiService.getRemoteCatalogueApi().remoteCatalogueControllerGetFullItemFromItemIdsArray({ids : idList})).data; + + } + + + +} \ No newline at end of file diff --git a/libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts b/libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts index 04118db..9a06321 100644 --- a/libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts +++ b/libs/services/common/src/lib/offer/catalogueServiceWorkflow.ts @@ -4,6 +4,7 @@ import { MenuApiService } from '../apis/menuApiService'; import { OfferService } from './offer.service'; import { CategorizedCatalog, CatalogueService } from './catalogue.service'; import { MenuItem } from "@spos/clients-menu"; +import { logger } from '../logger'; @injectable() @@ -13,7 +14,7 @@ export class CatalogueServiceWorkflow implements CatalogueService { private offerService = new OfferService(); - + @logger async getFilteredCatalog(offerName: string): Promise { const offer = await this.offerService.getOffers().then(response => response.find(element => element.name?.toLowerCase() === offerName?.toLowerCase()) @@ -36,7 +37,8 @@ export class CatalogueServiceWorkflow implements CatalogueService { return categorizedCatalog; } - + + @logger async getFullItemFromItemIdsArray(idList: string[]): Promise { return (await this.menuApiService.getMenuApi().menusControllerGetFullMenu()).data.filter( item => idList.includes(item._id)