Compare commits

..

2 Commits

Author SHA1 Message Date
Kallesh B S
f24de4803f pdf generation 2025-08-07 15:15:19 +05:30
Kallesh B S
ad748be61d 7Aug Api modifications 2025-08-07 15:14:44 +05:30
7 changed files with 63 additions and 40 deletions

View File

@ -17,6 +17,7 @@ import { RolesGuard } from 'src/guards/roles.guard';
import { Response } from 'express'; import { Response } from 'express';
import { join } from 'path'; import { join } from 'path';
import { createReadStream } from 'fs'; import { createReadStream } from 'fs';
import { deleteFilesAsync } from 'src/utils/helper';
@ApiTags('Carnet Application - Oracle') @ApiTags('Carnet Application - Oracle')
@ -157,19 +158,28 @@ export class CarnetApplicationController {
@Post('PrintCarnet') @Post('PrintCarnet')
@Roles('ca', 'sa', 'ua') @Roles('ca', 'sa', 'ua')
async PrintCarnet(@Body() body: PrintCarnetDTO, @Res({ passthrough: true }) res: Response) { async PrintCarnet(@Body() body: PrintCarnetDTO, @Res({ passthrough: true }) res: Response) {
const fileName = 'carnet.pdf';
const filePath = join(process.cwd(), 'public/carnet-pdf', fileName);
const filesArray = ['p2.pdf', fileName];
try { try {
await this.carnetApplicationService.PrintCarnet(body); await this.carnetApplicationService.PrintCarnet(body);
const filePath = join(process.cwd(), 'public/carnet-pdf', 'carnet.pdf');
res.set({ res.set({
'Content-Type': 'application/pdf', 'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${'carnet.pdf'}"`, 'Content-Disposition': `attachment; filename="${fileName}"`,
}); });
const file = createReadStream(filePath);
return new StreamableFile(file); const stream = createReadStream(filePath);
// Clean up files after response finishes streaming
res.on('finish', async () => {
await deleteFilesAsync(filesArray);
});
return new StreamableFile(stream);
} catch (error) { } catch (error) {
return error.message return error.message;
} }
} }

View File

@ -1167,7 +1167,7 @@ export class CarnetApplicationService {
} }
async PrintCarnet(body: PrintCarnetDTO) { async PrintCarnet(body: PrintCarnetDTO) {
let filesArray = ['p2.pdf']
try { try {
@ -1220,8 +1220,6 @@ export class CarnetApplicationService {
} catch (error) { } catch (error) {
handleError(error, CarnetApplicationService.name) handleError(error, CarnetApplicationService.name)
} finally {
await deleteFilesAsync([...filesArray, 'carnet.pdf']);
} }
} }

View File

@ -32,35 +32,43 @@ export class ManageHoldersController {
@Get('SearchHolder/:P_SPID/:P_USERID') @Get('SearchHolder/:P_SPID/:P_USERID')
@ApiQuery({ name: "P_HOLDERNAME", type: String, required: false, description: "Optional" }) @ApiQuery({ name: "P_HOLDERNAME", type: String, required: false, description: "Optional" })
@ApiQuery({ name: "P_HOLDERID", type: Number, required: false, description: "Optional" })
SearchHolder( SearchHolder(
@Param('P_SPID') P_SPID: number, @Param('P_SPID') P_SPID: number,
@Param('P_USERID') P_USERID: string, @Param('P_USERID') P_USERID: string,
@Query('P_HOLDERID') P_HOLDERID?: number,
@Query('P_HOLDERNAME') P_HOLDERNAME?: string | null | undefined, @Query('P_HOLDERNAME') P_HOLDERNAME?: string | null | undefined,
) { ) {
let rawHolderName: string | null | undefined = P_HOLDERNAME; if (!P_USERID) {
throw new BadRequestException('User ID is required');
}
if (typeof rawHolderName === 'string') { // Sanitize holder name
rawHolderName = rawHolderName.trim(); let rawHolderName: string | null = null;
rawHolderName = rawHolderName.replace(/^['"]|['"]$/g, '');
if (rawHolderName === '' || rawHolderName.toLowerCase() === 'null') { if (typeof P_HOLDERNAME === 'string') {
rawHolderName = null; const trimmed = P_HOLDERNAME.trim().replace(/^['"]|['"]$/g, '');
} else { rawHolderName = trimmed === '' || trimmed.toLowerCase() === 'null' ? null : trimmed;
const allowedPattern = /^[A-Za-z0-9 _@&.-]+$/; }
// uncomment for strict validation // Validate and coerce P_HOLDERID
let holderId: number | null = null;
// if (!allowedPattern.test(rawHolderName)) { if (P_HOLDERID !== undefined && P_HOLDERID !== null) {
// rawHolderName = null; const parsed = Number(P_HOLDERID);
// } if (isNaN(parsed)) {
throw new BadRequestException('Invalid holder ID');
} }
} else { holderId = parsed;
rawHolderName = null;
} }
if(!P_USERID){
return new BadRequestException(); const body = {
} P_SPID,
const body = { P_SPID,P_USERID,P_HOLDERNAME: rawHolderName } P_USERID,
P_HOLDERID: holderId,
P_HOLDERNAME: rawHolderName,
};
return this.manageHoldersService.SearchHolder(body) return this.manageHoldersService.SearchHolder(body)
} }

View File

@ -631,7 +631,7 @@ export class ManageHoldersService {
} }
}; };
SearchHolder = async (body: { P_SPID: number, P_USERID: string, P_HOLDERNAME: string | null }) => { SearchHolder = async (body: { P_SPID: number, P_USERID: string, P_HOLDERID: number | null, P_HOLDERNAME: string | null }) => {
let connection; let connection;
try { try {
@ -640,11 +640,12 @@ export class ManageHoldersService {
const result: Result<any> = await connection.execute( const result: Result<any> = await connection.execute(
`BEGIN `BEGIN
MANAGEHOLDER_PKG.SearchHolder( MANAGEHOLDER_PKG.SearchHolder(
:P_SPID, :P_HOLDERNAME, :P_USERID, :P_CURSOR :P_SPID, :P_HOLDERID, :P_HOLDERNAME, :P_USERID, :P_CURSOR
); );
END;`, END;`,
{ {
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
P_HOLDERID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
P_HOLDERNAME: { val: body.P_HOLDERNAME, type: oracledb.DB_TYPE_NVARCHAR }, P_HOLDERNAME: { val: body.P_HOLDERNAME, type: oracledb.DB_TYPE_NVARCHAR },
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }

View File

@ -1,10 +1,10 @@
import { Body, Controller, Get, Patch, Post, Put, Query, UseGuards } from '@nestjs/common'; import { Body, Controller, Get, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common';
import { ApiQuery, ApiTags } from '@nestjs/swagger'; import { ApiQuery, ApiTags } from '@nestjs/swagger';
import { ParamTableService } from './param-table.service'; import { ParamTableService } from './param-table.service';
import { import {
ActivateOrInactivateParamRecordDTO, CreateParamRecordDTO, CreateTableRecordDTO, ActivateOrInactivateParamRecordDTO, CreateParamRecordDTO, CreateTableRecordDTO,
getParamValuesDTO, UpdateParamRecordDTO getParamValuesDTO, SPID_DTO, UpdateParamRecordDTO
} from 'src/dto/property.dto'; } from 'src/dto/property.dto';
import { Roles } from 'src/decorators/roles.decorator'; import { Roles } from 'src/decorators/roles.decorator';
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard'; import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
@ -53,10 +53,10 @@ export class ParamTableController {
return this.paramTableService.GETALLPARAMVALUES(body); return this.paramTableService.GETALLPARAMVALUES(body);
} }
@Get('GetCountriesAndMessages') @Get('GetCountriesAndMessages/:P_SPID')
@Roles('ca', 'sa', 'ua') @Roles('ca', 'sa', 'ua')
GET_COUNTRIES_AND_MESSAGES() { GET_COUNTRIES_AND_MESSAGES(@Param() body: SPID_DTO) {
return this.paramTableService.GET_COUNTRIES_AND_MESSAGES(); return this.paramTableService.GET_COUNTRIES_AND_MESSAGES(body);
} }
@Post('/CreateTableRecord') @Post('/CreateTableRecord')

View File

@ -8,7 +8,7 @@ import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/hel
import { import {
ActivateOrInactivateParamRecordDTO, CreateParamRecordDTO, CreateTableRecordDTO, ActivateOrInactivateParamRecordDTO, CreateParamRecordDTO, CreateTableRecordDTO,
getParamValuesDTO, UpdateParamRecordDTO getParamValuesDTO, SPID_DTO, UpdateParamRecordDTO
} from 'src/dto/property.dto'; } from 'src/dto/property.dto';
@Injectable() @Injectable()
@ -109,16 +109,17 @@ export class ParamTableService {
} }
} }
async GET_COUNTRIES_AND_MESSAGES() { async GET_COUNTRIES_AND_MESSAGES(body: SPID_DTO) {
let connection; let connection;
try { try {
connection = await this.oracleDBService.getConnection(); connection = await this.oracleDBService.getConnection();
const result = await connection.execute( const result = await connection.execute(
`BEGIN `BEGIN
MANAGEPARAMTABLE_PKG.GetCountriesAndMessages(:P_CURSOR); MANAGEPARAMTABLE_PKG.GetCountriesAndMessages(:P_SPID, :P_CURSOR);
END;`, END;`,
{ {
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
}, },
{ outFormat: oracledb.OUT_FORMAT_OBJECT } { outFormat: oracledb.OUT_FORMAT_OBJECT }

View File

@ -11,6 +11,7 @@ const path = require('path');
import { PDFDocument as pdfl } from 'pdf-lib'; import { PDFDocument as pdfl } from 'pdf-lib';
import PDFMerger from 'pdf-merger-js'; import PDFMerger from 'pdf-merger-js';
import * as fsPromises from 'fs/promises'; import * as fsPromises from 'fs/promises';
import { BadRequestException as BR } from 'src/exceptions/badRequest.exception';
const doc = new PDFDocument({ const doc = new PDFDocument({
size: 'A4', size: 'A4',
@ -21,13 +22,11 @@ const doc = new PDFDocument({
right: 50 right: 50
} }
}); });
const generalistFilePath = path.join(__dirname, '../../../public/carnet-pdf', 'p2.pdf')
doc.pipe(fs.createWriteStream(generalistFilePath));
const logger = new Logger('Helper'); const logger = new Logger('Helper');
export const handleError = (error: any, context: string = 'UnknownService'): never => { export const handleError = (error: any, context: string = 'UnknownService'): never => {
if (error instanceof BadRequestException) { if (error instanceof BadRequestException || error instanceof BR) {
logger.warn(`[${context}] ${error.message}`); logger.warn(`[${context}] ${error.message}`);
throw error; throw error;
} }
@ -546,6 +545,9 @@ export const generateGeneralistPDF1 = async (jsonData: pdfGLData[], headerData:
// Finalize the PDF file // Finalize the PDF file
doc.end(); doc.end();
const generalistFilePath = path.join(__dirname, '../../../public/carnet-pdf', 'p2.pdf')
doc.pipe(fs.createWriteStream(generalistFilePath));
console.log('PDF created successfully!'); console.log('PDF created successfully!');
return "p2 done"; return "p2 done";
@ -581,6 +583,9 @@ export const generateGeneralistPDF2 = async (carnetNumber: string) => {
// Finalize PDF // Finalize PDF
doc.end(); doc.end();
const generalistFilePath = path.join(__dirname, '../../../public/carnet-pdf', 'p2.pdf')
doc.pipe(fs.createWriteStream(generalistFilePath));
return "p2 done" return "p2 done"
} }