From 0fd58f3bf1dac83c939ff64bc74f4e5093698352 Mon Sep 17 00:00:00 2001 From: Krishnan Subramanian <84348052+krishnan-aot@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:55:17 -0700 Subject: [PATCH] ORV2-2073 Adding allApplications query parameter (#1324) --- vehicles/src/app.module.ts | 2 +- .../getApplicationsInCart.query-param.dto.ts | 22 ++++++++++ .../shopping-cart/shopping-cart.controller.ts | 4 ++ .../shopping-cart/shopping-cart.service.ts | 43 +++++++++++++------ 4 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 vehicles/src/modules/shopping-cart/dto/request/queryParam/getApplicationsInCart.query-param.dto.ts diff --git a/vehicles/src/app.module.ts b/vehicles/src/app.module.ts index f6a0f4f51..afdd2b069 100644 --- a/vehicles/src/app.module.ts +++ b/vehicles/src/app.module.ts @@ -94,7 +94,7 @@ const envPath = path.resolve(process.cwd() + '/../'); AuthModule, PaymentModule, ShoppingCartModule, - PermitReceiptDocumentModule, + PermitReceiptDocumentModule, ApplicationModule, //! Application Module should be imported before PermitModule to avoid URI conflict PermitModule, FeatureFlagsModule, diff --git a/vehicles/src/modules/shopping-cart/dto/request/queryParam/getApplicationsInCart.query-param.dto.ts b/vehicles/src/modules/shopping-cart/dto/request/queryParam/getApplicationsInCart.query-param.dto.ts new file mode 100644 index 000000000..e706b4661 --- /dev/null +++ b/vehicles/src/modules/shopping-cart/dto/request/queryParam/getApplicationsInCart.query-param.dto.ts @@ -0,0 +1,22 @@ +import { ApiPropertyOptional } from '@nestjs/swagger'; +import { Transform, Type } from 'class-transformer'; +import { IsBoolean, IsOptional } from 'class-validator'; + +export class GetApplicationInCartQueryParams { + @ApiPropertyOptional({ + description: + `If true, all applications in the company are retrieved; ` + + `if false, only the current user's own applications are retrieved.` + + `This field is only accepted for company administrators or staff;` + + `Ignored otherwise.`, + example: true, + }) + @Type(() => Boolean) + @Transform(({ obj, key }: { obj: Record; key: string }) => { + if (obj[key] === 'true') return true; + return obj[key] === 'false' ? false : obj[key]; + }) + @IsOptional() + @IsBoolean() + allApplications?: boolean; +} diff --git a/vehicles/src/modules/shopping-cart/shopping-cart.controller.ts b/vehicles/src/modules/shopping-cart/shopping-cart.controller.ts index e27353013..2f3eaa2b2 100644 --- a/vehicles/src/modules/shopping-cart/shopping-cart.controller.ts +++ b/vehicles/src/modules/shopping-cart/shopping-cart.controller.ts @@ -5,6 +5,7 @@ import { Get, Param, Post, + Query, Req, } from '@nestjs/common'; import { @@ -28,6 +29,7 @@ import { UpdateShoppingCartDto } from './dto/request/update-shopping-cart.dto'; import { ReadShoppingCartDto } from './dto/response/read-shopping-cart.dto'; import { ResultDto } from './dto/response/result.dto'; import { ShoppingCartService } from './shopping-cart.service'; +import { GetApplicationInCartQueryParams } from './dto/request/queryParam/getApplicationsInCart.query-param.dto'; @ApiBearerAuth() @ApiTags('Shopping Cart') @@ -97,10 +99,12 @@ export class ShoppingCartController { async getApplicationsInCart( @Req() request: Request, @Param() { companyId }: CompanyIdPathParamDto, + @Query() { allApplications }: GetApplicationInCartQueryParams, ): Promise { return await this.shoppingCartService.findApplicationsInCart( request.user as IUserJWT, companyId, + allApplications, ); } diff --git a/vehicles/src/modules/shopping-cart/shopping-cart.service.ts b/vehicles/src/modules/shopping-cart/shopping-cart.service.ts index ec78c4614..e04b8651b 100644 --- a/vehicles/src/modules/shopping-cart/shopping-cart.service.ts +++ b/vehicles/src/modules/shopping-cart/shopping-cart.service.ts @@ -77,13 +77,14 @@ export class ShoppingCartService { async findApplicationsInCart( currentUser: IUserJWT, companyId: number, + allApplications?: boolean, ): Promise { const { userGUID, orbcUserAuthGroup } = currentUser; - const applications = await this.getSelectShoppingCartQB( - companyId, + const applications = await this.getSelectShoppingCartQB(companyId, { userGUID, orbcUserAuthGroup, - ) + allApplications, + }) .orderBy({ 'application.updatedDateTime': 'DESC' }) .getMany(); @@ -114,11 +115,13 @@ export class ShoppingCartService { companyId: number, ): Promise { const { userGUID, orbcUserAuthGroup } = currentUser; - return await this.getSelectShoppingCartQB( - companyId, + return await this.getSelectShoppingCartQB(companyId, { userGUID, orbcUserAuthGroup, - ).getCount(); + // For a company admin, the cart count is the count of all the + // applications of the company with IN_CART status. + allApplications: true, + }).getCount(); } /** @@ -133,8 +136,15 @@ export class ShoppingCartService { */ private getSelectShoppingCartQB( companyId: number, - userGUID?: string, - orbcUserAuthGroup?: UserAuthGroup, + { + userGUID, + orbcUserAuthGroup, + allApplications, + }: { + userGUID?: string; + orbcUserAuthGroup?: UserAuthGroup; + allApplications?: boolean; + }, ): SelectQueryBuilder { const queryBuilder = this.applicationRepository .createQueryBuilder('application') @@ -148,15 +158,20 @@ export class ShoppingCartService { }); queryBuilder.andWhere('company.companyId = :companyId', { companyId }); - // If user is a Permit Applicant, get only their own applications in cart - if (orbcUserAuthGroup === ClientUserAuthGroup.PERMIT_APPLICANT) { + // Get only their own applications in cart. + // - If the user is a Permit Applicant + // - If the user has passed the allApplications query parameter + if ( + orbcUserAuthGroup === ClientUserAuthGroup.PERMIT_APPLICANT || + !allApplications + ) { queryBuilder.andWhere('applicationOwner.userGUID = :userGUID', { userGUID, }); } - // If user is a Company Admin, get all applications in cart for that company - // EXCEPT for those created by staff user. - else if (orbcUserAuthGroup === ClientUserAuthGroup.COMPANY_ADMINISTRATOR) { + // If the user is a BCeID user, select only those applications + // where the applicationOwner isn't a staff user. + if (!doesUserHaveAuthGroup(orbcUserAuthGroup, IDIR_USER_AUTH_GROUP_LIST)) { queryBuilder.andWhere( new NotBrackets((qb) => { qb.where('applicationOwner.directory = :directory', { @@ -243,7 +258,7 @@ export class ShoppingCartService { { permitId: applicationId, company: { companyId }, - ...(userGUID && { userGUID }), + ...(userGUID && { applicationOwner: { userGUID } }), }, { permitStatus: statusToUpdateTo,