import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common'; import { CreateClientLoginsDTO, CreateSPLoginsDTO, CreateUSCIBLoginsDTO, EMAIL_DTO, SPID_CLIENTID_DTO, SPID_DTO, SPID_EMAIL_DTO, USERID_DTO } from 'src/dto/property.dto'; import { checkPgUserDefinedErrors, 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'; @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 { 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'); checkPgUserDefinedErrors(roleResult); checkPgUserDefinedErrors(menuResult); checkPgUserDefinedErrors(menuPageResult); checkPgUserDefinedErrors(userDetailsResult); return { roleDetails: toUpperCaseKeys(roleResult.rows), menuDetails: toUpperCaseKeys(menuResult.rows), menuPageDetails: toUpperCaseKeys(menuPageResult.rows), userDetails: toUpperCaseKeys(userDetailsResult.rows), }; } 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] }; } 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) { 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); 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) { 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); const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_SP }) 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) { 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); const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_CLIENT }) 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)[0]] } 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); return toUpperCaseKeys(fetchResult.rows); } catch (error) { if (client) await client.query('ROLLBACK'); handlePgError(error, UserMaintenanceService.name) } finally { releasePgClient(client) } } }