import { Injectable, Logger } from '@nestjs/common'; import { OracleDBService } from 'src/db/db.service'; import * as oracledb from 'oracledb'; import { BadRequestException } from 'src/exceptions/badRequest.exception'; import { InternalServerException } from 'src/exceptions/internalServerError.exception'; import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/helper'; import { CLIENTLOCADDRESSTABLE_ROW_DTO, CreateClientContactsDTO, CreateClientDataDTO, CreateClientLocationsDTO, GetPreparerByClientidContactsByClientidLocByClientidDTO, GetPreparersDTO, UpdateClientContactsDTO, UpdateClientDTO, UpdateClientLocationsDTO, CONTACTSTABLE_ROW_DTO } from 'src/dto/property.dto'; @Injectable() export class ManageClientsService { private readonly logger = new Logger(ManageClientsService.name); constructor(private readonly oracleDBService: OracleDBService) { } CreateClientData = async (body: CreateClientDataDTO) => { const newBody = { P_SPID: null, P_CLIENTNAME: null, P_LOOKUPCODE: null, P_ADDRESS1: null, P_ADDRESS2: null, P_CITY: null, P_STATE: null, P_ZIP: null, P_COUNTRY: null, P_ISSUINGREGION: null, P_REVENUELOCATION: null, P_USERID: null, }; const 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_CLIENTCURSOR_ROWS: any = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.CreateClientData( :P_SPID, :P_CLIENTNAME, :P_LOOKUPCODE, :P_ADDRESS1, :P_ADDRESS2, :P_CITY, :P_STATE, :P_ZIP, :P_COUNTRY, :P_ISSUINGREGION, :P_REVENUELOCATION, :P_USERID, :P_CLIENTCURSOR ); END;`, { P_SPID: { val: finalBody.P_SPID ? finalBody.P_SPID : null, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTNAME: { val: finalBody.P_CLIENTNAME ? finalBody.P_CLIENTNAME : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_LOOKUPCODE: { val: finalBody.P_LOOKUPCODE ? finalBody.P_LOOKUPCODE : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ADDRESS1: { val: finalBody.P_ADDRESS1 ? finalBody.P_ADDRESS1 : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ADDRESS2: { val: finalBody.P_ADDRESS2 ? finalBody.P_ADDRESS2 : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_CITY: { val: finalBody.P_CITY ? finalBody.P_CITY : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_STATE: { val: finalBody.P_STATE ? finalBody.P_STATE : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ZIP: { val: finalBody.P_ZIP ? finalBody.P_ZIP : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_COUNTRY: { val: finalBody.P_COUNTRY ? finalBody.P_COUNTRY : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ISSUINGREGION: { val: finalBody.P_ISSUINGREGION ? finalBody.P_ISSUINGREGION : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_REVENUELOCATION: { val: finalBody.P_REVENUELOCATION ? finalBody.P_REVENUELOCATION : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_USERID: { val: finalBody.P_USERID ? finalBody.P_USERID : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_CLIENTCURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, } }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); await connection.commit(); if (result.outBinds && result.outBinds.P_CLIENTCURSOR) { const cursor = result.outBinds.P_CLIENTCURSOR; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CLIENTCURSOR_ROWS = P_CLIENTCURSOR_ROWS.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } else { throw new Error('No cursor returned from the stored procedure'); } if (P_CLIENTCURSOR_ROWS.length > 0 && P_CLIENTCURSOR_ROWS[0].ERRORMESG) { throw new BadRequestException(P_CLIENTCURSOR_ROWS[0].ERRORMESG); } return { statusCode: 201, message: "Created Successfully" }; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('CREATECLIENTDATA failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; UpdateClient = async (body: UpdateClientDTO) => { const newBody = { P_SPID: null, P_CLIENTID: null, P_PREPARERNAME: null, P_ADDRESS1: null, P_ADDRESS2: null, P_CITY: null, P_STATE: null, P_ZIP: null, P_COUNTRY: null, P_REVENUELOCATION: null, P_USERID: null, }; const 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: UpdateClientDTO = { ...newBody, ...reqBody }; let connection; let P_CURSOR_rows: any = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.UpdateClient( :P_SPID, :P_CLIENTID, :P_PREPARERNAME, :P_ADDRESS1, :P_ADDRESS2, :P_CITY, :P_STATE, :P_ZIP, :P_COUNTRY, :P_REVENUELOCATION, :P_USERID, :P_CURSOR ); END;`, { P_SPID: { val: finalBody.P_SPID ? finalBody.P_SPID : null, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTID: { val: finalBody.P_CLIENTID ? finalBody.P_CLIENTID : null, type: oracledb.DB_TYPE_NUMBER, }, P_PREPARERNAME: { val: finalBody.P_PREPARERNAME ? finalBody.P_PREPARERNAME : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ADDRESS1: { val: finalBody.P_ADDRESS1 ? finalBody.P_ADDRESS1 : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ADDRESS2: { val: finalBody.P_ADDRESS2 ? finalBody.P_ADDRESS2 : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_CITY: { val: finalBody.P_CITY ? finalBody.P_CITY : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_STATE: { val: finalBody.P_STATE ? finalBody.P_STATE : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ZIP: { val: finalBody.P_ZIP ? finalBody.P_ZIP : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_COUNTRY: { val: finalBody.P_COUNTRY ? finalBody.P_COUNTRY : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_REVENUELOCATION: { val: finalBody.P_REVENUELOCATION ? finalBody.P_REVENUELOCATION : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_USERID: { val: finalBody.P_USERID ? finalBody.P_USERID : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); await connection.commit(); if (result.outBinds && result.outBinds.P_CURSOR) { const cursor = result.outBinds.P_CURSOR; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } else { throw new Error('No cursor returned from the stored procedure'); } if (P_CURSOR_rows.length > 0 && P_CURSOR_rows[0].ERRORMESG) { throw new BadRequestException(P_CURSOR_rows[0].ERRORMESG); } return { statusCode: 200, message: "Updated Successfully" }; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('UpdateClient failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; UpdateClientContacts = async (body: UpdateClientContactsDTO) => { const newBody = { P_SPID: null, P_CLIENTCONTACTID: null, P_FIRSTNAME: null, P_LASTNAME: null, P_MIDDLEINITIAL: null, P_TITLE: null, P_PHONENO: null, P_FAXNO: null, P_MOBILENO: null, P_EMAILADDRESS: null, P_USERID: null, }; const 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: UpdateClientContactsDTO = { ...newBody, ...reqBody }; let connection; let P_CURSOR_rows: any = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.UpdateClientContacts( :P_SPID, :P_CLIENTCONTACTID, :P_FIRSTNAME, :P_LASTNAME, :P_MIDDLEINITIAL, :P_TITLE, :P_PHONENO, :P_FAXNO, :P_MOBILENO, :P_EMAILADDRESS, :P_USERID, :P_cursor ); END;`, { P_SPID: { val: finalBody.P_SPID ? finalBody.P_SPID : null, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTCONTACTID: { val: finalBody.P_CLIENTCONTACTID ? finalBody.P_CLIENTCONTACTID : null, type: oracledb.DB_TYPE_NUMBER, }, P_FIRSTNAME: { val: finalBody.P_FIRSTNAME ? finalBody.P_FIRSTNAME : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_LASTNAME: { val: finalBody.P_LASTNAME ? finalBody.P_LASTNAME : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_MIDDLEINITIAL: { val: finalBody.P_MIDDLEINITIAL ? finalBody.P_MIDDLEINITIAL : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_TITLE: { val: finalBody.P_TITLE ? finalBody.P_TITLE : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_PHONENO: { val: finalBody.P_PHONENO ? finalBody.P_PHONENO : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_FAXNO: { val: finalBody.P_FAXNO ? finalBody.P_FAXNO : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_MOBILENO: { val: finalBody.P_MOBILENO ? finalBody.P_MOBILENO : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_EMAILADDRESS: { val: finalBody.P_EMAILADDRESS ? finalBody.P_EMAILADDRESS : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_USERID: { val: finalBody.P_USERID ? finalBody.P_USERID : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); await connection.commit(); if (result.outBinds && result.outBinds.P_cursor) { const cursor = result.outBinds.P_cursor; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } else { throw new Error('No cursor returned from the stored procedure'); } if (P_CURSOR_rows.length > 0 && P_CURSOR_rows[0].ERRORMESG) { throw new BadRequestException(P_CURSOR_rows[0].ERRORMESG); } return { statusCode: 200, message: "Updated Successfully" }; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('UpdateClientContacts failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; UpdateClientLocations = async (body: UpdateClientLocationsDTO) => { const newBody = { P_SPID: null, P_CLIENTLOCATIONID: null, P_LOCATIONNAME: null, P_ADDRESS1: null, P_ADDRESS2: null, P_CITY: null, P_STATE: null, P_ZIP: null, P_COUNTRY: null, P_USERID: null, }; const 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: UpdateClientLocationsDTO = { ...newBody, ...reqBody }; let connection; let P_CURSOR_rows: any = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.UpdateClientLocations( :P_SPID, :P_CLIENTLOCATIONID, :P_LOCATIONNAME, :P_ADDRESS1, :P_ADDRESS2, :P_CITY, :P_STATE, :P_ZIP, :P_COUNTRY, :P_USERID, :P_CURSOR ); END;`, { P_SPID: { val: finalBody.P_SPID ? finalBody.P_SPID : null, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTLOCATIONID: { val: finalBody.P_CLIENTLOCATIONID ? finalBody.P_CLIENTLOCATIONID : null, type: oracledb.DB_TYPE_NUMBER, }, P_LOCATIONNAME: { val: finalBody.P_LOCATIONNAME ? finalBody.P_LOCATIONNAME : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ADDRESS1: { val: finalBody.P_ADDRESS1 ? finalBody.P_ADDRESS1 : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ADDRESS2: { val: finalBody.P_ADDRESS2 ? finalBody.P_ADDRESS2 : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_CITY: { val: finalBody.P_CITY ? finalBody.P_CITY : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_STATE: { val: finalBody.P_STATE ? finalBody.P_STATE : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_ZIP: { val: finalBody.P_ZIP ? finalBody.P_ZIP : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_COUNTRY: { val: finalBody.P_COUNTRY ? finalBody.P_COUNTRY : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_USERID: { val: finalBody.P_USERID ? finalBody.P_USERID : null, type: oracledb.DB_TYPE_NVARCHAR, }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); await connection.commit(); if (result.outBinds && result.outBinds.P_CURSOR) { const cursor = result.outBinds.P_CURSOR; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } else { throw new Error('No cursor returned from the stored procedure'); } if (P_CURSOR_rows.length > 0 && P_CURSOR_rows[0].ERRORMESG) { throw new BadRequestException(P_CURSOR_rows[0].ERRORMESG); } return { statusCode: 200, message: "Updated Successfully" }; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('UpdateClientLocations failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; // CreateClientContactX = async (body: CreateClientContactsDTO) => { // const newBody = { // P_SPID: null, // P_CLIENTID: null, // p_contactstable: null, // p_defcontactflag: null, // P_USERID: null, // }; // const 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: CreateClientContactsDTO = { // ...newBody, // ...reqBody, // }; // let connection; // let P_CURSOR_rows: any = []; // try { // connection = await this.oracleDBService.getConnection(); // if (!connection) { // throw new InternalServerException('No DB Connected'); // } // const CONTACTSTABLE = await connection.getDbObjectClass( // 'CARNETSYS.CONTACTSTABLE', // ); // // Check if CONTACTSTABLE is a constructor // if (typeof CONTACTSTABLE !== 'function') { // throw new InternalServerException('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 // MANAGEPREPARER_PKG.CreateClientContact( // :P_SPID, // :P_CLIENTID, // :p_contactstable, // :p_defcontactflag, // :P_USERID, // :P_CURSOR // ); // END;`, // { // P_SPID: { // val: finalBody.P_SPID, // type: oracledb.DB_TYPE_NUMBER, // }, // P_CLIENTID: { // val: finalBody.P_CLIENTID, // type: oracledb.DB_TYPE_NUMBER, // }, // p_contactstable: { // val: CONTACTSTABLE_INSTANCE, // type: oracledb.DB_TYPE_OBJECT, // }, // p_defcontactflag: { // val: finalBody.p_defcontactflag, // type: oracledb.DB_TYPE_NVARCHAR, // }, // P_USERID: { // val: finalBody.P_USERID, // type: oracledb.DB_TYPE_NVARCHAR, // }, // P_CURSOR: { // type: oracledb.CURSOR, // dir: oracledb.BIND_OUT, // }, // }, // { // outFormat: oracledb.OUT_FORMAT_OBJECT, // }, // ); // await connection.commit(); // if (result.outBinds && result.outBinds.P_CURSOR) { // const cursor = result.outBinds.P_CURSOR; // let rowsBatch; // do { // rowsBatch = await cursor.getRows(100); // P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); // } while (rowsBatch.length > 0); // await cursor.close(); // } else { // throw new InternalServerException('No cursor returned from the stored procedure'); // } // if (P_CURSOR_rows.length > 0 && P_CURSOR_rows[0].ERRORMESG) { // throw new BadRequestException(P_CURSOR_rows[0].ERRORMESG); // } // return { statusCode: 201, message: "Created Successfully" }; // } catch (error) { // if (error instanceof BadRequestException) { // this.logger.warn(error.message); // throw error; // } // this.logger.error('CreateClientContact failed', error.stack || error); // throw new InternalServerException(); // } finally { // if (connection) { // try { // await connection.close(); // } catch (closeErr) { // this.logger.error('Failed to close DB connection', closeErr); // } // } // } // }; async CreateClientContact(body: CreateClientContactsDTO) { const newBody = { P_SPID: null, P_CLIENTID: null, P_CONTACTSTABLE: null, P_DEFCONTACTFLAG: null, P_USERID: null, }; const 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: CreateClientContactsDTO = { ...newBody, ...reqBody }; let connection; try { connection = await this.oracleDBService.getConnection(); const CONTACTSTABLE = await connection.getDbObjectClass( 'CARNETSYS.CONTACTSTABLE', ); // Check if CONTACTSTABLE is a constructor if (typeof CONTACTSTABLE !== 'function') { throw new InternalServerException('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: CONTACTSTABLE_ROW_DTO) => { return await CREATECONTACTSTABLE_INSTANCE( connection, x.P_FIRSTNAME, x.P_LASTNAME, x.P_MIDDLEINITIAL, x.P_TITLE, x.P_EMAILADDRESS, x.P_PHONENO, x.P_MOBILENO, x.P_FAXNO, ); }), ) : []; // Create an instance of GLTABLE const CONTACTSTABLE_INSTANCE = new CONTACTSTABLE(CONTACTSARRAY); const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.CreateClientContact( :P_SPID, :P_CLIENTID, :P_CONTACTSTABLE, :P_DEFCONTACTFLAG, :P_USERID, :P_CURSOR ); END;`, { P_SPID: { val: finalBody.P_SPID, type: oracledb.DB_TYPE_NUMBER }, P_CLIENTID: { val: finalBody.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER }, P_CONTACTSTABLE: { val: CONTACTSTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT }, P_DEFCONTACTFLAG: { val: finalBody.P_DEFCONTACTFLAG, type: oracledb.DB_TYPE_NVARCHAR }, P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); await connection.commit(); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } return await fetchCursor(outBinds.P_CURSOR, ManageClientsService.name); } catch (error) { handleError(error, ManageClientsService.name) } finally { await closeOracleDbConnection(connection, ManageClientsService.name) } } CreateClientLocation = async (body: CreateClientLocationsDTO) => { const newBody = { P_SPID: null, P_CLIENTID: null, p_clientlocaddresstable: null, P_USERID: null, }; const 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: CreateClientLocationsDTO = { ...newBody, ...reqBody, }; let connection; let P_CURSOR_rows: any = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const CLIENTLOCADDRESSTABLE = await connection.getDbObjectClass( 'CARNETSYS.CLIENTLOCADDRESSTABLE', ); if (typeof CLIENTLOCADDRESSTABLE !== 'function') { throw new Error('CLIENTLOCADDRESSTABLE is not a constructor'); } async function CREATECLIENTLOCADDRESSTABLE_INSTANCE( connection, Nameof, Address1, Address2, City, State, Zip, Country, ) { const result = await connection.execute( `SELECT CARNETSYS.CLIENTLOCADDRESSARRAY(:Nameof, :Address1, :Address2, :City, :State, :Zip, :Country) FROM dual`, { Nameof, Address1, Address2, City, State, Zip, Country, }, ); return result.rows[0][0]; } const CLIENTLOCADDRESSARRAY = finalBody.P_CLIENTLOCADDRESSTABLE ? await Promise.all( finalBody.P_CLIENTLOCADDRESSTABLE.map( async (x: CLIENTLOCADDRESSTABLE_ROW_DTO) => { return await CREATECLIENTLOCADDRESSTABLE_INSTANCE( connection, x.P_NAMEOF, x.P_ADDRESS1, x.P_ADDRESS2, x.P_CITY, x.P_CITY, x.P_ZIP, x.P_COUNTRY, ); }, ), ) : []; const CLIENTLOCADDRESSTABLE_INSTANCE = new CLIENTLOCADDRESSTABLE( CLIENTLOCADDRESSARRAY, ); const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.CreateClientLocation( :P_SPID, :P_CLIENTID, :p_ClientLocAddressTable, :P_USERID, :P_CURSOR ); END;`, { P_SPID: { val: finalBody.P_SPID, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTID: { val: finalBody.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER, }, p_clientlocaddresstable: { val: CLIENTLOCADDRESSTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT, }, P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR, }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, } }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); await connection.commit(); if (result.outBinds && result.outBinds.P_CURSOR) { const cursor = result.outBinds.P_CURSOR; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } else { throw new Error('No cursor returned from the stored procedure'); } if (P_CURSOR_rows.length > 0 && P_CURSOR_rows[0].ERRORMESG) { throw new BadRequestException(P_CURSOR_rows[0].ERRORMESG); } return { statusCode: 201, message: "Created Successfully" }; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('CreateClientLocation failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; GetPreparers = async (body: GetPreparersDTO) => { let connection; let p_maincursor_rows = []; // let p_contactscursor_rows = []; // let p_locationcursor_rows = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new InternalServerException(); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.GetPreparers( :P_SPID, :P_NAME, :P_LOOKUPCODE, :P_CITY, :P_STATE, :P_STATUS, :p_maincursor ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER, }, P_NAME: { val: body.P_NAME, type: oracledb.DB_TYPE_NVARCHAR, }, P_LOOKUPCODE: { val: body.P_LOOKUPCODE, type: oracledb.DB_TYPE_NVARCHAR, }, P_CITY: { val: body.P_CITY, type: oracledb.DB_TYPE_NVARCHAR, }, P_STATE: { val: body.P_STATE, type: oracledb.DB_TYPE_NVARCHAR, }, P_STATUS: { val: body.P_STATUS, type: oracledb.DB_TYPE_NVARCHAR, }, p_maincursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, } }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); if (result.outBinds && result.outBinds.p_maincursor) { const cursor = result.outBinds.p_maincursor; let rowsBatch; do { rowsBatch = await cursor.getRows(100); p_maincursor_rows = p_maincursor_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } return p_maincursor_rows; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('GetPreparers failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; GetPreparerByClientid = async ( body: GetPreparerByClientidContactsByClientidLocByClientidDTO, ) => { let connection; let P_CURSOR_rows: any = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.GetPreparerByClientid( :P_SPID, :P_CLIENTID, :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTID: { val: body.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER, }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); if (result.outBinds && result.outBinds.P_CURSOR) { const cursor = result.outBinds.P_CURSOR; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } return P_CURSOR_rows; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('GetPreparerByClientid failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; GetPreparerContactsByClientid = async ( body: GetPreparerByClientidContactsByClientidLocByClientidDTO, ) => { let connection; let P_CURSOR_rows = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.GetPreparerContactsByClientid( :P_SPID, :P_CLIENTID, :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTID: { val: body.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER, }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); if (result.outBinds && result.outBinds.P_CURSOR) { const cursor = result.outBinds.P_CURSOR; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } return P_CURSOR_rows; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('GetPreparerContactsByClientid failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; GetPreparerLocByClientid = async ( body: GetPreparerByClientidContactsByClientidLocByClientidDTO, ) => { let connection; let P_CURSOR_rows = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new Error('No DB Connected'); } const result = await connection.execute( `BEGIN MANAGEPREPARER_PKG.GetPreparerLocByClientid( :P_SPID, :P_CLIENTID, :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER, }, P_CLIENTID: { val: body.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER, }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); if (result.outBinds && result.outBinds.P_CURSOR) { const cursor = result.outBinds.P_CURSOR; let rowsBatch; do { rowsBatch = await cursor.getRows(100); P_CURSOR_rows = P_CURSOR_rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } return P_CURSOR_rows; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('GetPreparerLocByClientid failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } }; }