BE/src/pg/user-maintenance/user-maintenance.service.ts
2025-09-27 16:36:01 +05:30

591 lines
19 KiB
TypeScript

import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
import { CreateClientLoginsDTO, CreateSPLoginsDTO, CreateUSCIBLoginsDTO, EMAIL_DTO, GetCarnetDetailsbyCarnetStatusDTO, SPID_CLIENTID_DTO, SPID_DTO, SPID_EMAIL_DTO, USERID_DTO } from 'src/dto/property.dto';
import { checkPgUserDefinedErrors, extractSubdomain, handlePgError, normalizeKeysToUpperCase, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
import { PoolClient } from 'pg';
import { PgDBService } from 'src/db/db.service';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import { AuthService } from 'src/auth/auth.service';
import { MailTypeDTO } from 'src/auth/auth.dto';
import { Request } from 'express';
@Injectable()
export class UserMaintenanceService {
private readonly logger = new Logger(UserMaintenanceService.name);
constructor(
private readonly pgDBService: PgDBService,
@Inject(forwardRef(() => AuthService))
private readonly authService: AuthService
) { }
async GetSPUserDetails(body: USERID_DTO): Promise<any> {
let client: PoolClient | null = null;
// Assign unique names to each cursor
const roleCursor = 'role_cursor';
const menuCursor = 'menu_cursor';
const menuPageCursor = 'menu_page_cursor';
const userDetailsCursor = 'user_details_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".spclientuser_pkg_getspuserdetails($1, $2, $3, $4, $5)
`;
await client.query(callProcQuery, [
body.P_USERID,
roleCursor,
menuCursor,
menuPageCursor,
userDetailsCursor
]);
// Fetch all data from each cursor
const roleResult = await client.query(`FETCH ALL FROM ${roleCursor}`);
const menuResult = await client.query(`FETCH ALL FROM ${menuCursor}`);
const menuPageResult = await client.query(`FETCH ALL FROM ${menuPageCursor}`);
const userDetailsResult = await client.query(`FETCH ALL FROM ${userDetailsCursor}`);
// Close all cursors
await client.query(`CLOSE ${roleCursor}`);
await client.query(`CLOSE ${menuCursor}`);
await client.query(`CLOSE ${menuPageCursor}`);
await client.query(`CLOSE ${userDetailsCursor}`);
await client.query('COMMIT');
// no need for this api
// checkPgUserDefinedErrors(roleResult);
// checkPgUserDefinedErrors(menuResult);
// checkPgUserDefinedErrors(menuPageResult);
// checkPgUserDefinedErrors(userDetailsResult);
return {
roleDetails: toUpperCaseKeys(roleResult.rows).map(x => x.ROLENAME),
menuDetails: toUpperCaseKeys(menuResult.rows).map(x => x.MENUNAME),
menuPageDetails: toUpperCaseKeys(menuPageResult.rows),
userDetails: toUpperCaseKeys(userDetailsResult.rows)[0],
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, 'getSpUserDetails');
} finally {
releasePgClient(client);
}
}
async LockUserAccount(body: SPID_EMAIL_DTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_lockuseraccount($1, $2, $3)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_EMAILADDR,
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.lockedUserDone,
// ...toUpperCaseKeys(fetchResult?.rows)[0]
// };
return toUpperCaseKeys(fetchResult?.rows)
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
// USCIB_LOGINS
async GetUSCIBLogins() {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_getusciblogins($1)
`;
await client.query(callProcQuery, [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 toUpperCaseKeys(fetchResult.rows);
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
async CreateUSCIBLogins(body: CreateUSCIBLoginsDTO, req: Request) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_createusciblogins($1, $2, $3, $4, $5)
`;
await client.query(callProcQuery,
[
body.P_USERID,
body.P_EMAILADDR,
body.P_LOOKUPCODE,
body.P_ENABLEPASSWORDPOLICY,
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);
let appDomain;
if (req.headers.origin) {
appDomain = extractSubdomain(req.headers.origin)
}
else {
appDomain = ""
}
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_USCIB }, appDomain)
if (mailRes.statusCode !== 200) {
throw new InternalServerException();
}
return {
statusCode: 201,
message: ResponseStatus.created,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
// SP LOGINS
async GetSPLogins(body: SPID_DTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_getsplogins($1, $2)
`;
await client.query(callProcQuery, [body.P_SPID, 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 toUpperCaseKeys(fetchResult.rows);
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
async CreateSPLogins(body: CreateSPLoginsDTO, req: Request) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_createsplogins($1, $2, $3, $4, $5, $6, $7)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_USERID,
body.P_DOMAIN,
body.P_EMAILADDR,
body.P_LOOKUPCODE,
body.P_ENABLEPASSWORDPOLICY,
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);
let appDomain;
if (req.headers.origin) {
appDomain = extractSubdomain(req.headers.origin)
}
else {
appDomain = ""
}
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_SP }, appDomain)
if (mailRes.statusCode !== 200) {
throw new InternalServerException();
}
return {
statusCode: 201,
message: ResponseStatus.created,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
// CLIENT LOGINS
async GetClientloginsBySPID(body: SPID_DTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_getclientloginsbyspid($1, $2)
`;
await client.query(callProcQuery, [body.P_SPID, 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 toUpperCaseKeys(fetchResult.rows);
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
async GetClientloginsByClientID(body: SPID_CLIENTID_DTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_getclientloginsbyclientid($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 toUpperCaseKeys(fetchResult.rows);
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
async CreateClientLogins(body: CreateClientLoginsDTO, req: Request) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_createclientlogins($1, $2, $3, $4, $5)
`;
await client.query(callProcQuery,
[
body.P_SPID,
body.P_USERID,
body.P_CLIENTCONTACTID,
body.P_ENABLEPASSWORDPOLICY,
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);
let appDomain;
if (req.headers.origin) {
appDomain = extractSubdomain(req.headers.origin)
}
else {
appDomain = ""
}
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_CLIENT }, appDomain)
if (mailRes.statusCode !== 200) {
throw new InternalServerException();
}
return {
statusCode: 201,
message: ResponseStatus.clientRegistrationDone,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
// validate email
async ValidateEmail(body: EMAIL_DTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_validateemail($1, $2)
`;
await client.query(callProcQuery, [body.P_EMAILADDR, 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);
if (fetchResult?.rows.length > 0) {
return toUpperCaseKeys(fetchResult.rows)
}
else {
return [];
}
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
//carnet summary data
async GetCarnetSummaryData(body: USERID_DTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".userlogin_pkg_getcarnetsummarydata($1, $2)
`;
await client.query(callProcQuery, [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);
const fres: any = toUpperCaseKeys(fetchResult.rows);
// Step 1: Replace spaces in keys
const mappedRows = fres.map((obj) => {
const newObj = {};
for (const key in obj) {
const newKey = key.replace(/ /g, '_');
newObj[newKey] = obj[key];
}
return newObj;
});
// Step 2: Group and aggregate
const reducedRows = mappedRows.reduce((acc, curr) => {
let existing;
if (curr.SERVICE_PROVIDER_NAME && curr.SPID) {
existing = acc.find(
(item) =>
item.SERVICE_PROVIDER_NAME === curr.SERVICE_PROVIDER_NAME &&
item.SPID === curr.SPID
);
} else if (curr.PREPARER_NAME && curr.CLIENTID) {
existing = acc.find(
(item) =>
item.PREPARER_NAME === curr.PREPARER_NAME &&
item.CLIENTID === curr.CLIENTID
);
}
if (existing) {
existing.CARNETSTATUS.push(curr.CARNETSTATUS);
existing.CARNET_COUNT.push(curr.CARNET_COUNT);
} else {
const newItem = {
CARNETSTATUS: [curr.CARNETSTATUS],
Carnet_Count: [curr.CARNET_COUNT],
};
if (curr.SERVICE_PROVIDER_NAME && curr.SPID) {
newItem['SERVICE_PROVIDER_NAME'] = curr.SERVICE_PROVIDER_NAME;
newItem['SPID'] = curr.SPID;
} else if (curr.PREPARER_NAME && curr.CLIENTID) {
newItem['PREPARER_NAME'] = curr.PREPARER_NAME;
newItem['CLIENTID'] = curr.CLIENTID;
}
acc.push(newItem);
}
return acc;
}, []);
return reducedRows;
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, UserMaintenanceService.name)
} finally {
releasePgClient(client)
}
}
}