BE/src/pg/carnet-application/carnet-application.service.ts
2025-09-30 11:15:23 +05:30

1753 lines
62 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import {
CarnetProcessingCenterDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO,
CreateApplicationDTO,
UpdateExpGoodsAuthRepDTO,
AddGenerallistItemsDTO,
AddCountriesDTO,
UpdateShippingDetailsDTO,
CA_UpdateHolderDTO,
GetCarnetControlCenterDTO,
DeleteGenerallistItemsDTO,
PrintCarnetDTO,
PrintGLDTO,
YON,
CopyCarnetDTO,
GetExtendedSectionDTO,
SaveExtensionApplicationDTO,
CarnetProcessingCenterDTO2,
CapturePaymentDTO,
InitiatePaymentDTO,
GetOrderDetailsDTO,
GetPaymentHistoryDTO,
SaveHistoryDTO,
GetCarnetDetailsbyCarnetStatusDTO
} from 'src/dto/property.dto';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
import { PoolClient } from 'pg';
import { PgDBService } from 'src/db/db.service';
import { checkPgUserDefinedErrors, deleteFilesAsync, fnCounterFoil, fnVochers, generateFinalPDF, generateGL, generateGL1, generateGreenCoverPDF, handlePgError, parsePGNumericFields, pdfCarnetData, pdfGLData, releasePgClient, replaceSlashWithDash, ResponseStatus, tnVochers, toUpperCaseKeys, tsCounterFoil, usCounterFoil } from 'src/utils/helper';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import axios from 'axios';
import { PaypalService } from 'src/paypal/paypal.service';
import { NotFoundException } from 'src/exceptions/notFound.exception';
@Injectable()
export class CarnetApplicationService {
constructor(
private readonly pgDBService: PgDBService,
private readonly payPalService: PaypalService
) { }
// [ CARNETAPPLICATION_PKG ]
// async SaveCarnetApplication(body: SaveCarnetApplicationDTO) { }
async TransmitApplicationtoProcess(body: TransmitApplicationtoProcessDTO) {
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_transmitapplicationtoprocess($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_HEADERID, 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.transmitted,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async CreateApplication(body: CreateApplicationDTO) {
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_createapplication($1, $2, $3, $4, $5, $6, $7)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, body.P_LOCATIONID, body.P_USERID, body.P_APPLICATIONNAME, body.P_ORDERTYPE, 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, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async UpdateHolder(body: CA_UpdateHolderDTO) {
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_updateholder($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_HEADERID, 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 {
statusCode: 200,
message: ResponseStatus.updated,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
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,
...toUpperCaseKeys(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 escapePostgresCompositeField(str: string): string {
if (str == null) return '';
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
const contactLiterals = body.P_GLTABLE.map(c => {
const fields = [
c.ITEMNO ?? '',
c.ITEMDESCRIPTION ?? '',
c.ITEMVALUE ?? '',
c.NOOFPIECES ?? '',
c.ITEMWEIGHT ?? '',
c.ITEMWEIGHTUOM ?? '',
c.GOODSORIGINCOUNTRY ?? '',
].map(field => escapePostgresCompositeField(String(field))).join(',');
return `"(${fields})"`; // ✅ Wrap entire composite in 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,
...toUpperCaseKeys(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 escapePostgresCompositeField(str: string): string {
if (str == null) return '';
return str.replace(/\\/g, '\\\\').replace(/"/g, '""');
}
const contactLiterals = body.P_GLTABLE.map(c => {
const fields = [
c.ITEMNO ?? '',
c.ITEMDESCRIPTION ?? '',
c.ITEMVALUE ?? '',
c.NOOFPIECES ?? '',
c.ITEMWEIGHT ?? '',
c.ITEMWEIGHTUOM ?? '',
c.GOODSORIGINCOUNTRY ?? '',
].map(field => escapePostgresCompositeField(String(field))).join(',');
return `"(${fields})"`; // ✅ Wrap each composite in 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,
...toUpperCaseKeys(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,
...toUpperCaseKeys(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 escapePostgresCompositeField(str: string): string {
if (str == null) return '';
return str.replace(/\\/g, '\\\\').replace(/"/g, '""'); // PostgreSQL-compliant
}
const contactLiterals = body.P_COUNTRYTABLE.map(c => {
const fields = [
c.P_VISISTTRANSITIND ?? '',
c.COUNTRYCODE ?? '',
c.NOOFTIMESENTLEAVE ?? '',
].map(field => escapePostgresCompositeField(String(field))).join(',');
return `"(${fields})"`; // ✅ wrap entire composite in 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,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async UpdateShippingDetails(body: UpdateShippingDetailsDTO) {
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_updateshippingdetails($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29)
`;
await client.query(callProcQuery,
[
body.P_HEADERID,
body.P_SHIPTOTYPE,
body.P_SHIPCONTACTID,
body.P_SHIPNAME,
body.P_ADDRESS1,
body.P_ADDRESS2,
body.P_CITY,
body.P_STATE,
body.P_ZIP,
body.P_COUNTRY,
body.P_FIRSTNAME,
body.P_LASTNAME,
body.P_TITLE,
body.P_PHONENO,
body.P_MOBILENO,
body.P_FAXNO,
body.P_EMAILADDRESS,
body.P_MIDDLEINITIAL,
body.P_FORMOFSECURITY,
body.P_INSPROTECTION,
body.P_LDIPROTECTION,
body.P_DELIVERYTYPE,
body.P_DELIVERYMETHOD,
body.P_PAYMENTMETHOD,
body.P_CUSTCOURIERNO,
body.P_REFNO,
body.P_NOTES,
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,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async EstimatedFees(body: GetCarnetControlCenterDTO) {
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_estimatedfees($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_HEADERID, 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');
return parsePGNumericFields(toUpperCaseKeys(fetchResult.rows)[0] ?? []);
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
// processing [ PROCESSINGCENTER_PKG ]
async ProcessCarnet(body: CarnetProcessingCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_processcarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_HEADERID, 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.processed,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async UpdatePrintCarnet(body: CarnetProcessingCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_updateprintcarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_HEADERID, 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,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async VoidCarnet(body: CarnetProcessingCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_voidcarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_HEADERID, 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.voided,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async CopyCarnet(body: CopyCarnetDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_copycarnet($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_HEADERID, body.P_APPLICATIONNAME, 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.copied,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async DuplicateCarnet(body: CarnetProcessingCenterDTO2) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_duplicatecarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_CARNETNO, 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.duplicated,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async AddlSets(body: CarnetProcessingCenterDTO2) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_addlsets($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_CARNETNO, 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.addl_completed,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async ExtendCarnet(body: CarnetProcessingCenterDTO2) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_extendcarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_CARNETNO, 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.extended,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async GetExtendedSection(body: GetExtendedSectionDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_getextendedsection($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HEADERID, 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');
return toUpperCaseKeys(fetchResult.rows)[0] ?? [];
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async SaveExtensionApplication(body: SaveExtensionApplicationDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_saveextensionapplication($1, $2, $3, $4, $5, $6, $7, $8)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_SPID, body.P_HEADERID, body.P_GOODSPORT, body.P_GOODSCOUNTRY, body.P_REASONCODE, body.P_EXTENSIONPERIOD, 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.saved,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async CloseCarnet(body: CarnetProcessingCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_closecarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_HEADERID, 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.closed,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async ResetCarnet(body: CarnetProcessingCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_resetcarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_HEADERID, 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.reset_successfull,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async DeleteCarnet(body: CarnetProcessingCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".processingcenter_pkg_deletecarnet($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_USERID, body.P_HEADERID, 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,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
// [ CARNETCONTROLCENTER_PKG ]
async GetHolderstoEdit(body: GetCarnetControlCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".carnetcontrolcenter_pkg_getholderstoedit($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_HEADERID, 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');
return toUpperCaseKeys(fetchResult.rows)[0] ?? [];
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async GetGoodsDetailstoEdit(body: GetCarnetControlCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".carnetcontrolcenter_pkg_getgoodsdetailstoedit($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_HEADERID, 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');
return toUpperCaseKeys(fetchResult.rows)[0] ?? [];
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async GetGoodsItemstoEdit(body: GetCarnetControlCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".carnetcontrolcenter_pkg_getgoodsitemstoedit($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_HEADERID, 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');
return toUpperCaseKeys(fetchResult.rows);
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async GetCountryDetailstoEdit(body: GetCarnetControlCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".carnetcontrolcenter_pkg_getcountrydetailstoedit($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_HEADERID, 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');
let fres = toUpperCaseKeys(fetchResult.rows);
// return toUpperCaseKeys(fetchResult.rows)[0] ?? [];
return fres.length > 0 ?
{
NOOFUSSETS: fres[0].NOOFUSSETS,
P_COUNTRYTABLE: fres.map(({ NOOFUSSETS, ...rest }) => rest)
}
: {};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async GetShipPaymentDetailstoEdit(body: GetCarnetControlCenterDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".carnetcontrolcenter_pkg_getshippaymentdetailstoedit($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_HEADERID, 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');
return toUpperCaseKeys(fetchResult.rows)[0] ?? [];
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async GetCarnetDetailsbyCarnetStatus(body: GetCarnetDetailsbyCarnetStatusDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".carnetcontrolcenter_pkg_getcarnetdetails($1, $2, $3, $4)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_USERID, body.P_CARNETSTATUS, 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, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
// [PRINT_PKG]
async getPrintingData(body: PrintCarnetDTO) {
let client: PoolClient | null = null;
const p_carnetdatacursor = 'p_carnetdatacursor';
const p_gldatacursor = 'p_gldatacursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".print_pkg_printcarnet($1, $2, $3, $4, $5)
`;
await client.query(callProcQuery, [body.P_SPID, body.P_HEADERID, body.P_PRINTGL, p_carnetdatacursor, p_gldatacursor]);
// 🚫 DON'T quote the cursor name in FETCH
const p_carnetdatacursorResult = await client.query(`FETCH ALL FROM ${p_carnetdatacursor}`);
const p_gldatacursorResult = await client.query(`FETCH ALL FROM ${p_gldatacursor}`);
// 🚫 DON'T quote the cursor name in CLOSE
await client.query(`CLOSE ${p_carnetdatacursor}`);
await client.query(`CLOSE ${p_gldatacursor}`);
await client.query('COMMIT');
checkPgUserDefinedErrors(p_carnetdatacursorResult);
checkPgUserDefinedErrors(p_gldatacursorResult);
return { fres: toUpperCaseKeys(p_carnetdatacursorResult.rows), fres1: toUpperCaseKeys(p_gldatacursorResult.rows) }
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async PrintCarnet(body: PrintCarnetDTO) {
try {
const { fres, fres1 }: any = await this.getPrintingData(body);
if (body.P_PRINTGL === 'Y') {
if (fres.length === 0 || !fres[0].CARNETNO || fres1.length === 0) {
throw new BadRequestException("Print failed please check the submitted details");
}
}
else {
if (fres.length === 0 || !fres[0].CARNETNO) {
throw new BadRequestException("Print failed please check the submitted details");
}
}
if (fres.length > 0 && fres[0].ERRORMESG) {
// this.logger.warn(fres[0].ERRORMESG);
console.log(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
try {
const glData: pdfGLData[] = fres1.map((x: any) => {
return {
itemNo: x.ITEMNO,
description: x.ITEMDESCRIPTION,
noOfPieces: x.NOOFPIECES,
weight: x.WEIGHT,
itemValue: isNaN(Number(x.ITEMVALUE)) ? 0 : Number(x.ITEMVALUE),
countryOfOrigin: x.GOODSORIGINCOUNTRY
};
});
const carnetData: pdfCarnetData = {
carnetNo: fres[0].CARNETNO ?? "",
ISSUEDBY: fres[0].ISSUEDBY ?? "",
ISSUEDATE: fres[0].ISSUEDATE ?? "",
EXPDATE: fres[0].EXPDATE ?? "",
AUTHREP: fres[0].AUTHREP ?? "",
NOOFUSSETS: isNaN(Number(fres[0].NOOFUSSETS)) ? 0 : Number(fres[0].NOOFUSSETS),
NOOFFOREIGNSETS: isNaN(Number(fres[0].NOOFFOREIGNSETS)) ? 0 : Number(fres[0].NOOFFOREIGNSETS),
NOOFTRANSITSETS: isNaN(Number(fres[0].NOOFTRANSITSETS)) ? 0 : Number(fres[0].NOOFTRANSITSETS),
PRINTGOODSTOBEEXPORTED: fres[0].PRINTGOODSTOBEEXPORTED ?? "",
HOLDERDATATOPRINT: fres[0].HOLDERDATATOPRINT ?? "",
CONTINUATIONSHEETS: isNaN(Number(fres[0].CONTINUATIONSHEETS)) ? 0 : Number(fres[0].CONTINUATIONSHEETS),
NEXTUSCFNO: isNaN(Number(fres[0].NEXTUSCFNO)) ? 0 : Number(fres[0].NEXTUSCFNO),
NEXTFOREIGNCFNO: isNaN(fres[0].NEXTFOREIGNCFNO) ? 0 : Number(fres[0].NEXTFOREIGNCFNO),
NEXTTRANSITCFNO: isNaN(Number(fres[0].NEXTTRANSITCFNO)) ? 0 : Number(fres[0].NEXTTRANSITCFNO),
contPageNo: 0
}
const p1Status = await generateGreenCoverPDF(carnetData);
let p2Status: any = "";
if (body.P_PRINTGL === 'Y') {
p2Status = await generateGL(glData, carnetData, body);
// console.log("-------- p2 --------", p2Status);
// console.log(typeof p2Status.batch, p2Status.batch);
if (p2Status.batch % 2 === 0) {
await generateFinalPDF([...p2Status.fileArray, '2GeneralListVOID.pdf'], `${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`)
await deleteFilesAsync([...p2Status.fileArray])
}
else {
await generateFinalPDF([...p2Status.fileArray], `${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`)
await deleteFilesAsync([...p2Status.fileArray])
}
} else {
p2Status = await generateGL1(carnetData);
if (p2Status === 'p2 done') {
await generateFinalPDF([`${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`, '2GeneralListVOID.pdf'], `${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`)
}
}
const p3Status = await usCounterFoil(carnetData);
const p4Status = await fnCounterFoil(carnetData);
const p5Status = await tsCounterFoil(carnetData);
const p6Status = await fnVochers(carnetData, body);
const p7Status = await tnVochers(carnetData, body);
const finalArray = [
...p3Status,
...p4Status,
...p5Status,
...p6Status,
...p7Status
]
return { finalArray, carnetData }
} catch (error) {
throw new InternalServerException(error.message)
}
}
catch (error) {
// if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
}
}
async PrintGL(body: PrintGLDTO) {
let newBody: PrintCarnetDTO = { ...body, P_PRINTGL: YON.YES }
try {
const { fres, fres1 }: any = await this.getPrintingData(newBody);
if (fres.length === 0 || fres1.length === 0) {
throw new BadRequestException("Print failed please check the submitted details");
}
if (fres.length > 0 && fres[0].ERRORMESG) {
// this.logger.warn(fres[0].ERRORMESG);
console.log(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
try {
const glData: pdfGLData[] = fres1.map(x => {
return {
itemNo: x.ITEMNO,
description: x.ITEMDESCRIPTION,
noOfPieces: x.NOOFPIECES,
weight: x.WEIGHT,
itemValue: x.ITEMVALUE,
countryOfOrigin: x.GOODSORIGINCOUNTRY
};
});
const carnetData: pdfCarnetData = {
carnetNo: fres[0].CARNETNO ?? "",
ISSUEDBY: fres[0].ISSUEDBY ?? "",
ISSUEDATE: fres[0].ISSUEDATE ?? "",
EXPDATE: fres[0].EXPDATE ?? "",
AUTHREP: fres[0].AUTHREP ?? "",
NOOFUSSETS: fres[0].NOOFUSSETS ?? 0,
NOOFFOREIGNSETS: fres[0].NOOFFOREIGNSETS ?? 0,
NOOFTRANSITSETS: fres[0].NOOFTRANSITSETS ?? 0,
PRINTGOODSTOBEEXPORTED: fres[0].PRINTGOODSTOBEEXPORTED ?? "",
HOLDERDATATOPRINT: fres[0].HOLDERDATATOPRINT ?? "",
CONTINUATIONSHEETS: fres[0].CONTINUATIONSHEETS ?? 0,
NEXTUSCFNO: fres[0].NEXTUSCFNO ?? 0,
NEXTFOREIGNCFNO: fres[0].NEXTFOREIGNCFNO ?? 0,
NEXTTRANSITCFNO: fres[0].NEXTTRANSITCFNO ?? 0,
contPageNo: 0
}
// const p1Status = await generateGreenCoverPDF(carnetData);
let p2Status: any = "";
p2Status = await generateGL(glData, carnetData, body);
// console.log("-------- p2 --------", p2Status);
// console.log(typeof p2Status.batch, p2Status.batch);
if (p2Status.batch % 2 === 0) {
await generateFinalPDF([...p2Status.fileArray, '2GeneralListVOID.pdf'], `${body.P_HEADERID}p2.pdf`)
await deleteFilesAsync([...p2Status.fileArray])
}
else {
await generateFinalPDF([...p2Status.fileArray], `${body.P_HEADERID}p2.pdf`)
await deleteFilesAsync([...p2Status.fileArray])
}
// const p3Status = await usCounterFoil(carnetData);
// const p4Status = await fnCounterFoil(carnetData);
// const p5Status = await tsCounterFoil(carnetData);
// const p6Status = await fnVochers(carnetData);
// const p7Status = await tnVochers(carnetData);
const finalArray = [
// ...p3Status,
// ...p4Status,
// ...p5Status,
// ...p6Status,
// ...p7Status
]
return { finalArray, carnetData }
} catch (error) {
throw new InternalServerException(error.message)
}
}
catch (error) {
// if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
}
}
// [payment]
async formatAmount(amount) {
if (typeof amount !== 'number' || isNaN(amount)) {
throw new Error('Amount must be a valid number');
}
if (amount < 0) {
throw new BadRequestException('Amount must be non-negative');
}
return amount.toFixed(2); // Always returns a string with 2 decimal places
}
async InitiatePayment(body: InitiatePaymentDTO) {
const quantity = 1;
let orderID: string | null = null
const formattedAmount = await this.formatAmount(body.P_PRICE * quantity);
try {
const accessToken = await this.payPalService.generateAccessToken();
const response = await axios({
url: process.env.PAYPAL_BASE_URL + '/v2/checkout/orders',
method: 'post',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + accessToken
},
data: JSON.stringify({
intent: 'CAPTURE',
purchase_units: [
{
items: [
{
name: 'Carnet',
description: body.P_DESCRIPTION,
quantity: quantity,
unit_amount: {
currency_code: 'USD',
value: formattedAmount
}
}
],
amount: {
currency_code: 'USD',
value: formattedAmount,
breakdown: {
item_total: {
currency_code: 'USD',
value: formattedAmount
}
}
}
}
],
application_context: {
return_url: process.env.BASE_URL + '/complete-order',
cancel_url: process.env.BASE_URL + '/cancel-order',
shipping_preference: 'NO_SHIPPING',
user_action: 'PAY_NOW',
brand_name: 'test sample',
disable_funding: "card"
}
})
});
orderID = response?.data?.id;
const save_result: any = await this.SaveHistory(
{
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
P_ORDERID: response?.data?.id,
P_PAYMENTAMOUNT: body.P_PRICE,
P_STATUS: "CREATED",
P_USERID: body.P_USERID
}
);
if (save_result.statusCode === 200) {
return {
id: response?.data?.id, href: response?.data?.links?.find(obj => obj.rel === 'approve')?.href
};
}
else {
throw new InternalServerException();
}
} catch (error) {
console.error('Error creating PayPal order:', error.response?.data || error?.message || error);
await this.SaveHistory({
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
P_ORDERID: orderID,
P_PAYMENTAMOUNT: body.P_PRICE,
P_STATUS: "FAILED",
P_USERID: body.P_USERID,
P_PAYMENTERROR: orderID ? error?.message : `Error while creating ORDERID : ${error?.message}`
});
throw new InternalServerException();
}
}
async CapturePayment(body: CapturePaymentDTO) {
try {
const approve_result = await this.OrderDetails({ P_ORDERID: body.P_ORDERID });
const formattedAmount = await this.formatAmount(body.P_PRICE);
if (approve_result.data.id === body.P_ORDERID
&& approve_result.data.status === "APPROVED"
&& approve_result.data.purchase_units[0]?.amount?.value === formattedAmount + ""
) {
await this.SaveHistory({
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
P_ORDERID: body.P_ORDERID,
P_PAYMENTAMOUNT: body.P_PRICE,
P_STATUS: "APPROVED",
P_USERID: body.P_USERID
// P_PAYMENTERROR: `Error while capturing Payment : ${error?.message}`
});
const accessToken = await this.payPalService.generateAccessToken();
const response = await axios({
url: `${process.env.PAYPAL_BASE_URL}/v2/checkout/orders/${body.P_ORDERID}/capture`,
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
},
});
const capture = response?.data?.purchase_units?.[0]?.payments?.captures?.[0];
// console.log(JSON.stringify(response?.data));
await this.SaveHistory({
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
P_ORDERID: body.P_ORDERID,
P_PAYMENTAMOUNT: body.P_PRICE,
P_STATUS: "COMPLETED",
P_USERID: body.P_USERID
// P_PAYMENTERROR: `Error while capturing Payment : ${error?.message}`
});
return {
statusCode: 200,
message: "Payment successful",
amount: `${capture?.amount?.value} ${capture?.amount?.currency_code}`,
};
}
else {
await this.SaveHistory({
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
P_ORDERID: body.P_ORDERID,
P_PAYMENTAMOUNT: body.P_PRICE,
P_STATUS: "FAILED",
P_USERID: body.P_USERID,
P_PAYMENTERROR: `Error while validating user approval`
});
throw new InternalServerException("failed to save approved status");
}
} catch (error: any) {
const status = error.response?.status || 500;
const message = error.response?.data?.message || "Payment failed due to an unexpected error.";
// Optional: log full error for debugging
console.error("PayPal Capture Error:", {
status,
message,
details: error.response?.data,
});
if (status === 404) {
await this.SaveHistory({
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
P_ORDERID: body.P_ORDERID,
P_PAYMENTAMOUNT: body.P_PRICE,
P_STATUS: "FAILED",
P_USERID: body.P_USERID,
P_PAYMENTERROR: `ORDERID NOT FOUND : ${error?.message}`
});
throw new NotFoundException(error.response?.data?.message || error?.message || "Resource Not Found")
}
await this.SaveHistory({
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
P_ORDERID: body.P_ORDERID,
P_PAYMENTAMOUNT: body.P_PRICE,
P_STATUS: "FAILED",
P_USERID: body.P_USERID,
P_PAYMENTERROR: `Error while capturing Payment : ${error?.message}`
});
throw new InternalServerException();
}
}
async OrderDetails(body: GetOrderDetailsDTO) {
try {
// Max length of Order ID: 36 characters (UUID)
if (!body.P_ORDERID || body.P_ORDERID.length > 36) {
throw new BadRequestException("Invalid Order ID");
}
const accessToken = await this.payPalService.generateAccessToken();
const response = await axios({
url: `${process.env.PAYPAL_BASE_URL}/v2/checkout/orders/${body.P_ORDERID}`,
method: 'get',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
},
});
// console.log("PayPal Order Details:", JSON.stringify(response.data));
return {
statusCode: 200,
message: "Order details retrieved successfully",
data: response.data,
};
} catch (error: any) {
const isAxiosError = error.isAxiosError;
if (isAxiosError) {
const axiosErrorCode = error.code;
switch (axiosErrorCode) {
case 'ECONNABORTED':
case 'ETIMEDOUT':
console.error("PayPal request timed out. Please try again later.")
throw new InternalServerException("Service is currently unreachable. Please try again later.");
case 'ENOTFOUND':
case 'ECONNREFUSED':
console.error("PayPal service is currently unavailable. Please try again later.")
throw new InternalServerException("Service is currently unreachable. Please try again later.");
}
}
const status = error.response?.status || 500;
const message = error.response?.data?.message || "Failed to fetch order details.";
console.error("PayPal OrderDetails Error:", {
status,
message,
details: error.response?.data,
});
if (status === 404) {
throw new NotFoundException(message);
}
throw new InternalServerException("A Error Occured while Processing your Request");
}
}
async GetPaymentHistory(body: GetPaymentHistoryDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".Pay_GetPaymentHistory($1, $2, $3)
`;
await client.query(callProcQuery, [body.P_APPLICATIONNAME, 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');
return toUpperCaseKeys(fetchResult.rows)[0] ?? {};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
async SaveHistory(body: SaveHistoryDTO) {
let client: PoolClient | null = null;
const cursorName = 'p_cursor';
try {
client = await this.pgDBService.getConnection();
await client.query('BEGIN');
const callProcQuery = `
CALL "CARNETSYS".Pay_SaveHistory($1, $2, $3, $4, $5, $6, $7)
`;
await client.query(callProcQuery, [body.P_APPLICATIONNAME, body.P_ORDERID, body.P_PAYMENTAMOUNT, body.P_STATUS, body.P_USERID, body.P_PAYMENTERROR, 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.saved,
...toUpperCaseKeys(fetchResult?.rows)[0]
};
} catch (error) {
if (client) await client.query('ROLLBACK');
handlePgError(error, CarnetApplicationService.name)
} finally {
releasePgClient(client)
}
}
}