Compare commits

..

1 Commits

Author SHA1 Message Date
Kallesh B S
ecbf959ec7 pdf generation 2025-08-06 19:06:48 +05:30
7 changed files with 40 additions and 63 deletions

View File

@ -17,7 +17,6 @@ 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')
@ -158,28 +157,19 @@ 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="${fileName}"`, 'Content-Disposition': `attachment; filename="${'carnet.pdf'}"`,
}); });
const file = createReadStream(filePath);
const stream = createReadStream(filePath); return new StreamableFile(file);
// 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,6 +1220,8 @@ export class CarnetApplicationService {
} catch (error) { } catch (error) {
handleError(error, CarnetApplicationService.name) handleError(error, CarnetApplicationService.name)
} finally {
await deleteFilesAsync([...filesArray, 'carnet.pdf']);
} }
} }

View File

@ -32,43 +32,35 @@ 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,
) { ) {
if (!P_USERID) { let rawHolderName: string | null | undefined = P_HOLDERNAME;
throw new BadRequestException('User ID is required');
}
// Sanitize holder name if (typeof rawHolderName === 'string') {
let rawHolderName: string | null = null; rawHolderName = rawHolderName.trim();
rawHolderName = rawHolderName.replace(/^['"]|['"]$/g, '');
if (typeof P_HOLDERNAME === 'string') { if (rawHolderName === '' || rawHolderName.toLowerCase() === 'null') {
const trimmed = P_HOLDERNAME.trim().replace(/^['"]|['"]$/g, ''); rawHolderName = null;
rawHolderName = trimmed === '' || trimmed.toLowerCase() === 'null' ? null : trimmed; } else {
} const allowedPattern = /^[A-Za-z0-9 _@&.-]+$/;
// Validate and coerce P_HOLDERID // uncomment for strict validation
let holderId: number | null = null;
if (P_HOLDERID !== undefined && P_HOLDERID !== null) { // if (!allowedPattern.test(rawHolderName)) {
const parsed = Number(P_HOLDERID); // rawHolderName = null;
if (isNaN(parsed)) { // }
throw new BadRequestException('Invalid holder ID');
} }
holderId = parsed; } else {
rawHolderName = null;
} }
if(!P_USERID){
const body = { return new BadRequestException();
P_SPID, }
P_USERID, const body = { P_SPID,P_USERID,P_HOLDERNAME: rawHolderName }
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_HOLDERID: number | null, P_HOLDERNAME: string | null }) => { SearchHolder = async (body: { P_SPID: number, P_USERID: string, P_HOLDERNAME: string | null }) => {
let connection; let connection;
try { try {
@ -640,12 +640,11 @@ 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_HOLDERID, :P_HOLDERNAME, :P_USERID, :P_CURSOR :P_SPID, :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, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common'; import { Body, Controller, Get, 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, SPID_DTO, UpdateParamRecordDTO getParamValuesDTO, 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/:P_SPID') @Get('GetCountriesAndMessages')
@Roles('ca', 'sa', 'ua') @Roles('ca', 'sa', 'ua')
GET_COUNTRIES_AND_MESSAGES(@Param() body: SPID_DTO) { GET_COUNTRIES_AND_MESSAGES() {
return this.paramTableService.GET_COUNTRIES_AND_MESSAGES(body); return this.paramTableService.GET_COUNTRIES_AND_MESSAGES();
} }
@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, SPID_DTO, UpdateParamRecordDTO getParamValuesDTO, UpdateParamRecordDTO
} from 'src/dto/property.dto'; } from 'src/dto/property.dto';
@Injectable() @Injectable()
@ -109,17 +109,16 @@ export class ParamTableService {
} }
} }
async GET_COUNTRIES_AND_MESSAGES(body: SPID_DTO) { async GET_COUNTRIES_AND_MESSAGES() {
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_SPID, :P_CURSOR); MANAGEPARAMTABLE_PKG.GetCountriesAndMessages(: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,7 +11,6 @@ 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',
@ -22,11 +21,13 @@ 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 || error instanceof BR) { if (error instanceof BadRequestException) {
logger.warn(`[${context}] ${error.message}`); logger.warn(`[${context}] ${error.message}`);
throw error; throw error;
} }
@ -545,9 +546,6 @@ 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";
@ -583,9 +581,6 @@ 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"
} }