From b4be18ad86d1c559bc3e8b70b5cf47f764c1fb77 Mon Sep 17 00:00:00 2001 From: gchauhan-aot <113390759+gchauhan-aot@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:18:36 -0600 Subject: [PATCH] BE: Special Auth Changes (#1529) Co-authored-by: praju-aot --- .../versions/revert/v_39_ddl_revert.sql | 33 +++++ database/mssql/scripts/versions/v_39_ddl.sql | 66 +++++++++ database/mssql/test/versions/v_39_1_test.sql | 14 ++ database/mssql/test/versions/v_39_test.sh | 16 +++ vehicles/src/app.module.ts | 4 +- vehicles/src/common/enum/no-fee-type.enum.ts | 7 + vehicles/src/modules/loa/loa.module.ts | 15 -- .../dto/request/create-lcv.dto.ts | 17 +++ .../dto/request/create-loa-file.dto.ts | 0 .../dto/request/create-loa.dto.ts | 0 .../dto/request/create-no-fee.dto.ts | 14 ++ .../pathParam/loa-Id.path-params.dto.ts | 0 .../queryParam/get-loa.query-params.dto.ts | 0 .../dto/request/update-loa-file.dto.ts | 0 .../dto/request/update-loa.dto.ts | 0 .../dto/response/read-loa.dto.ts | 0 .../dto/response/read-special-auth.dto.ts | 46 +++++++ .../entities/loa-detail.entity.ts | 0 .../loa-permit-type-details.entity.ts | 0 .../entities/loa-vehicles.entity.ts | 0 .../entities/special-auth.entity.ts | 54 ++++++++ .../{loa => special-auth}/loa.controller.ts | 16 +-- .../{loa => special-auth}/loa.service.ts | 1 - .../profile/loa.profile.ts | 0 .../profile/special-auth.profile.ts | 28 ++++ .../special-auth/special-auth.controller.ts | 104 ++++++++++++++ .../special-auth/special-auth.module.ts | 26 ++++ .../special-auth/special-auth.service.ts | 128 ++++++++++++++++++ 28 files changed, 563 insertions(+), 26 deletions(-) create mode 100644 database/mssql/scripts/versions/revert/v_39_ddl_revert.sql create mode 100644 database/mssql/scripts/versions/v_39_ddl.sql create mode 100644 database/mssql/test/versions/v_39_1_test.sql create mode 100644 database/mssql/test/versions/v_39_test.sh create mode 100644 vehicles/src/common/enum/no-fee-type.enum.ts delete mode 100644 vehicles/src/modules/loa/loa.module.ts create mode 100644 vehicles/src/modules/special-auth/dto/request/create-lcv.dto.ts rename vehicles/src/modules/{loa => special-auth}/dto/request/create-loa-file.dto.ts (100%) rename vehicles/src/modules/{loa => special-auth}/dto/request/create-loa.dto.ts (100%) create mode 100644 vehicles/src/modules/special-auth/dto/request/create-no-fee.dto.ts rename vehicles/src/modules/{loa => special-auth}/dto/request/pathParam/loa-Id.path-params.dto.ts (100%) rename vehicles/src/modules/{loa => special-auth}/dto/request/queryParam/get-loa.query-params.dto.ts (100%) rename vehicles/src/modules/{loa => special-auth}/dto/request/update-loa-file.dto.ts (100%) rename vehicles/src/modules/{loa => special-auth}/dto/request/update-loa.dto.ts (100%) rename vehicles/src/modules/{loa => special-auth}/dto/response/read-loa.dto.ts (100%) create mode 100644 vehicles/src/modules/special-auth/dto/response/read-special-auth.dto.ts rename vehicles/src/modules/{loa => special-auth}/entities/loa-detail.entity.ts (100%) rename vehicles/src/modules/{loa => special-auth}/entities/loa-permit-type-details.entity.ts (100%) rename vehicles/src/modules/{loa => special-auth}/entities/loa-vehicles.entity.ts (100%) create mode 100644 vehicles/src/modules/special-auth/entities/special-auth.entity.ts rename vehicles/src/modules/{loa => special-auth}/loa.controller.ts (97%) rename vehicles/src/modules/{loa => special-auth}/loa.service.ts (99%) rename vehicles/src/modules/{loa => special-auth}/profile/loa.profile.ts (100%) create mode 100644 vehicles/src/modules/special-auth/profile/special-auth.profile.ts create mode 100644 vehicles/src/modules/special-auth/special-auth.controller.ts create mode 100644 vehicles/src/modules/special-auth/special-auth.module.ts create mode 100644 vehicles/src/modules/special-auth/special-auth.service.ts diff --git a/database/mssql/scripts/versions/revert/v_39_ddl_revert.sql b/database/mssql/scripts/versions/revert/v_39_ddl_revert.sql new file mode 100644 index 000000000..af2a9a4cc --- /dev/null +++ b/database/mssql/scripts/versions/revert/v_39_ddl_revert.sql @@ -0,0 +1,33 @@ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +SET NOCOUNT ON +GO + +SET XACT_ABORT ON + +BEGIN TRY + BEGIN TRANSACTION + ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] DROP CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_CREATE_USERID] + ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] DROP CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_CREATE_TIMESTAMP] + ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] DROP CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_LAST_UPDATE_USERID] + ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] DROP CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_LAST_UPDATE_TIMESTAMP] + ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] DROP CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_CREATE_USERID] + ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] DROP CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_CREATE_TIMESTAMP] + ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] DROP CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_LAST_UPDATE_USERID] + ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] DROP CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_LAST_UPDATE_TIMESTAMP] + ALTER TABLE [permit].[ORBC_SPECIAL_AUTH_HIST] ALTER COLUMN NO_FEE_TYPE VARCHAR(12) NOT NULL + COMMIT +END TRY + +BEGIN CATCH + IF @@TRANCOUNT > 0 + ROLLBACK; + THROW +END CATCH + +DECLARE @VersionDescription VARCHAR(255) +SET @VersionDescription = 'Deleting constraint from DB related coulmns form special authorization and no fee tables' + +INSERT [dbo].[ORBC_SYS_VERSION] ([VERSION_ID], [DESCRIPTION], [RELEASE_DATE]) VALUES (38, @VersionDescription, getutcdate()) diff --git a/database/mssql/scripts/versions/v_39_ddl.sql b/database/mssql/scripts/versions/v_39_ddl.sql new file mode 100644 index 000000000..5db7ca6e1 --- /dev/null +++ b/database/mssql/scripts/versions/v_39_ddl.sql @@ -0,0 +1,66 @@ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +SET NOCOUNT ON +GO + +SET XACT_ABORT ON +GO +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE +GO +BEGIN TRANSACTION +GO +IF @@ERROR <> 0 SET NOEXEC ON +GO +ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] ADD CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_CREATE_USERID] DEFAULT(user_name()) +FOR [DB_CREATE_USERID] + +ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] ADD CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_CREATE_TIMESTAMP] DEFAULT(getutcdate()) +FOR [DB_CREATE_TIMESTAMP] + +ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] ADD CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_LAST_UPDATE_USERID] DEFAULT(user_name()) +FOR [DB_LAST_UPDATE_USERID] + +ALTER TABLE [permit].[ORBC_SPECIAL_AUTH] ADD CONSTRAINT [DF_ORBC_SPECIAL_AUTH_DB_LAST_UPDATE_TIMESTAMP] DEFAULT(getutcdate()) +FOR [DB_LAST_UPDATE_TIMESTAMP] + +ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] ADD CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_CREATE_USERID] DEFAULT(user_name()) +FOR [DB_CREATE_USERID] + +ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] ADD CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_CREATE_TIMESTAMP] DEFAULT(getutcdate()) +FOR [DB_CREATE_TIMESTAMP] + +ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] ADD CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_LAST_UPDATE_USERID] DEFAULT(user_name()) +FOR [DB_LAST_UPDATE_USERID] + +ALTER TABLE [permit].[ORBC_NO_FEE_TYPE] ADD CONSTRAINT [DF_ORBC_NO_FEE_TYPE_DB_LAST_UPDATE_TIMESTAMP] DEFAULT(getutcdate()) +FOR [DB_LAST_UPDATE_TIMESTAMP] +GO +ALTER TABLE [permit].[ORBC_SPECIAL_AUTH_HIST] ALTER COLUMN NO_FEE_TYPE VARCHAR(12) NULL +GO + +IF @@ERROR <> 0 SET NOEXEC ON +GO + +DECLARE @VersionDescription VARCHAR(255) +SET @VersionDescription = 'Default values for ORBC_SPECIAL_AUTH for Db related columns.' + +INSERT [dbo].[ORBC_SYS_VERSION] ([VERSION_ID], [DESCRIPTION], [UPDATE_SCRIPT], [REVERT_SCRIPT], [RELEASE_DATE]) VALUES (39, @VersionDescription, '$(UPDATE_SCRIPT)', '$(REVERT_SCRIPT)', getutcdate()) +IF @@ERROR <> 0 SET NOEXEC ON +GO + +COMMIT TRANSACTION +GO +IF @@ERROR <> 0 SET NOEXEC ON +GO +DECLARE @Success AS BIT +SET @Success = 1 +SET NOEXEC OFF +IF (@Success = 1) PRINT 'The database update succeeded' +ELSE BEGIN + IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION + PRINT 'The database update failed' +END +GO + diff --git a/database/mssql/test/versions/v_39_1_test.sql b/database/mssql/test/versions/v_39_1_test.sql new file mode 100644 index 000000000..b1f179125 --- /dev/null +++ b/database/mssql/test/versions/v_39_1_test.sql @@ -0,0 +1,14 @@ +-- Test that the role types have been inserted correctly against user auth groups +SET NOCOUNT ON + +IF (OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_SPECIAL_AUTH_DB_CREATE_USERID]','D') IS NOT NULL) +AND OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_SPECIAL_AUTH_DB_CREATE_TIMESTAMP]','D') IS NOT NULL +AND (OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_SPECIAL_AUTH_DB_LAST_UPDATE_USERID]','D') IS NOT NULL) +AND (OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_SPECIAL_AUTH_DB_LAST_UPDATE_TIMESTAMP]','D') IS NOT NULL) +AND (OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_NO_FEE_TYPE_DB_CREATE_USERID]','D') IS NOT NULL) +AND OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_NO_FEE_TYPE_DB_CREATE_TIMESTAMP]','D') IS NOT NULL +AND (OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_NO_FEE_TYPE_DB_LAST_UPDATE_USERID]','D') IS NOT NULL) +AND (OBJECT_ID('[$(DB_NAME)].[permit].[DF_ORBC_NO_FEE_TYPE_DB_LAST_UPDATE_TIMESTAMP]','D') IS NOT NULL) + SELECT 1 +ELSE + SELECT 0 \ No newline at end of file diff --git a/database/mssql/test/versions/v_39_test.sh b/database/mssql/test/versions/v_39_test.sh new file mode 100644 index 000000000..046cc61d4 --- /dev/null +++ b/database/mssql/test/versions/v_39_test.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Retrieve arguments +source ${SCRIPT_DIR}/utility/getopt.sh +USAGE="-u USER -p PASS -s SERVER -d DATABASE" +parse_options "${USAGE}" ${@} + +# All database tests for database version 39 are run from this shell script. +# TESTS_DIR variable set by the calling test-runner script. + +TEST_39_1_RESULT=$(/opt/mssql-tools/bin/sqlcmd -U ${USER} -P "${PASS}" -S ${SERVER} -v DB_NAME=${DATABASE} -h -1 -i ${TESTS_DIR}/v_39_1_test.sql | xargs) +if [[ $TEST_39_1_RESULT -eq 1 ]]; then + echo "Test 39.1 passed: Db column constaints for special auth and no fee table are added correctly" +else + echo "******** Test 39.1 failed: Db column constaints for special auth and no fee table are not added correctly" +fi \ No newline at end of file diff --git a/vehicles/src/app.module.ts b/vehicles/src/app.module.ts index 350e3d79c..2fda196fb 100644 --- a/vehicles/src/app.module.ts +++ b/vehicles/src/app.module.ts @@ -37,7 +37,7 @@ import { PaymentModule } from './modules/permit-application-payment/payment/paym import { PermitReceiptDocumentModule } from './modules/permit-application-payment/permit-receipt-document/permit-receipt-document.module'; import { ShoppingCartModule } from './modules/shopping-cart/shopping-cart.module'; import { CreditAccountModule } from './modules/credit-account/credit-account.module'; -import { LoaModule } from './modules/loa/loa.module'; +import { SpecialAuthModule } from './modules/special-auth/special-auth.module'; const envPath = path.resolve(process.cwd() + '/../'); @@ -101,7 +101,7 @@ const envPath = path.resolve(process.cwd() + '/../'); PermitModule, CreditAccountModule, FeatureFlagsModule, - LoaModule, + SpecialAuthModule, ], controllers: [AppController], providers: [AppService], diff --git a/vehicles/src/common/enum/no-fee-type.enum.ts b/vehicles/src/common/enum/no-fee-type.enum.ts new file mode 100644 index 000000000..127dc6921 --- /dev/null +++ b/vehicles/src/common/enum/no-fee-type.enum.ts @@ -0,0 +1,7 @@ +export enum NoFeeType { + CA_GOVT = 'CA_GOVT', + MUNICPALITY = 'MUNICPALITY', + SCHOOL = 'SCHOOL', + USA_GOVT = 'USA_GOVT', + ANY_USA_GOVT = 'ANY_USA_GOVT', +} diff --git a/vehicles/src/modules/loa/loa.module.ts b/vehicles/src/modules/loa/loa.module.ts deleted file mode 100644 index 9d88c9962..000000000 --- a/vehicles/src/modules/loa/loa.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Module } from '@nestjs/common'; -import { LoaController } from './loa.controller'; -import { LoaService } from './loa.service'; -import { LoaDetail } from './entities/loa-detail.entity'; -import { LoaPermitType } from './entities/loa-permit-type-details.entity'; -import { LoaVehicle } from './entities/loa-vehicles.entity'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { LoaProfile } from './profile/loa.profile'; - -@Module({ - imports: [TypeOrmModule.forFeature([LoaDetail, LoaPermitType, LoaVehicle])], - controllers: [LoaController], - providers: [LoaService, LoaProfile], -}) -export class LoaModule {} diff --git a/vehicles/src/modules/special-auth/dto/request/create-lcv.dto.ts b/vehicles/src/modules/special-auth/dto/request/create-lcv.dto.ts new file mode 100644 index 000000000..5ac29c3fe --- /dev/null +++ b/vehicles/src/modules/special-auth/dto/request/create-lcv.dto.ts @@ -0,0 +1,17 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Transform } from 'class-transformer'; +import { IsBoolean } from 'class-validator'; + +export class CreateLcvDto { + @ApiProperty({ + type: 'boolean', + example: false, + description: + 'Indicates whether the company is permitted to operate long combination vehicles', + }) + @Transform(({ obj, key }: { obj: Record; key: string }) => { + return obj[key] === 'true' ? true : obj[key] === 'false' ? false : obj[key]; + }) + @IsBoolean() + isLcvAllowed: boolean; +} diff --git a/vehicles/src/modules/loa/dto/request/create-loa-file.dto.ts b/vehicles/src/modules/special-auth/dto/request/create-loa-file.dto.ts similarity index 100% rename from vehicles/src/modules/loa/dto/request/create-loa-file.dto.ts rename to vehicles/src/modules/special-auth/dto/request/create-loa-file.dto.ts diff --git a/vehicles/src/modules/loa/dto/request/create-loa.dto.ts b/vehicles/src/modules/special-auth/dto/request/create-loa.dto.ts similarity index 100% rename from vehicles/src/modules/loa/dto/request/create-loa.dto.ts rename to vehicles/src/modules/special-auth/dto/request/create-loa.dto.ts diff --git a/vehicles/src/modules/special-auth/dto/request/create-no-fee.dto.ts b/vehicles/src/modules/special-auth/dto/request/create-no-fee.dto.ts new file mode 100644 index 000000000..e9a006522 --- /dev/null +++ b/vehicles/src/modules/special-auth/dto/request/create-no-fee.dto.ts @@ -0,0 +1,14 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsEnum, IsOptional } from 'class-validator'; +import { NoFeeType } from 'src/common/enum/no-fee-type.enum'; + +export class CreateNoFeeDto { + @ApiProperty({ + enum: NoFeeType, + example: NoFeeType.CA_GOVT, + description: 'Detailed reason of no fee type permit.', + }) + @IsOptional() + @IsEnum(NoFeeType) + noFeeType: NoFeeType; +} diff --git a/vehicles/src/modules/loa/dto/request/pathParam/loa-Id.path-params.dto.ts b/vehicles/src/modules/special-auth/dto/request/pathParam/loa-Id.path-params.dto.ts similarity index 100% rename from vehicles/src/modules/loa/dto/request/pathParam/loa-Id.path-params.dto.ts rename to vehicles/src/modules/special-auth/dto/request/pathParam/loa-Id.path-params.dto.ts diff --git a/vehicles/src/modules/loa/dto/request/queryParam/get-loa.query-params.dto.ts b/vehicles/src/modules/special-auth/dto/request/queryParam/get-loa.query-params.dto.ts similarity index 100% rename from vehicles/src/modules/loa/dto/request/queryParam/get-loa.query-params.dto.ts rename to vehicles/src/modules/special-auth/dto/request/queryParam/get-loa.query-params.dto.ts diff --git a/vehicles/src/modules/loa/dto/request/update-loa-file.dto.ts b/vehicles/src/modules/special-auth/dto/request/update-loa-file.dto.ts similarity index 100% rename from vehicles/src/modules/loa/dto/request/update-loa-file.dto.ts rename to vehicles/src/modules/special-auth/dto/request/update-loa-file.dto.ts diff --git a/vehicles/src/modules/loa/dto/request/update-loa.dto.ts b/vehicles/src/modules/special-auth/dto/request/update-loa.dto.ts similarity index 100% rename from vehicles/src/modules/loa/dto/request/update-loa.dto.ts rename to vehicles/src/modules/special-auth/dto/request/update-loa.dto.ts diff --git a/vehicles/src/modules/loa/dto/response/read-loa.dto.ts b/vehicles/src/modules/special-auth/dto/response/read-loa.dto.ts similarity index 100% rename from vehicles/src/modules/loa/dto/response/read-loa.dto.ts rename to vehicles/src/modules/special-auth/dto/response/read-loa.dto.ts diff --git a/vehicles/src/modules/special-auth/dto/response/read-special-auth.dto.ts b/vehicles/src/modules/special-auth/dto/response/read-special-auth.dto.ts new file mode 100644 index 000000000..265069445 --- /dev/null +++ b/vehicles/src/modules/special-auth/dto/response/read-special-auth.dto.ts @@ -0,0 +1,46 @@ +import { AutoMap } from '@automapper/classes'; +import { ApiProperty } from '@nestjs/swagger'; +import { Transform } from 'class-transformer'; +import { IsOptional } from 'class-validator'; +import { NoFeeType } from 'src/common/enum/no-fee-type.enum'; + +export class ReadSpecialAuthDto { + @AutoMap() + @ApiProperty({ + example: 1, + description: 'Unique Identifier for special authorization.', + }) + specialAuthId: number; + + @AutoMap() + @ApiProperty({ + description: 'Id of the company requesting the LoA.', + example: 74, + required: false, + }) + companyId: number; + + @AutoMap() + @ApiProperty({ + type: 'boolean', + example: false, + description: + 'Indicates whether the company is permitted to operate long combination vehicles', + required: false, + }) + @Transform(({ obj, key }: { obj: Record; key: string }) => { + return obj[key] === 'true' ? true : obj[key] === 'false' ? false : obj[key]; + }) + @IsOptional() + isLcvAllowed: boolean; + + @AutoMap() + @ApiProperty({ + enum: NoFeeType, + example: NoFeeType.CA_GOVT, + description: 'Detailed reason of no fee type permit.', + required: false, + }) + @IsOptional() + noFeeType: NoFeeType; +} diff --git a/vehicles/src/modules/loa/entities/loa-detail.entity.ts b/vehicles/src/modules/special-auth/entities/loa-detail.entity.ts similarity index 100% rename from vehicles/src/modules/loa/entities/loa-detail.entity.ts rename to vehicles/src/modules/special-auth/entities/loa-detail.entity.ts diff --git a/vehicles/src/modules/loa/entities/loa-permit-type-details.entity.ts b/vehicles/src/modules/special-auth/entities/loa-permit-type-details.entity.ts similarity index 100% rename from vehicles/src/modules/loa/entities/loa-permit-type-details.entity.ts rename to vehicles/src/modules/special-auth/entities/loa-permit-type-details.entity.ts diff --git a/vehicles/src/modules/loa/entities/loa-vehicles.entity.ts b/vehicles/src/modules/special-auth/entities/loa-vehicles.entity.ts similarity index 100% rename from vehicles/src/modules/loa/entities/loa-vehicles.entity.ts rename to vehicles/src/modules/special-auth/entities/loa-vehicles.entity.ts diff --git a/vehicles/src/modules/special-auth/entities/special-auth.entity.ts b/vehicles/src/modules/special-auth/entities/special-auth.entity.ts new file mode 100644 index 000000000..47704d9e4 --- /dev/null +++ b/vehicles/src/modules/special-auth/entities/special-auth.entity.ts @@ -0,0 +1,54 @@ +import { + Entity, + Column, + PrimaryGeneratedColumn, + ManyToOne, + JoinColumn, +} from 'typeorm'; +import { AutoMap } from '@automapper/classes'; +import { Base } from 'src/modules/common/entities/base.entity'; +import { Company } from 'src/modules/company-user-management/company/entities/company.entity'; +import { IsOptional } from 'class-validator'; +import { NoFeeType } from 'src/common/enum/no-fee-type.enum'; +import { ApiProperty } from '@nestjs/swagger'; + +@Entity({ name: 'permit.ORBC_SPECIAL_AUTH' }) +export class SpecialAuth extends Base { + @AutoMap() + @PrimaryGeneratedColumn({ type: 'int', name: 'ID' }) + specialAuthId: number; + + @AutoMap() + @ManyToOne(() => Company, { eager: true, cascade: false }) + @JoinColumn({ name: 'COMPANY_ID' }) + company: Company; + + @AutoMap() + @Column({ + type: 'char', + name: 'LCV', + nullable: false, + default: false, + transformer: { + to: (value: boolean): string => (value ? 'Y' : 'N'), // Converts the boolean value to 'Y' or 'N' for storage. + from: (value: string): boolean => value === 'Y', // Converts the stored string back to a boolean. + }, + }) + isLcvAllowed: boolean; + + @AutoMap() + @ApiProperty({ + enum: NoFeeType, + example: NoFeeType.CA_GOVT, + description: 'No Fee Type Id', + }) + @IsOptional() + @Column({ + type: 'simple-enum', + enum: NoFeeType, + length: 12, + name: 'NO_FEE_TYPE', + nullable: true, + }) + noFeeType: NoFeeType; +} diff --git a/vehicles/src/modules/loa/loa.controller.ts b/vehicles/src/modules/special-auth/loa.controller.ts similarity index 97% rename from vehicles/src/modules/loa/loa.controller.ts rename to vehicles/src/modules/special-auth/loa.controller.ts index da85fff40..2aff033cd 100644 --- a/vehicles/src/modules/loa/loa.controller.ts +++ b/vehicles/src/modules/special-auth/loa.controller.ts @@ -27,23 +27,23 @@ import { ApiUnprocessableEntityResponse, } from '@nestjs/swagger'; import { ExceptionDto } from 'src/common/exception/exception.dto'; -import { ReadLoaDto } from './dto/response/read-loa.dto'; import { IUserJWT } from 'src/common/interface/user-jwt.interface'; import { LoaService } from './loa.service'; import { Request, Response } from 'express'; -import { GetLoaQueryParamsDto } from './dto/request/queryParam/get-loa.query-params.dto'; import { FileInterceptor } from '@nestjs/platform-express'; import { FileDownloadModes } from 'src/common/enum/file-download-modes.enum'; import { setResHeaderCorrelationId } from 'src/common/helper/response-header.helper'; -import { JsonReqBodyInterceptor } from '../../common/interceptor/json-req-body.interceptor'; -import { CreateLoaFileDto } from './dto/request/create-loa-file.dto'; +import { Roles } from 'src/common/decorator/roles.decorator'; +import { Role } from 'src/common/enum/roles.enum'; +import { IsFeatureFlagEnabled } from 'src/common/decorator/is-feature-flag-enabled.decorator'; +import { ReadLoaDto } from './dto/response/read-loa.dto'; +import { JsonReqBodyInterceptor } from 'src/common/interceptor/json-req-body.interceptor'; import { CompanyIdPathParamDto } from '../common/dto/request/pathParam/companyId.path-param.dto'; -import { UpdateLoaFileDto } from './dto/request/update-loa-file.dto'; +import { CreateLoaFileDto } from './dto/request/create-loa-file.dto'; +import { GetLoaQueryParamsDto } from './dto/request/queryParam/get-loa.query-params.dto'; import { LoaIdPathParamDto } from './dto/request/pathParam/loa-Id.path-params.dto'; +import { UpdateLoaFileDto } from './dto/request/update-loa-file.dto'; import { GetDocumentQueryParamsDto } from '../common/dto/request/queryParam/getDocument.query-params.dto'; -import { IsFeatureFlagEnabled } from '../../common/decorator/is-feature-flag-enabled.decorator'; -import { Roles } from 'src/common/decorator/roles.decorator'; -import { Role } from 'src/common/enum/roles.enum'; @ApiBearerAuth() @ApiTags('Letter of Authorization (LoA)') diff --git a/vehicles/src/modules/loa/loa.service.ts b/vehicles/src/modules/special-auth/loa.service.ts similarity index 99% rename from vehicles/src/modules/loa/loa.service.ts rename to vehicles/src/modules/special-auth/loa.service.ts index f0b4067b5..d9e761715 100644 --- a/vehicles/src/modules/loa/loa.service.ts +++ b/vehicles/src/modules/special-auth/loa.service.ts @@ -285,7 +285,6 @@ export class LoaService { LoaDetail, { extraArgs: () => ({ - companyId, loaId, isActive, documentId, diff --git a/vehicles/src/modules/loa/profile/loa.profile.ts b/vehicles/src/modules/special-auth/profile/loa.profile.ts similarity index 100% rename from vehicles/src/modules/loa/profile/loa.profile.ts rename to vehicles/src/modules/special-auth/profile/loa.profile.ts diff --git a/vehicles/src/modules/special-auth/profile/special-auth.profile.ts b/vehicles/src/modules/special-auth/profile/special-auth.profile.ts new file mode 100644 index 000000000..c732a9cca --- /dev/null +++ b/vehicles/src/modules/special-auth/profile/special-auth.profile.ts @@ -0,0 +1,28 @@ +import { Mapper, createMap, forMember, mapFrom } from '@automapper/core'; +import { AutomapperProfile, InjectMapper } from '@automapper/nestjs'; +import { Injectable } from '@nestjs/common'; +import { SpecialAuth } from '../entities/special-auth.entity'; +import { ReadSpecialAuthDto } from '../dto/response/read-special-auth.dto'; + +@Injectable() +export class SpecialAuthProfile extends AutomapperProfile { + constructor(@InjectMapper() mapper: Mapper) { + super(mapper); + } + + override get profile() { + return (mapper: Mapper) => { + createMap( + mapper, + SpecialAuth, + ReadSpecialAuthDto, + forMember( + (d) => d.companyId, + mapFrom((s) => { + return s.company?.companyId; + }), + ), + ); + }; + } +} diff --git a/vehicles/src/modules/special-auth/special-auth.controller.ts b/vehicles/src/modules/special-auth/special-auth.controller.ts new file mode 100644 index 000000000..254490628 --- /dev/null +++ b/vehicles/src/modules/special-auth/special-auth.controller.ts @@ -0,0 +1,104 @@ +import { Body, Controller, Get, Param, Put, Req } from '@nestjs/common'; +import { + ApiBadRequestResponse, + ApiBearerAuth, + ApiInternalServerErrorResponse, + ApiMethodNotAllowedResponse, + ApiOperation, + ApiResponse, + ApiTags, + ApiUnprocessableEntityResponse, +} from '@nestjs/swagger'; +import { ExceptionDto } from 'src/common/exception/exception.dto'; +import { CompanyIdPathParamDto } from '../common/dto/request/pathParam/companyId.path-param.dto'; +import { SpecialAuthService } from './special-auth.service'; +import { ReadSpecialAuthDto } from './dto/response/read-special-auth.dto'; +import { IUserJWT } from 'src/common/interface/user-jwt.interface'; +import { Request } from 'express'; +import { CreateLcvDto } from './dto/request/create-lcv.dto'; +import { CreateNoFeeDto } from './dto/request/create-no-fee.dto'; +import { Roles } from 'src/common/decorator/roles.decorator'; +import { Role } from 'src/common/enum/roles.enum'; + +@ApiBearerAuth() +@ApiTags('Special Authorization') +@Controller('companies/:companyId/special-auths') +@ApiMethodNotAllowedResponse({ + description: 'The Special Authorizaion Api Method Not Allowed Response', + type: ExceptionDto, +}) +@ApiInternalServerErrorResponse({ + description: 'The Special Authorizaion Api Internal Server Error Response', + type: ExceptionDto, +}) +@ApiUnprocessableEntityResponse({ + description: 'The Special Authorizaion Entity could not be processed.', + type: ExceptionDto, +}) +@ApiBadRequestResponse({ + description: 'Bad Request Response', + type: ExceptionDto, +}) +export class SpecialAuthController { + constructor(private readonly specialAuthService: SpecialAuthService) {} + @ApiOperation({ + summary: 'Get all special authorizations for a company.', + description: + 'Returns all special authorizations for a company in the database.', + }) + @Roles(Role.READ_SPECIAL_AUTH) + @Get() + async get( + @Param() { companyId }: CompanyIdPathParamDto, + ): Promise { + return await this.specialAuthService.findOneDto(companyId); + } + + @ApiOperation({ + summary: 'Create or update LCV (Long Combination Vehicle) allowance.', + description: 'Create or update LCV (Long Combination Vehicle) allowance.', + }) + @ApiResponse({ + status: 200, + description: 'LCV allowance updated successfully.', + type: ReadSpecialAuthDto, + }) + @Roles(Role.WRITE_LCV_FLAG) + @Put('/lcv') + async updateLcv( + @Req() request: Request, + @Param() { companyId }: CompanyIdPathParamDto, + @Body() { isLcvAllowed }: CreateLcvDto, + ): Promise { + const currentUser = request.user as IUserJWT; + return await this.specialAuthService.upsertSpecialAuth({ + currentUser, + companyId, + isLcvAllowed, + }); + } + + @ApiOperation({ + summary: 'Create or update no fee type.', + description: 'Create or update no fee type.', + }) + @ApiResponse({ + status: 200, + description: 'No fee type updated successfully.', + type: ReadSpecialAuthDto, + }) + @Roles(Role.WRITE_NOFEE) + @Put('/no-fee') + async updateNoFee( + @Req() request: Request, + @Param() { companyId }: CompanyIdPathParamDto, + @Body() { noFeeType }: CreateNoFeeDto, + ): Promise { + const currentUser = request.user as IUserJWT; + return await this.specialAuthService.upsertSpecialAuth({ + currentUser, + companyId, + noFeeType, + }); + } +} diff --git a/vehicles/src/modules/special-auth/special-auth.module.ts b/vehicles/src/modules/special-auth/special-auth.module.ts new file mode 100644 index 000000000..f8b2ddf76 --- /dev/null +++ b/vehicles/src/modules/special-auth/special-auth.module.ts @@ -0,0 +1,26 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { SpecialAuthService } from './special-auth.service'; +import { SpecialAuth } from './entities/special-auth.entity'; +import { SpecialAuthController } from './special-auth.controller'; +import { LoaDetail } from './entities/loa-detail.entity'; +import { LoaVehicle } from './entities/loa-vehicles.entity'; +import { LoaPermitType } from './entities/loa-permit-type-details.entity'; +import { LoaController } from './loa.controller'; +import { LoaService } from './loa.service'; +import { LoaProfile } from './profile/loa.profile'; +import { SpecialAuthProfile } from './profile/special-auth.profile'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([ + SpecialAuth, + LoaDetail, + LoaVehicle, + LoaPermitType, + ]), + ], + controllers: [SpecialAuthController, LoaController], + providers: [SpecialAuthService, LoaService, LoaProfile, SpecialAuthProfile], +}) +export class SpecialAuthModule {} diff --git a/vehicles/src/modules/special-auth/special-auth.service.ts b/vehicles/src/modules/special-auth/special-auth.service.ts new file mode 100644 index 000000000..3109eea1e --- /dev/null +++ b/vehicles/src/modules/special-auth/special-auth.service.ts @@ -0,0 +1,128 @@ +import { LogAsyncMethodExecution } from 'src/common/decorator/log-async-method-execution.decorator'; +import { Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { InjectMapper } from '@automapper/nestjs'; +import { Mapper } from '@automapper/core'; +import { Repository } from 'typeorm'; +import { IUserJWT } from 'src/common/interface/user-jwt.interface'; +import { SpecialAuth } from './entities/special-auth.entity'; +import { ReadSpecialAuthDto } from './dto/response/read-special-auth.dto'; +import { Company } from '../company-user-management/company/entities/company.entity'; +import { Nullable } from '../../common/types/common'; +import { NoFeeType } from '../../common/enum/no-fee-type.enum'; + +export class SpecialAuthService { + private readonly logger = new Logger(SpecialAuthService.name); + constructor( + @InjectMapper() private readonly classMapper: Mapper, + @InjectRepository(SpecialAuth) + private specialAuthRepository: Repository, + ) {} + + /** + * Finds a special authorization by company ID. + * + * This method retrieves a special authorization entity from the database based on the provided company ID. + * + * @param companyId - The ID of the company for which to find the special authorization. + * + * @returns {Promise} A Promise that resolves to a `SpecialAuth` object representing the special authorization details. + * + * @throws Will throw an error if the special authorization cannot be found. + */ + @LogAsyncMethodExecution() + async findOne(companyId: number): Promise { + const specialAuthEntity = await this.specialAuthRepository.findOne({ + where: { + company: { companyId: companyId }, + }, + relations: ['company'], + }); + + return specialAuthEntity; + } + + /** + * Finds a special authorization by company ID. + * + * This method retrieves a special authorization entity from the database based on the provided company ID. + * It then maps the retrieved entity to a Data Transfer Object (DTO) for further processing or response. + * + * @param companyId - The ID of the company for which to find the special authorization. + * + * @returns {Promise} A Promise that resolves to a `ReadSpecialAuthDto` object representing the special authorization details. + * + * @throws Will throw an error if the special authorization cannot be found or if mapping fails. + */ + @LogAsyncMethodExecution() + async findOneDto(companyId: number): Promise { + const specialAuthEntity = await this.findOne(companyId); + const readSpecialAuthDto = await this.classMapper.mapAsync( + specialAuthEntity, + SpecialAuth, + ReadSpecialAuthDto, + ); + return readSpecialAuthDto; + } + + /** + * Creates or updates a special authorization based on the provided data. + * + * This method performs an upsert operation for special authorization. It first attempts to find an existing special authorization + * using the provided `companyId`. If found, it updates the existing record; if not, it creates a new special authorization. + * + * @param companyId - The ID of the company for which to create or update the special authorization. + * @param currentUser - The current user performing the operation. + * @param isLcvAllowed - Boolean flag indicating if LCV is allowed. + * @param noFeeType - The type of no-fee authorization. + * + * @returns {Promise} A Promise that resolves to a `ReadSpecialAuthDto` object representing the newly created or updated special authorization. + * + * @throws Will throw an error if the special authorization cannot be found or saved, or if mapping fails. + */ + @LogAsyncMethodExecution() + async upsertSpecialAuth({ + currentUser, + companyId, + isLcvAllowed, + noFeeType, + }: { + currentUser: IUserJWT; + companyId: number; + isLcvAllowed?: Nullable; + noFeeType?: Nullable; + }): Promise { + let specialAuth = await this.findOne(companyId); + const commonFields = { + isLcvAllowed: isLcvAllowed, + noFeeType: noFeeType, + updatedUser: currentUser.userName, + updatedUserGuid: currentUser.userGUID, + updatedDateTime: new Date(), + updatedUserDirectory: currentUser.orbcUserDirectory, + }; + + if (specialAuth) { + Object.assign(specialAuth, commonFields); + } else { + specialAuth = new SpecialAuth(); + specialAuth.company = new Company(); + Object.assign(specialAuth, { + ...commonFields, + company: { companyId: companyId }, + createdUser: currentUser.userName, + createdUserGuid: currentUser.userGUID, + createdDateTime: new Date(), + createdUserDirectory: currentUser.orbcUserDirectory, + }); + } + + specialAuth = await this.specialAuthRepository.save(specialAuth); + + return await this.classMapper.mapAsync( + specialAuth, + SpecialAuth, + ReadSpecialAuthDto, + ); + } +}