diff --git a/src/pg/carnet-application/carnet-application.service.ts b/src/pg/carnet-application/carnet-application.service.ts index bb148ee..df487bf 100644 --- a/src/pg/carnet-application/carnet-application.service.ts +++ b/src/pg/carnet-application/carnet-application.service.ts @@ -123,7 +123,7 @@ export class CarnetApplicationService { await client.query('BEGIN'); const callProcQuery = ` - CALL "CARNETSYS".carnetapplication_pkg_createapplication($1, $2, $3) + CALL "CARNETSYS".carnetapplication_pkg_updateholder($1, $2, $3) `; await client.query(callProcQuery, [body.P_HEADERID, body.P_HOLDERID, cursorName]); @@ -150,12 +150,275 @@ export class CarnetApplicationService { } } - async UpdateExpGoodsAuthRep(body: UpdateExpGoodsAuthRepDTO) { } - async AddGenerallistItems(body: AddGenerallistItemsDTO) { } - async EditGenerallistItems(body: AddGenerallistItemsDTO) { } - async DeleteGenerallistItems(body: DeleteGenerallistItemsDTO) { } - async AddCountries(body: AddCountriesDTO) { } + async UpdateExpGoodsAuthRep(body: UpdateExpGoodsAuthRepDTO) { + let client: PoolClient | null = null; + + const cursorName = 'p_cursor'; + + try { + client = await this.pgDBService.getConnection(); + + await client.query('BEGIN'); + + const callProcQuery = ` + CALL "CARNETSYS".carnetapplication_pkg_updateexpgoodsauthrep($1, $2, $3, $4, $5, $6, $7, $8) + `; + await client.query(callProcQuery, [body.P_HEADERID, body.P_COMMERCIALSAMPLEFLAG, body.P_PROFEQUIPMENTFLAG, body.P_EXHIBITIONSFAIRFLAG, body.P_AUTOFLAG, body.P_HORSEFLAG, body.P_AUTHREP, 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, CarnetApplicationService.name) + } finally { + releasePgClient(client) + } + } + + async AddGenerallistItems(body: AddGenerallistItemsDTO) { + let client: PoolClient | null = null; + + const cursorName = 'p_cursor'; + + try { + client = await this.pgDBService.getConnection(); + + await client.query('BEGIN'); + + function escapePostgresString(str: string): string { + if (str == null) return ''; + return `"${str.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`; + } + + function escapePostgresValue(val: any): string { + if (val == null || val === '') return ''; // NULL or empty becomes empty string + if (typeof val === 'number') return String(val); // pass numbers as-is + return escapePostgresString(String(val)); // quote and escape strings + } + + const contactLiterals = body.P_GLTABLE.map(c => { + const fields = [ + escapePostgresValue(c.ITEMNO), // integer + escapePostgresValue(c.ITEMDESCRIPTION), // varchar + escapePostgresValue(c.ITEMVALUE), // numeric + escapePostgresValue(c.NOOFPIECES), // integer + escapePostgresValue(c.ITEMWEIGHT), // numeric + escapePostgresValue(c.ITEMWEIGHTUOM), // varchar + escapePostgresValue(c.GOODSORIGINCOUNTRY), // varchar + ]; + + return `(${fields.join(',')})`; // composite literal without outer double quotes + }); + + const pgArrayLiteral = `{${contactLiterals.join(',')}}`; + + const callProcQuery = ` + CALL "CARNETSYS".carnetapplication_pkg_addgenerallistitems($1, $2::"CARNETSYS".gltable[], $3, $4) + `; + await client.query(callProcQuery, [body.P_HEADERID, 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: 200, + message: ResponseStatus.added, + ...fetchResult?.rows?.[0] || {} + }; + + } catch (error) { + if (client) await client.query('ROLLBACK'); + handlePgError(error, CarnetApplicationService.name) + } finally { + releasePgClient(client) + } + } + + async EditGenerallistItems(body: AddGenerallistItemsDTO) { + let client: PoolClient | null = null; + + const cursorName = 'p_cursor'; + + try { + client = await this.pgDBService.getConnection(); + + await client.query('BEGIN'); + + function escapePostgresString(str: string): string { + if (str == null) return ''; + return `"${str.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`; + } + + function escapePostgresValue(val: any): string { + if (val == null || val === '') return ''; // NULL or empty becomes empty string + if (typeof val === 'number') return String(val); // pass numbers as-is + return escapePostgresString(String(val)); // quote and escape strings + } + + const contactLiterals = body.P_GLTABLE.map(c => { + const fields = [ + escapePostgresValue(c.ITEMNO), // integer + escapePostgresValue(c.ITEMDESCRIPTION), // varchar + escapePostgresValue(c.ITEMVALUE), // numeric + escapePostgresValue(c.NOOFPIECES), // integer + escapePostgresValue(c.ITEMWEIGHT), // numeric + escapePostgresValue(c.ITEMWEIGHTUOM), // varchar + escapePostgresValue(c.GOODSORIGINCOUNTRY), // varchar + ]; + + return `(${fields.join(',')})`; // composite literal without outer double quotes + }); + + const pgArrayLiteral = `{${contactLiterals.join(',')}}`; + + const callProcQuery = ` + CALL "CARNETSYS".carnetapplication_pkg_editgenerallistitems($1, $2::"CARNETSYS".gltable[], $3, $4) + `; + await client.query(callProcQuery, [body.P_HEADERID, 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: 200, + message: ResponseStatus.updated, + ...fetchResult?.rows?.[0] || {} + }; + + } catch (error) { + if (client) await client.query('ROLLBACK'); + handlePgError(error, CarnetApplicationService.name) + } finally { + releasePgClient(client) + } + } + + async DeleteGenerallistItems(body: DeleteGenerallistItemsDTO) { + let client: PoolClient | null = null; + + const cursorName = 'p_cursor'; + + try { + client = await this.pgDBService.getConnection(); + + await client.query('BEGIN'); + + const callProcQuery = ` + CALL "CARNETSYS".carnetapplication_pkg_deletegenerallistitems($1, $2, $3, $4) + `; + await client.query(callProcQuery, [body.P_HEADERID, body.P_ITEMNO, 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.deleted, + ...fetchResult?.rows?.[0] || {} + }; + + } catch (error) { + if (client) await client.query('ROLLBACK'); + handlePgError(error, CarnetApplicationService.name) + } finally { + releasePgClient(client) + } + } + + async AddCountries(body: AddCountriesDTO) { + let client: PoolClient | null = null; + + const cursorName = 'p_cursor'; + + try { + client = await this.pgDBService.getConnection(); + + await client.query('BEGIN'); + + function escapePostgresString(str: string): string { + if (str == null) return ''; + return `"${str.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`; + } + + function escapePostgresValue(val: any): string { + if (val == null || val === '') return ''; // NULL or empty becomes empty string + if (typeof val === 'number') return String(val); // pass numbers as-is + return escapePostgresString(String(val)); // quote and escape strings + } + + const contactLiterals = body.P_COUNTRYTABLE.map(c => { + const fields = [ + escapePostgresValue(c.P_VISISTTRANSITIND), // integer + escapePostgresValue(c.COUNTRYCODE), // varchar + escapePostgresValue(c.NOOFTIMESENTLEAVE), // numeric + ]; + + return `(${fields.join(',')})`; // composite literal without outer double quotes + }); + + const pgArrayLiteral = `{${contactLiterals.join(',')}}`; + + const callProcQuery = ` + CALL "CARNETSYS".carnetapplication_pkg_addcountries($1, $2, $3::"CARNETSYS".carnetcountrytable[], $4, $5) + `; + await client.query(callProcQuery, [body.P_HEADERID, body.P_USSETS, 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: 200, + message: ResponseStatus.added, + ...fetchResult?.rows?.[0] || {} + }; + + } catch (error) { + if (client) await client.query('ROLLBACK'); + handlePgError(error, CarnetApplicationService.name) + } finally { + releasePgClient(client) + } + } + async UpdateShippingDetails(body: UpdateShippingDetailsDTO) { } + async EstimatedFees(body: GetCarnetControlCenterDTO) { } // processing [ PROCESSINGCENTER_PKG ] diff --git a/src/utils/helper.ts b/src/utils/helper.ts index f1f7256..da5e6ad 100644 --- a/src/utils/helper.ts +++ b/src/utils/helper.ts @@ -25,7 +25,10 @@ export enum ResponseStatus { reActivate = 'Reactivated Successfully', clientRegistrationDone = 'Client registration initiated successfully', lockedUserDone = 'Locked Successfully', - transmitted = 'Transmitted Successfully' + transmitted = 'Transmitted Successfully', + added = 'Added Successfully', + deleted = 'Deleted Successfully', + } export function normalizeKeysToUpperCase(obj) {