added holders and client

This commit is contained in:
Kallesh B S 2025-09-18 15:45:53 +05:30
parent 72ffa77ba6
commit 2a45c0b522
9 changed files with 1248 additions and 30 deletions

View File

@ -11,8 +11,8 @@ import { PgModule } from './pg/pg.module';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }), PgModule,
AuthModule, DbModule, OracleModule, MailModule, PaypalModule
ConfigModule.forRoot({ isGlobal: true }),
AuthModule, PgModule, DbModule, OracleModule, MailModule, PaypalModule
],
controllers: [],
providers: [],

View File

@ -100,7 +100,9 @@ export class CONTACTSTABLE_ROW_DTO extends IntersectionType(
PHONE_NO_DTO,
MOBILE_NO_DTO,
PartialType(FAX_NO_DTO)
) { }
) {
FAX_NO: null;
}
export class CONTACTSTABLE_DTO {
@ApiProperty({ required: true, type: () => [CONTACTSTABLE_ROW_DTO] })

View File

@ -89,7 +89,8 @@ async function bootstrap() {
.addTag('SPContacts - PG')
.addTag('User Maintenance - PG')
.addTag('Manage Fee - PG')
// .addTag('Manage Holders - PG')
.addTag('Manage Holders - PG')
.addTag('Manage Clients - PG')
.addTag('User Maintenance - Oracle')
.addTag('Carnet Application - Oracle')
.addTag('HomePage - Oracle')

View File

@ -0,0 +1,92 @@
import { Body, Controller, Get, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common';
import { ClientContactControlsDTO, CreateClientContactsDTO, CreateClientDataDTO, CreateClientLocationsDTO, GetClientContactByLacationIdDTO, GetClientDTO, GetPreparersParamDTO, GetPreparersQueryDTO, UpdateClientContactsDTO, UpdateClientDTO, UpdateClientLocationsDTO } from 'src/dto/property.dto';
import { ManageClientsService } from './manage-clients.service';
import { Roles } from 'src/decorators/roles.decorator';
import { ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
import { RolesGuard } from 'src/guards/roles.guard';
@ApiTags('Manage Clients - PG')
// @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('sa')
@Controller('1')
export class ManageClientsController {
constructor(private readonly manageClientsService: ManageClientsService) { }
@Post('CreateNewClients')
async CreateClientData(@Body() body: CreateClientDataDTO) {
return this.manageClientsService.CreateClientData(body);
}
@Put('UpdateClient')
async UpdateClient(@Body() body: UpdateClientDTO) {
return this.manageClientsService.UpdateClient(body);
}
@Put('UpdateClientContacts')
@Roles('ca', 'sa')
UpdateClientContacts(@Body() body: UpdateClientContactsDTO) {
return this.manageClientsService.UpdateClientContacts(body);
}
@Put('UpdateClientLocations')
@Roles('ca', 'sa')
UpdateClientLocations(@Body() body: UpdateClientLocationsDTO) {
return this.manageClientsService.UpdateClientLocations(body);
}
@Post('CreateClientContacts')
@Roles('ca', 'sa')
CreateClientContact(@Body() body: CreateClientContactsDTO) {
return this.manageClientsService.CreateClientContact(body);
}
@Patch('SetDefaultClientContacts/:P_SPID/:P_CLIENTCONTACTID/:P_USERID')
SetDefaultClientContacts(@Param() param: ClientContactControlsDTO) {
return this.manageClientsService.SetDefaultClientContacts(param);
}
@Patch('InactivateClientContacts/:P_SPID/:P_CLIENTCONTACTID/:P_USERID')
InactivateClientContacts(@Param() param: ClientContactControlsDTO) {
return this.manageClientsService.InactivateClientContacts(param);
}
@Patch('ReactivateClientContacts/:P_SPID/:P_CLIENTCONTACTID/:P_USERID')
ReactivateClientContacts(@Param() param: ClientContactControlsDTO) {
return this.manageClientsService.ReactivateClientContacts(param);
}
@Post('CreateClientLocations')
@Roles('ca', 'sa')
CreateClientLocation(@Body() body: CreateClientLocationsDTO) {
return this.manageClientsService.CreateClientLocation(body);
}
@Get('GetPreparers/:P_SPID/:P_STATUS')
async GetPreparers(@Param() param: GetPreparersParamDTO, @Query() query: GetPreparersQueryDTO) {
return await this.manageClientsService.GetPreparers({ ...param, ...query });
}
@Get('GetPreparerByClientid/:P_SPID/:P_CLIENTID')
GetPreparerByClientid(@Param() body: GetClientDTO) {
return this.manageClientsService.GetPreparerByClientid(body);
}
@Get('GetPreparerContactsByClientid/:P_SPID/:P_CLIENTID')
@Roles('ca', 'sa')
GetPreparerContactsByClientid(@Param() body: GetClientDTO) {
return this.manageClientsService.GetPreparerContactsByClientid(body);
}
@Get('GetPreparerContactsbyClientLocationID/:P_SPID/:P_LOCATIONID')
@Roles('ca', 'sa')
GetPreparerContactsbyClientLocationID(@Param() body: GetClientContactByLacationIdDTO) {
return this.manageClientsService.GetPreparerContactsbyClientLocationID(body);
}
@Get('GetPreparerLocByClientid/:P_SPID/:P_CLIENTID')
@Roles('ca', 'sa')
GetPreparerLocByClientid(@Param() body: GetClientDTO) {
return this.manageClientsService.GetPreparerLocByClientid(body);
}
}

View File

@ -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 {}

View File

@ -0,0 +1,642 @@
import { Injectable } from '@nestjs/common';
import { ClientContactControlsDTO, CreateClientContactsDTO, CreateClientDataDTO, CreateClientLocationsDTO, GetClientContactByLacationIdDTO, GetClientDTO, GetPreparersDTO, UpdateClientContactsDTO, UpdateClientDTO, UpdateClientLocationsDTO } from 'src/dto/property.dto';
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus } from 'src/utils/helper';
import { PoolClient } from 'pg';
import { PgDBService } from 'src/db/db.service';
@Injectable()
export class ManageClientsService {
constructor(private readonly pgDBService: PgDBService) { }
CreateClientData = async (body: CreateClientDataDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_createclientdata($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_CLIENTNAME,
body.P_LOOKUPCODE,
body.P_ADDRESS1,
body.P_ADDRESS2,
body.P_CITY,
body.P_STATE,
body.P_ZIP,
body.P_COUNTRY,
body.P_ISSUINGREGION,
body.P_REVENUELOCATION,
body.P_USERID,
body.P_INDUSTRYTYPE,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.created,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
UpdateClient = async (body: UpdateClientDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_updateclient($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_CLIENTID,
body.P_PREPARERNAME,
body.P_ADDRESS1,
body.P_ADDRESS2,
body.P_CITY,
body.P_STATE,
body.P_ZIP,
body.P_COUNTRY,
body.P_REVENUELOCATION,
body.P_USERID,
body.P_INDUSTRYTYPE,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.updated,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
UpdateClientContacts = async (body: UpdateClientContactsDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_updateclientcontacts($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_CLIENTCONTACTID,
body.P_FIRSTNAME,
body.P_LASTNAME,
body.P_MIDDLEINITIAL,
body.P_TITLE,
body.P_PHONENO,
body.P_FAXNO,
body.P_MOBILENO,
body.P_EMAILADDRESS,
body.P_USERID,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.updated,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
UpdateClientLocations = async (body: UpdateClientLocationsDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_updateclientlocations($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_CLIENTLOCATIONID,
body.P_LOCATIONNAME,
body.P_ADDRESS1,
body.P_ADDRESS2,
body.P_CITY,
body.P_STATE,
body.P_ZIP,
body.P_COUNTRY,
body.P_USERID,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.updated,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
async CreateClientContact(body: CreateClientContactsDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
// Helper to escape special characters for Postgres composite fields
function escapePostgresCompositeField(str: string): string {
if (str == null) return '';
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
const contactLiterals = body.P_CONTACTSTABLE.map(c => {
const fields = [
c.P_FIRSTNAME || '',
c.P_LASTNAME || '',
c.P_MIDDLEINITIAL || '',
c.P_TITLE || '',
c.P_EMAILADDRESS || '',
c.P_PHONENO || '',
c.P_MOBILENO || '',
c.P_FAXNO || '',
].map(field => escapePostgresCompositeField(field)).join(',');
return `"(${fields})"`; // Composite literal wrapped in double quotes
});
const pgArrayLiteral = `{${contactLiterals.join(',')}}`;
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_createclientcontact($1, $2, $3::"CARNETSYS".contactstable[], $4, $5, $6)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_LOCATIONID,
pgArrayLiteral,
body.P_DEFCONTACTFLAG,
body.P_USERID,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.created,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
}
SetDefaultClientContacts = async (body: ClientContactControlsDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_setdefaultclientcontacts($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTCONTACTID, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 200,
message: ResponseStatus.updated,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
}
InactivateClientContacts = async (body: ClientContactControlsDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_inactivateclientcontacts($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTCONTACTID, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 200,
message: ResponseStatus.inActivate,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
}
ReactivateClientContacts = async (body: ClientContactControlsDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_reactivateclientcontacts($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTCONTACTID, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 200,
message: ResponseStatus.reActivate,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
}
CreateClientLocation = async (body: CreateClientLocationsDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
function escapePostgresCompositeField(str: string): string {
if (str == null) return '';
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
const addressLiterals = body.P_CLIENTLOCADDRESSTABLE.map(c => {
const fields = [
c.P_NAMEOF || '',
c.P_ADDRESS1 || '',
c.P_ADDRESS2 || '',
c.P_CITY || '',
c.P_STATE || '',
c.P_ZIP || '',
c.P_COUNTRY || '',
].map(field => escapePostgresCompositeField(field)).join(',');
return `"(${fields})"`; // Composite literal wrapped in double quotes
});
const pgArrayLiteral = `{${addressLiterals.join(',')}}`;
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_updateclientlocations($1, $2, $3::"CARNETSYS".addresstable[], $4, $5)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_CLIENTID,
pgArrayLiteral,
body.P_USERID,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.created,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
GetPreparers = async (body: GetPreparersDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_getpreparers($1, $2, $3, $4, $5, $6, $7)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_NAME, body.P_LOOKUPCODE, body.P_CITY, body.P_STATE, body.P_STATUS, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
GetPreparerByClientid = async (body: GetClientDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_getpreparerlocbyclientid($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
GetPreparerContactsByClientid = async (body: GetClientDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_getpreparercontactsbyclientid($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
GetPreparerContactsbyClientLocationID = async (body: GetClientContactByLacationIdDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_getpreparercontactsbyclientlocationid($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_LOCATIONID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
}
GetPreparerLocByClientid = async (body: GetClientDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".managepreparer_pkg_getpreparerlocbyclientid($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageClientsService.name)
} finally {
releasePgClient(client)
}
};
}

View File

@ -1,15 +1,21 @@
import { Body, Controller, Get, Param, Patch, Post, Put, Query } from '@nestjs/common';
import { ApiQuery } from '@nestjs/swagger';
import { Body, Controller, Get, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common';
import { ApiQuery, ApiTags } from '@nestjs/swagger';
import { CreateHolderContactsDTO, CreateHoldersDTO, GetHolderDTO, HolderActivateOrInactivateDTO, HolderContactActivateOrInactivateDTO, UpdateHolderContactDTO, UpdateHolderDTO } from 'src/dto/property.dto';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
import { ManageHolderService } from './manage-holder.service';
import { Roles } from 'src/decorators/roles.decorator';
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
import { RolesGuard } from 'src/guards/roles.guard';
@ApiTags('Manage Holders - PG')
// @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('ca', 'sa')
@Controller('manage-holder')
export class ManageHolderController {
constructor(private readonly manageHoldersService: ManageHolderService) { }
// @Get('SearchHolder/:P_SPID/:P_USERID')
@Get('SearchHolder/:P_SPID/:P_USERID')
@ApiQuery({ name: "P_HOLDERNAME", type: String, required: false, description: "Optional" })
@ApiQuery({ name: "P_HOLDERID", type: Number, required: false, description: "Optional" })
SearchHolder(
@ -51,52 +57,52 @@ export class ManageHolderController {
return this.manageHoldersService.SearchHolder(body)
}
// @Post('/CreateHolderData')
@Post('/CreateHolderData')
CreateHolders(@Body() body: CreateHoldersDTO) {
return this.manageHoldersService.CreateHolders(body);
}
// @Post('CreateHoldercontact')
@Post('CreateHoldercontact')
CreateHoldercontact(@Body() body: CreateHolderContactsDTO) {
return this.manageHoldersService.CreateHoldercontact(body);
}
// @Put('/UpdateHolder')
@Put('/UpdateHolder')
UpdateHolder(@Body() body: UpdateHolderDTO) {
return this.manageHoldersService.UpdateHolder(body);
}
// @Put('/UpdateHolderContact')
@Put('/UpdateHolderContact')
UpdateHolderContact(@Body() body: UpdateHolderContactDTO) {
return this.manageHoldersService.UpdateHolderContact(body);
}
// @Get('/GetHolderRecord/:P_SPID/:P_HOLDERID')
@Get('/GetHolderRecord/:P_SPID/:P_HOLDERID')
GetHolderMaster(@Param() body: GetHolderDTO) {
return this.manageHoldersService.GetHolderRecord(body);
}
// @Get('/GetHolderContacts/:P_SPID/:P_HOLDERID')
@Get('/GetHolderContacts/:P_SPID/:P_HOLDERID')
GetHolderContacts(@Param() body: GetHolderDTO) {
return this.manageHoldersService.GetHolderContacts(body);
}
// @Patch('/InactivateHolder/:P_SPID/:P_HOLDERID/:P_USERID')
@Patch('/InactivateHolder/:P_SPID/:P_HOLDERID/:P_USERID')
InactivateHolder(@Param() body: HolderActivateOrInactivateDTO) {
return this.manageHoldersService.InactivateHolder(body);
}
// @Patch('/ReactivateHolder/:P_SPID/:P_HOLDERID/:P_USERID')
@Patch('/ReactivateHolder/:P_SPID/:P_HOLDERID/:P_USERID')
ReactivateHolder(@Param() body: HolderActivateOrInactivateDTO) {
return this.manageHoldersService.ReactivateHolder(body);
}
// @Patch('/InactivateHolderContact/:P_SPID/:P_HOLDERCONTACTID/:P_USERID')
@Patch('/InactivateHolderContact/:P_SPID/:P_HOLDERCONTACTID/:P_USERID')
InactivateHolderContact(@Param() body: HolderContactActivateOrInactivateDTO) {
return this.manageHoldersService.InactivateHolderContact(body);
}
// @Patch('/ReactivateHolderContact/:P_SPID/:P_HOLDERCONTACTID/:P_USERID')
@Patch('/ReactivateHolderContact/:P_SPID/:P_HOLDERCONTACTID/:P_USERID')
ReactivateHolderContact(@Param() body: HolderContactActivateOrInactivateDTO) {
return this.manageHoldersService.ReactivateHolderContact(body);
}

View File

@ -1,33 +1,498 @@
import { Injectable } from '@nestjs/common';
import { PgDBService } from 'src/db/db.service';
import { CreateHolderContactsDTO, CreateHoldersDTO, GetHolderDTO, HolderActivateOrInactivateDTO, HolderContactActivateOrInactivateDTO, UpdateHolderContactDTO, UpdateHolderDTO } from 'src/dto/property.dto';
import { CONTACTSTABLE_ROW_DTO, CreateHolderContactsDTO, CreateHoldersDTO, GetHolderDTO, HolderActivateOrInactivateDTO, HolderContactActivateOrInactivateDTO, UpdateHolderContactDTO, UpdateHolderDTO } from 'src/dto/property.dto';
import { PoolClient } from 'pg';
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus } from 'src/utils/helper';
@Injectable()
export class ManageHolderService {
constructor(private readonly pgDBService: PgDBService) { }
async CreateHolders(body: CreateHoldersDTO) { }
async CreateHolders(body: CreateHoldersDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_createholderdata($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_CLIENTLOCATIONID,
body.P_HOLDERNO,
body.P_HOLDERTYPE,
body.P_USCIBMEMBERFLAG,
body.P_GOVAGENCYFLAG,
body.P_HOLDERNAME,
body.P_NAMEQUALIFIER,
body.P_ADDLNAME,
body.P_ADDRESS1,
body.P_ADDRESS2,
body.P_CITY,
body.P_STATE,
body.P_ZIP,
body.P_COUNTRY,
body.P_USERID,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.created,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
}
async CreateHoldercontact(body: CreateHolderContactsDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
// Helper to escape special characters for Postgres composite fields
function escapePostgresCompositeField(str: string): string {
if (str == null) return '';
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
UpdateHolder = async (body: UpdateHolderDTO) => { };
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
GetHolderRecord = async (body: GetHolderDTO) => { };
const contactLiterals = body.P_CONTACTSTABLE.map(c => {
const fields = [
c.P_FIRSTNAME || '',
c.P_LASTNAME || '',
c.P_MIDDLEINITIAL || '',
c.P_TITLE || '',
c.P_EMAILADDRESS || '',
c.P_PHONENO || '',
c.P_MOBILENO || '',
c.P_FAXNO || '',
].map(field => escapePostgresCompositeField(field)).join(',');
UpdateHolderContact = async (body: UpdateHolderContactDTO) => { };
GetHolderContacts = async (body: GetHolderDTO) => { };
return `"(${fields})"`; // Composite literal wrapped in double quotes
});
InactivateHolder = async (body: HolderActivateOrInactivateDTO) => { };
const pgArrayLiteral = `{${contactLiterals.join(',')}}`;
ReactivateHolder = async (body: HolderActivateOrInactivateDTO) => { };
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_createholdercontact($1, $2, $3::"CARNETSYS".contactstable[], $4, $5)
`;
InactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => { };
await client.query(callProcQuery, [
body.P_SPID,
body.P_HOLDERID,
pgArrayLiteral,
body.P_USERID,
cursorName,
]);
ReactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => { };
// Fetch results from cursor (do NOT quote cursor name)
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
SearchHolder = async (body: { P_SPID: number, P_USERID: string, P_HOLDERID: number | null, P_HOLDERNAME: string | null }) => { }
// Close cursor
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.created,
...fetchResult?.rows?.[0] || {},
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name);
} finally {
releasePgClient(client);
}
}
UpdateHolder = async (body: UpdateHolderDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_updateholder($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
`;
await client.query(callProcQuery,
[
body.P_HOLDERID,
body.P_SPID,
body.P_LOCATIONID,
body.P_HOLDERNO,
body.P_HOLDERTYPE,
body.P_USCIBMEMBERFLAG,
body.P_GOVAGENCYFLAG,
body.P_HOLDERNAME,
body.P_NAMEQUALIFIER,
body.P_ADDLNAME,
body.P_ADDRESS1,
body.P_ADDRESS2,
body.P_CITY,
body.P_STATE,
body.P_ZIP,
body.P_COUNTRY,
body.P_USERID,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.updated,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
GetHolderRecord = async (body: GetHolderDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_getholdermaster($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
UpdateHolderContact = async (body: UpdateHolderContactDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_updateholder($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
`;
await client.query(callProcQuery,
[
body.P_HOLDERCONTACTID,
body.P_SPID,
body.P_FIRSTNAME,
body.P_LASTNAME,
body.P_MIDDLEINITIAL,
body.P_TITLE,
body.P_PHONENO,
body.P_MOBILENO,
body.P_FAXNO,
body.P_EMAILADDRESS,
body.P_USERID,
cursorName
]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 201,
message: ResponseStatus.updated,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
GetHolderContacts = async (body: GetHolderDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_getholdercontacts($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
InactivateHolder = async (body: HolderActivateOrInactivateDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_inactivateholder($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 200,
message: ResponseStatus.inActivate,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
ReactivateHolder = async (body: HolderActivateOrInactivateDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_reactivateholder($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 200,
message: ResponseStatus.reActivate,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
InactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_inactivateholdercontact($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERCONTACTID, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 200,
message: ResponseStatus.inActivate,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
ReactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_reactivateholdercontact($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERCONTACTID, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return {
statusCode: 200,
message: ResponseStatus.reActivate,
...fetchResult?.rows?.[0] || {}
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
};
SearchHolder = async (body: { P_SPID: number, P_USERID: string, P_HOLDERID: number | null, P_HOLDERNAME: string | null }) => {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".manageholder_pkg_searchholder($1, $2, $3, $4, $5)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, body.P_HOLDERNAME, body.P_USERID, cursorName]);
// 🚫 DON'T quote the cursor name in FETCH
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${cursorName}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(fetchResult);
return fetchResult?.rows ? fetchResult?.rows : []
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, ManageHolderService.name)
} finally {
releasePgClient(client)
}
}
}

View File

@ -5,10 +5,11 @@ import { UscibManagedSpModule } from './uscib-managed-sp/uscib-managed-sp.module
import { UserMaintenanceModule } from './user-maintenance/user-maintenance.module';
import { ManageFeeModule } from './manage-fee/manage-fee.module';
import { ManageHolderModule } from './manage-holder/manage-holder.module';
import { ManageClientsModule } from './manage-clients/manage-clients.module';
@Global()
@Module({
imports: [DbModule, ParamTableModule, UscibManagedSpModule, UserMaintenanceModule, ManageFeeModule, ManageHolderModule],
imports: [DbModule, ParamTableModule, UscibManagedSpModule, UserMaintenanceModule, ManageFeeModule, ManageHolderModule, ManageClientsModule],
providers: [],
exports: [UserMaintenanceModule]
})