From cfba15325d1d0c4e4346d7050ac13f969703c59a Mon Sep 17 00:00:00 2001 From: manelcecs Date: Thu, 23 Nov 2023 10:11:00 +0100 Subject: [PATCH] Add totalAmountUDS resolver --- .../flows/flow-search-service.ts | 34 +++++++++++++++++-- src/domain-services/flows/flow-service.ts | 4 +-- src/domain-services/flows/graphql/args.ts | 15 ++++++++ src/domain-services/flows/graphql/resolver.ts | 17 ++++++++-- src/domain-services/flows/graphql/types.ts | 9 +++++ .../flows/strategy/flow-search-strategy.ts | 8 ++--- .../impl/flow-object-conditions-strategy.ts | 8 ++--- .../impl/only-flow-conditions-strategy.ts | 8 ++--- 8 files changed, 85 insertions(+), 18 deletions(-) diff --git a/src/domain-services/flows/flow-search-service.ts b/src/domain-services/flows/flow-search-service.ts index 238a8e8e..07088c9e 100644 --- a/src/domain-services/flows/flow-search-service.ts +++ b/src/domain-services/flows/flow-search-service.ts @@ -21,12 +21,14 @@ import { UsageYearService } from '../usage-years/usage-year-service'; import { type FlowObjectFilters, type SearchFlowsArgs, + type SearchFlowsArgsNonPaginated, type SearchFlowsFilters, } from './graphql/args'; import { type FlowPaged, type FlowParkedParentSource, type FlowSearchResult, + type FlowSearchTotalAmountResult, } from './graphql/types'; import { type FlowEntity } from './model'; import { type FlowSearchStrategy } from './strategy/flow-search-strategy'; @@ -79,10 +81,10 @@ export class FlowSearchService { // Obtain flows and its count based on the strategy selected const { flows, count } = await strategy.search( conditions, + models, orderBy, limitComputed, - cursorCondition, - models + cursorCondition ); // Remove the extra item used to check hasNextPage @@ -448,4 +450,32 @@ export class FlowSearchService { cursor: flow.id.valueOf(), }; } + + async searchTotalAmount( + models: Database, + args: SearchFlowsArgsNonPaginated + ): Promise { + const { flowFilters, flowObjectFilters } = args; + + const { strategy, conditions } = this.determineStrategy( + flowFilters, + flowObjectFilters + ); + + const { flows, count } = await strategy.search(conditions, models); + + const flowsAmountUSD: Array = flows.map( + (flow) => flow.amountUSD + ); + + const totalAmount = flowsAmountUSD.reduce((a, b) => +a + +b, 0); + + return { + totalAmountUSD: totalAmount.toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }), + flowsCount: count, + }; + } } diff --git a/src/domain-services/flows/flow-service.ts b/src/domain-services/flows/flow-service.ts index 4920eecd..353a8104 100644 --- a/src/domain-services/flows/flow-service.ts +++ b/src/domain-services/flows/flow-service.ts @@ -8,8 +8,8 @@ export class FlowService { async getFlows( models: Database, conditions: any, - orderBy: any, - limit: number + orderBy?: any, + limit?: number ) { return await models.flow.find({ orderBy, diff --git a/src/domain-services/flows/graphql/args.ts b/src/domain-services/flows/graphql/args.ts index 7996e7b0..e5ee56a9 100644 --- a/src/domain-services/flows/graphql/args.ts +++ b/src/domain-services/flows/graphql/args.ts @@ -72,3 +72,18 @@ export class SearchFlowsArgs extends PaginationArgs { @Field({ nullable: true }) includeChildrenOfParkedFlows: boolean; } + +@ArgsType() +export class SearchFlowsArgsNonPaginated { + @Field(() => SearchFlowsFilters, { nullable: true }) + flowFilters: SearchFlowsFilters; + + @Field(() => [FlowObjectFilters], { nullable: true }) + flowObjectFilters: FlowObjectFilters[]; + + @Field(() => [FlowCategory], { nullable: true }) + categoryFilters: FlowCategory[]; + + @Field({ nullable: true }) + includeChildrenOfParkedFlows: boolean; +} diff --git a/src/domain-services/flows/graphql/resolver.ts b/src/domain-services/flows/graphql/resolver.ts index 2852b580..ad49913d 100644 --- a/src/domain-services/flows/graphql/resolver.ts +++ b/src/domain-services/flows/graphql/resolver.ts @@ -2,8 +2,12 @@ import { Args, Ctx, Query, Resolver } from 'type-graphql'; import { Service } from 'typedi'; import Context from '../../Context'; import { FlowSearchService } from '../flow-search-service'; -import { SearchFlowsArgs } from './args'; -import { FlowPaged, FlowSearchResult } from './types'; +import { SearchFlowsArgs, SearchFlowsArgsNonPaginated } from './args'; +import { + FlowPaged, + FlowSearchResult, + FlowSearchTotalAmountResult, +} from './types'; @Service() @Resolver(FlowPaged) @@ -18,4 +22,13 @@ export default class FlowResolver { ): Promise { return await this.flowSearchService.search(context.models, args); } + + @Query(() => FlowSearchTotalAmountResult) + async searchFlowsTotalAmountUSD( + @Ctx() context: Context, + @Args(() => SearchFlowsArgsNonPaginated, { validate: false }) + args: SearchFlowsArgsNonPaginated + ): Promise { + return await this.flowSearchService.searchTotalAmount(context.models, args); + } } diff --git a/src/domain-services/flows/graphql/types.ts b/src/domain-services/flows/graphql/types.ts index cfa313bb..ec865f31 100644 --- a/src/domain-services/flows/graphql/types.ts +++ b/src/domain-services/flows/graphql/types.ts @@ -110,6 +110,15 @@ export class FlowSearchResult extends PageInfo { flows: FlowPaged[]; } +@ObjectType() +export class FlowSearchTotalAmountResult { + @Field(() => String, { nullable: false }) + totalAmountUSD: string; + + @Field(() => Number, { nullable: false }) + flowsCount: number; +} + export type FlowSortField = | 'id' | 'versionID' diff --git a/src/domain-services/flows/strategy/flow-search-strategy.ts b/src/domain-services/flows/strategy/flow-search-strategy.ts index ff11e0b5..2d2d4015 100644 --- a/src/domain-services/flows/strategy/flow-search-strategy.ts +++ b/src/domain-services/flows/strategy/flow-search-strategy.ts @@ -9,9 +9,9 @@ export interface FlowSearchStrategyResponse { export interface FlowSearchStrategy { search( flowConditions: Map, - orderBy: any, - limit: number, - cursorCondition: any, - models: Database + models: Database, + orderBy?: any, + limit?: number, + cursorCondition?: any ): Promise; } diff --git a/src/domain-services/flows/strategy/impl/flow-object-conditions-strategy.ts b/src/domain-services/flows/strategy/impl/flow-object-conditions-strategy.ts index c0dbed8d..47bacfcc 100644 --- a/src/domain-services/flows/strategy/impl/flow-object-conditions-strategy.ts +++ b/src/domain-services/flows/strategy/impl/flow-object-conditions-strategy.ts @@ -18,10 +18,10 @@ export class FlowObjectFiltersStrategy implements FlowSearchStrategy { async search( flowConditions: Map, - orderBy: any, - limit: number, - cursorCondition: any, - models: Database + models: Database, + orderBy?: any, + limit?: number, + cursorCondition?: any ): Promise { // Obtain flowObjects conditions const flowObjectsConditions: Map< diff --git a/src/domain-services/flows/strategy/impl/only-flow-conditions-strategy.ts b/src/domain-services/flows/strategy/impl/only-flow-conditions-strategy.ts index d6557e9e..01b7a21c 100644 --- a/src/domain-services/flows/strategy/impl/only-flow-conditions-strategy.ts +++ b/src/domain-services/flows/strategy/impl/only-flow-conditions-strategy.ts @@ -12,10 +12,10 @@ export class OnlyFlowFiltersStrategy implements FlowSearchStrategy { async search( flowConditions: any, - orderBy: any, - limit: number, - cursorCondition: any, - models: Database + models: Database, + orderBy?: any, + limit?: number, + cursorCondition?: any ): Promise { // Build conditions object const conditions: any = { ...cursorCondition, ...flowConditions };