diff --git a/src/db/db.module.ts b/src/db/db.module.ts index b243f5d..7973daa 100644 --- a/src/db/db.module.ts +++ b/src/db/db.module.ts @@ -1,6 +1,7 @@ -import { Module } from '@nestjs/common'; +import { Global, Module } from '@nestjs/common'; import { MssqlDBService, OracleDBService } from './db.service'; +@Global() @Module({ providers: [OracleDBService,MssqlDBService], exports:[OracleDBService,MssqlDBService] diff --git a/src/db/db.service.ts b/src/db/db.service.ts index 825671f..142dc9d 100644 --- a/src/db/db.service.ts +++ b/src/db/db.service.ts @@ -1,7 +1,9 @@ import { MssqlConfig , OracleConfig} from 'ormconfig'; import { createPool, Pool, Connection as cob, } from 'oracledb'; import { Connection, ConnectionPool } from 'mssql'; +import { Global, Injectable } from '@nestjs/common'; +@Injectable() export class OracleDBService { private pool: Pool; @@ -25,6 +27,7 @@ export class OracleDBService { } } +@Injectable() export class MssqlDBService { private pool: ConnectionPool; private readonly config = { diff --git a/src/main.ts b/src/main.ts index 3b6a01a..e5a9a93 100644 --- a/src/main.ts +++ b/src/main.ts @@ -54,11 +54,11 @@ async function bootstrap() { }; app.useGlobalPipes(new ValidationPipe({ + transform: true, exceptionFactory: customExceptionFactory, - stopAtFirstError: true, whitelist: true, + stopAtFirstError: true, forbidNonWhitelisted: true, - transform: true })); // app.useGlobalPipes(new ValidationPipe({ exceptionFactory:customExceptionFactory, whitelist: true, forbidNonWhitelisted: true, transform: true })); diff --git a/src/oracle/manage-clients/manage-clients.controller.ts b/src/oracle/manage-clients/manage-clients.controller.ts new file mode 100644 index 0000000..a4405a6 --- /dev/null +++ b/src/oracle/manage-clients/manage-clients.controller.ts @@ -0,0 +1,54 @@ +import { Body, Controller, Get, Post, Query } from '@nestjs/common'; +import { ManageClientsService } from './manage-clients.service'; +import { CreateClientDataDTO, GetPreparersDTO } from './manage-clients.dto'; +import { ApiTags } from '@nestjs/swagger'; + +@Controller('oracle') +export class ManageClientsController { + + constructor(private readonly manageClientsService:ManageClientsService){} + + @ApiTags('Manage Clients - Oracle') + @Post('CreateNewClients') + async CreateClientData(@Body() body:CreateClientDataDTO){ + return this.manageClientsService.CreateClientData(body); + } + + UpdateClient = async () =>{ + + } + + UpdateClientContacts = async () =>{ + + } + + UpdateClientLocations = async () =>{ + + } + + CreateClientContact = async () =>{ + + } + + CreateClientLocation = async () =>{ + + } + + @ApiTags('Manage Clients - Oracle') + @Get('GetPreparers') + async GetPreparers(@Query() query:GetPreparersDTO) { + return await this.manageClientsService.GetPreparers(query) + } + + GetPreparerByClientid = async () =>{ + + } + + GetPreparerContactsByClientid = async () =>{ + + } + + GetPreparerLocByClientid = async () =>{ + + } +} diff --git a/src/oracle/manage-clients/manage-clients.dto.ts b/src/oracle/manage-clients/manage-clients.dto.ts new file mode 100644 index 0000000..4a1a629 --- /dev/null +++ b/src/oracle/manage-clients/manage-clients.dto.ts @@ -0,0 +1,329 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsDefined, IsInt, IsNumber, IsOptional, IsString, Length, Max, Min, ValidateNested, IsArray, IsEmail } from 'class-validator'; +import { Transform, Type } from 'class-transformer'; +import { p_contactstableDTO } from '../manage-holders/manage-holders.dto'; + + +export class p_clientlocaddresstableDTO { + @ApiProperty({ required: true }) + @Length(0, 50, { message: "Property Nameof must be between 0 to 50 characters" }) + @IsString({ message: "Property Nameof must be a string" }) + @IsDefined({ message: "Property Nameof is required" }) + Nameof: string; + + @ApiProperty({ required: true }) + @Length(0, 50, { message: "Property Address1 must be between 0 to 50 characters" }) + @IsString({ message: "Property Address1 must be a string" }) + @IsDefined({ message: "Property Address1 is required" }) + Address1: string; + + @ApiProperty({ required: false }) + @Length(0, 50, { message: "Property Address2 must be between 0 to 50 characters" }) + @IsString({ message: "Property Address2 must be a string" }) + @IsOptional() + Address2?: string; + + @ApiProperty({ required: true }) + @Length(0, 30, { message: "Property City must be between 0 to 30 characters" }) + @IsString({ message: "Property City must be a string" }) + @IsDefined({ message: "Property City is required" }) + City: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property State must be between 0 to 2 characters" }) + @IsString({ message: "Property State must be a string" }) + @IsDefined({ message: "Property State is required" }) + State: string; + + @ApiProperty({ required: true }) + @Length(0, 10, { message: "Property Zip must be between 0 to 10 characters" }) + @IsString({ message: "Property Zip must be a string" }) + @IsDefined({ message: "Property Zip is required" }) + Zip: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property Country must be between 0 to 2 characters" }) + @IsString({ message: "Property Country must be a string" }) + @IsDefined({ message: "Property Country is required" }) + Country: string; +} + +export class CreateClientDataDTO { + @ApiProperty({ required: true }) + @Max(999999999, { message: "Property p_spid must not exceed 999999999" }) + @Min(0, { message: "Property p_spid must be at least 0 or more" }) + @IsInt({ message: "Property p_spid allows only whole numbers" }) + @IsNumber({}, { message: "Property p_spid must be a number" }) + @IsDefined({ message: "Property p_spid is required" }) + p_spid: number; + + @ApiProperty({ required: true }) + // @Max(999999999, { message: "Property p_clientname must not exceed 999999999" }) + // @Min(0, { message: "Property p_clientname must be at least 0 or more" }) + // @IsInt({ message: "Property p_clientname allows only whole numbers" }) + // @IsNumber({}, { message: "Property p_clientname must be a number" }) + // @IsDefined({ message: "Property p_clientname is required" }) + @Length(0, 50, { message: "Property p_clientname must be between 0 to 50 characters" }) + @IsString({ message: "Property p_clientname must be a string" }) + @IsDefined({ message: "Property p_clientname is required" }) + p_clientname: string; + + @ApiProperty({ required: true }) + @Length(0, 20, { message: "Property p_lookupcode must be between 0 to 20 characters" }) + @IsString({ message: "Property p_lookupcode must be a string" }) + @IsDefined({ message: "Property p_lookupcode is required" }) + p_lookupcode: string; + + @ApiProperty({ required: true }) + @Length(0, 50, { message: "Property p_address1 must be between 0 to 50 characters" }) + @IsString({ message: "Property p_address1 must be a string" }) + @IsDefined({ message: "Property p_address1 is required" }) + p_address1: string; + + @ApiProperty({ required: false }) + @Length(0, 50, { message: "Property p_address2 must be between 0 to 50 characters" }) + @IsString({ message: "Property p_address2 must be a string" }) + @IsOptional() + p_address2?: string; + + @ApiProperty({ required: true }) + @Length(0, 30, { message: "Property p_city must be between 0 to 30 characters" }) + @IsString({ message: "Property p_city must be a string" }) + @IsDefined({ message: "Property p_city is required" }) + p_city: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property p_state must be between 0 to 2 characters" }) + @IsString({ message: "Property p_state must be a string" }) + @IsDefined({ message: "Property p_state is required" }) + p_state: string; + + @ApiProperty({ required: false }) + @Length(0, 10, { message: "Property p_zip must be between 0 to 10 characters" }) + @IsString({ message: "Property p_zip must be a string" }) + @IsOptional() + p_zip?: string; + + @ApiProperty({ required: false }) + @Length(0, 2, { message: "Property p_country must be between 0 to 2 characters" }) + @IsString({ message: "Property p_country must be a string" }) + @IsOptional() + p_country?: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property p_issuingregion must be between 0 to 2 characters" }) + @IsString({ message: "Property p_issuingregion must be a string" }) + @IsDefined({ message: "Property p_issuingregion is required" }) + p_issuingregion: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property p_revenuelocation must be between 0 to 2 characters" }) + @IsString({ message: "Property p_revenuelocation must be a string" }) + @IsDefined({ message: "Property p_revenuelocation is required" }) + p_revenuelocation: string; + + @ApiProperty({ required: true }) + @Length(0, 100, { message: "Property p_userid must be between 0 to 100 characters" }) + @IsString({ message: "Property p_userid must be a string" }) + @IsDefined({ message: "Property p_userid is required" }) + p_userid: string; + + @ApiProperty({ required: true, type: () => [p_contactstableDTO] }) + @Type(() => p_contactstableDTO) + @ValidateNested({ each: true }) + @IsArray({ message: "Property p_contactstable allows only array type" }) + @IsDefined({ message: "Property p_contactstable is required" }) + p_contactstable: p_contactstableDTO[]; + + @ApiProperty({ required: true, type: () => [p_clientlocaddresstableDTO] }) + @Type(() => p_clientlocaddresstableDTO) + @ValidateNested({ each: true }) + @IsArray({ message: "Property p_clientlocaddresstable allows only array type" }) + @IsDefined({ message: "Property p_clientlocaddresstable is required" }) + p_clientlocaddresstable: p_clientlocaddresstableDTO[]; +} + +export class UpdateClientDTO { + @ApiProperty({ required: true }) + @Max(999999999, { message: "Property p_spid must not exceed 999999999" }) + @Min(0, { message: "Property p_spid must be at least 0 or more" }) + @IsInt({ message: "Property p_spid allows only whole numbers" }) + @IsNumber({}, { message: "Property p_spid must be a number" }) + @IsDefined({ message: "Property p_spid is required" }) + p_spid: number; + + @ApiProperty({ required: true }) + @Max(999999999, { message: "Property p_clientid must not exceed 999999999" }) + @Min(0, { message: "Property p_clientid must be at least 0 or more" }) + @IsInt({ message: "Property p_clientid allows only whole numbers" }) + @IsNumber({}, { message: "Property p_clientid must be a number" }) + @IsDefined({ message: "Property p_clientid is required" }) + p_clientid: number; + + @ApiProperty({ required: true }) + @Length(0, 50, { message: "Property p_preparername must be between 0 to 50 characters" }) + @IsString({ message: "Property p_preparername must be a string" }) + @IsDefined({ message: "Property p_preparername is required" }) + p_preparername: string; + + @ApiProperty({ required: true }) + @Length(0, 50, { message: "Property p_address1 must be between 0 to 50 characters" }) + @IsString({ message: "Property p_address1 must be a string" }) + @IsDefined({ message: "Property p_address1 is required" }) + p_address1: string; + + @ApiProperty({ required: false }) + @Length(0, 50, { message: "Property p_address2 must be between 0 to 50 characters" }) + @IsString({ message: "Property p_address2 must be a string" }) + @IsOptional() + p_address2?: string; + + @ApiProperty({ required: true }) + @Length(0, 30, { message: "Property p_city must be between 0 to 30 characters" }) + @IsString({ message: "Property p_city must be a string" }) + @IsDefined({ message: "Property p_city is required" }) + p_city: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property p_state must be between 0 to 2 characters" }) + @IsString({ message: "Property p_state must be a string" }) + @IsDefined({ message: "Property p_state is required" }) + p_state: string; + + @ApiProperty({ required: true }) + @Length(0, 10, { message: "Property p_zip must be between 0 to 10 characters" }) + @IsString({ message: "Property p_zip must be a string" }) + @IsDefined({ message: "Property p_zip is required" }) + p_zip: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property p_country must be between 0 to 2 characters" }) + @IsString({ message: "Property p_country must be a string" }) + @IsDefined({ message: "Property p_country is required" }) + p_country: string; + + @ApiProperty({ required: true }) + @Length(0, 2, { message: "Property p_revenuelocation must be between 0 to 2 characters" }) + @IsString({ message: "Property p_revenuelocation must be a string" }) + @IsDefined({ message: "Property p_revenuelocation is required" }) + p_revenuelocation: string; + + @ApiProperty({ required: true }) + @Length(0, 100, { message: "Property p_userid must be between 0 to 100 characters" }) + @IsString({ message: "Property p_userid must be a string" }) + @IsDefined({ message: "Property p_userid is required" }) + p_userid: string; +} + +export class UpdateClientContactsDTO { + @ApiProperty({ required: true }) + @Max(999999999, { message: "Property p_spid must not exceed 999999999" }) + @Min(0, { message: "Property p_spid must be at least 0 or more" }) + @IsInt({ message: "Property p_spid allows only whole numbers" }) + @IsNumber({}, { message: "Property p_spid must be a number" }) + @IsDefined({ message: "Property p_spid is required" }) + p_spid: number; + + @ApiProperty({ required: true }) + @Max(999999999, { message: "Property p_clientcontactid must not exceed 999999999" }) + @Min(0, { message: "Property p_clientcontactid must be at least 0 or more" }) + @IsInt({ message: "Property p_clientcontactid allows only whole numbers" }) + @IsNumber({}, { message: "Property p_clientcontactid must be a number" }) + @IsDefined({ message: "Property p_clientcontactid is required" }) + p_clientcontactid: number; + + @ApiProperty({ required: true }) + @Length(0, 50, { message: "Property p_firstname must be between 0 to 50 characters" }) + @IsString({ message: "Property p_firstname must be a string" }) + @IsDefined({ message: "Property p_firstname is required" }) + p_firstname: string; + + @ApiProperty({ required: true }) + @Length(0, 50, { message: "Property p_lastname must be between 0 to 50 characters" }) + @IsString({ message: "Property p_lastname must be a string" }) + @IsDefined({ message: "Property p_lastname is required" }) + p_lastname: string; + + @ApiProperty({ required: false }) + @Length(0, 3, { message: "Property p_middleinitial must be between 0 to 3 characters" }) + @IsString({ message: "Property p_middleinitial must be a string" }) + @IsOptional() + p_middleinitial?: string; + + @ApiProperty({ required: false }) + @Length(0, 50, { message: "Property p_title must be between 0 to 50 characters" }) + @IsString({ message: "Property p_title must be a string" }) + @IsOptional() + p_title?: string; + + @ApiProperty({ required: true }) + @Length(0, 20, { message: "Property p_phone must be between 0 to 20 characters" }) + @IsString({ message: "Property p_phone must be a string" }) + @IsDefined({ message: "Property p_phone is required" }) + p_phone: string; + + @ApiProperty({ required: true }) + @Length(0, 20, { message: "Property p_fax must be between 0 to 20 characters" }) + @IsString({ message: "Property p_fax must be a string" }) + @IsDefined({ message: "Property p_fax is required" }) + p_fax: string; + + @ApiProperty({ required: false }) + @Length(0, 20, { message: "Property p_mobileno must be between 0 to 20 characters" }) + @IsString({ message: "Property p_mobileno must be a string" }) + @IsOptional() + p_mobileno?: string; + + @ApiProperty({ required: true }) + @Length(0, 100, { message: "Property p_emailaddress must be between 0 to 100 characters" }) + @IsEmail({}, { message: "Property p_emailaddress must be a valid email address" }) + @IsDefined({ message: "Property p_emailaddress is required" }) + p_emailaddress: string; + + @ApiProperty({ required: true }) + @Length(0, 100, { message: "Property p_userid must be between 0 to 100 characters" }) + @IsString({ message: "Property p_userid must be a string" }) + @IsDefined({ message: "Property p_userid is required" }) + p_userid: string; +} + +export class GetPreparersDTO { + @ApiProperty({ required: true }) + @Transform(({ value }) => Number(value)) + @Max(999999999, { message: "Property p_spid must not exceed 999999999" }) + @Min(0, { message: "Property p_spid must be at least 0 or more" }) + @IsInt({ message: "Property p_spid allows only whole numbers" }) + @IsNumber({}, { message: "Property p_spid must be a number" }) + @IsDefined({ message: "Property p_spid is required" }) + p_spid: number; + + @ApiProperty({ required: false }) + @Length(0, 50, { message: "Property p_name must be between 0 to 50 characters" }) + @IsString({ message: "Property p_name must be a string" }) + @IsOptional() + p_name?: string; + + @ApiProperty({ required: false }) + @Length(0, 30, { message: "Property p_lookupcode must be between 0 to 30 characters" }) + @IsString({ message: "Property p_lookupcode must be a string" }) + @IsOptional() + p_lookupcode?: string; + + @ApiProperty({ required: false }) + @Length(0, 20, { message: "Property p_city must be between 0 to 20 characters" }) + @IsString({ message: "Property p_city must be a string" }) + @IsOptional() + p_city?: string; + + @ApiProperty({ required: false }) + @Length(0, 2, { message: "Property p_state must be between 0 to 2 characters" }) + @IsString({ message: "Property p_state must be a string" }) + @IsOptional() + p_state?: string; + + @ApiProperty({ required: true }) + @Length(0, 10, { message: "Property p_status must be between 0 to 10 characters" }) + @IsString({ message: "Property p_status must be a string" }) + @IsDefined({ message: "Property p_status is required" }) + p_status: string; +} \ No newline at end of file diff --git a/src/oracle/manage-clients/manage-clients.module.ts b/src/oracle/manage-clients/manage-clients.module.ts new file mode 100644 index 0000000..72b2df6 --- /dev/null +++ b/src/oracle/manage-clients/manage-clients.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { ManageClientsController } from './manage-clients.controller'; +import { ManageClientsService } from './manage-clients.service'; + +@Module({ + controllers: [ManageClientsController], + providers: [ManageClientsService] +}) +export class ManageClientsModule {} diff --git a/src/oracle/manage-clients/manage-clients.service.ts b/src/oracle/manage-clients/manage-clients.service.ts new file mode 100644 index 0000000..afbc6ba --- /dev/null +++ b/src/oracle/manage-clients/manage-clients.service.ts @@ -0,0 +1,182 @@ +import { Injectable } from '@nestjs/common'; +import { OracleDBService } from 'src/db/db.service'; +import { CreateClientDataDTO, GetPreparersDTO } from './manage-clients.dto'; + +@Injectable() +export class ManageClientsService { + constructor(private readonly oracleDBService: OracleDBService) { } + + CreateClientData = async (body: CreateClientDataDTO) => { + + + + let newBody = { + "p_spid": null, + "p_clientlocationid": null, + "p_holderno": null, + "p_holdertype": null, + "p_uscibmemberflag": null, + "p_govagencyflag": null, + "p_holdername": null, + "p_namequalifier": null, + "p_addlname": null, + "p_address1": null, + "p_address2": null, + "p_city": null, + "p_state": null, + "p_zip": null, + "p_country": null, + "p_userid": null, + "p_contactstable": null + } + + let reqBody = JSON.parse(JSON.stringify(body)); + + function setEmptyStringsToNull(obj) { + Object.keys(obj).forEach(key => { + if (typeof obj[key] === 'object' && obj[key] !== null) { + setEmptyStringsToNull(obj[key]); + } else if (obj[key] === "") { + obj[key] = null; + } + }); + } + + setEmptyStringsToNull(reqBody); + + const finalBody: CreateClientDataDTO = { ...newBody, ...reqBody }; + + let connection; + let p_holdercursor_rows = []; + let p_holdercontactcursor_rows = []; + try { + + connection = await this.oracleDBService.getConnection() + if (!connection) { + throw new Error('No DB Connected') + } + + let res = await connection.execute(`SELECT owner, type_name FROM all_types WHERE type_name LIKE '%CLIENT%'`); + + return { res:res.rows }; + + // const CONTACTSARRAY = await connection.getDbObjectClass('CARNETSYS.CONTACTSARRAY'); + // const CONTACTSTABLE = await connection.getDbObjectClass('CARNETSYS.CONTACTSTABLE'); + + // // Check if GLTABLE is a constructor + // if (typeof CONTACTSTABLE !== 'function') { + // throw new Error('CONTACTSTABLE is not a constructor'); + // } + + // async function CREATECONTACTSTABLE_INSTANCE(connection, FirstName, LastName, MiddleInitial, Title, EmailAddress, PhoneNo, MobileNo, FaxNo) { + // const result = await connection.execute( + // `SELECT CARNETSYS.CONTACTSARRAY(:FirstName, :LastName, :MiddleInitial, :Title, :EmailAddress, :PhoneNo, :MobileNo, :FaxNo) FROM dual`, + // { + // FirstName, + // LastName, + // MiddleInitial, + // Title, + // EmailAddress, + // PhoneNo, + // MobileNo, + // FaxNo + // } + // ); + // return result.rows[0][0]; + // } + + // const CONTACTSARRAY = finalBody.p_contactstable ? await Promise.all(finalBody.p_contactstable.map(async (x: p_contactstableDTO) => { + // return await CREATECONTACTSTABLE_INSTANCE(connection, x.FirstName, x.LastName, x.MiddleInitial, x.Title, x.EmailAddress, x.PhoneNo, x.MobileNo, x.FaxNo); + // })) : []; + + // Create an instance of GLTABLE + // const CONTACTSTABLE_INSTANCE = new CONTACTSTABLE(CONTACTSARRAY); + + // const result = await connection.execute( + // `BEGIN + // MANAGEHOLDER_PKG.CreateHolderData( + // :p_spid, + // ); + // END;`, + // { + // p_spid: { + // val: finalBody.p_spid ? finalBody.p_spid : null, + // type: oracledb.DB_TYPE_NUMBER + // }, + + // p_holderno: { + // val: finalBody.p_holderno ? finalBody.p_holderno : null, + // type: oracledb.DB_TYPE_NVARCHAR + // }, + // p_holdercontactcursor: { + // type: oracledb.CURSOR, + // dir: oracledb.BIND_OUT + // } + // }, { + // outFormat: oracledb.OUT_FORMAT_OBJECT + // } + // ); + + // await connection.commit(); + + // if (result.outBinds && result.outBinds.p_holdercursor) { + // const cursor = result.outBinds.p_holdercursor; + // let rowsBatch; + + // do { + // rowsBatch = await cursor.getRows(100); + // p_holdercursor_rows = p_holdercursor_rows.concat(rowsBatch); + // } while (rowsBatch.length > 0); + + + // await cursor.close(); + // } else { + // throw new Error('No cursor returned from the stored procedure'); + // } + + // return { p_holdercursor: p_holdercursor_rows, p_holdercontactcursor: p_holdercontactcursor_rows }; + + + } catch (err) { + console.error('Error fetching users: ', err); + return { error: err.message } + } finally { } + + } + + UpdateClient = async () => { + + } + + UpdateClientContacts = async () => { + + } + + UpdateClientLocations = async () => { + + } + + CreateClientContact = async () => { + + } + + CreateClientLocation = async () => { + + } + + GetPreparers = async (reqQuery: GetPreparersDTO) => { + return reqQuery + } + + GetPreparerByClientid = async () => { + + } + + GetPreparerContactsByClientid = async () => { + + } + + GetPreparerLocByClientid = async () => { + + } +} diff --git a/src/oracle/oracle.module.ts b/src/oracle/oracle.module.ts index ec968c7..edc3d6b 100644 --- a/src/oracle/oracle.module.ts +++ b/src/oracle/oracle.module.ts @@ -9,9 +9,10 @@ import { HomePageModule } from './home-page/home-page.module'; import { UscibManagedSpModule } from './uscib-managed-sp/uscib-managed-sp.module'; import { ParamTableModule } from './param-table/param-table.module'; import { ManageFeeModule } from './manage-fee/manage-fee.module'; +import { ManageClientsModule } from './manage-clients/manage-clients.module'; @Module({ - imports:[DbModule, HomePageModule, ManageHoldersModule, UscibManagedSpModule, ParamTableModule, ManageFeeModule], + imports:[DbModule, HomePageModule, ManageHoldersModule, UscibManagedSpModule, ParamTableModule, ManageFeeModule, ManageClientsModule], providers: [OracleService,ParamTableService,ManageFeeService], controllers: [OracleController], exports:[OracleService,ParamTableService,ManageFeeService]