Compare commits

..

2 Commits

Author SHA1 Message Date
Kallesh B S
c9508e47e9 pdf generation 2025-08-07 20:18:55 +05:30
Kallesh B S
ad748be61d 7Aug Api modifications 2025-08-07 15:14:44 +05:30
7 changed files with 11 additions and 212 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@
/build
# pdf
/public/carnet-pdf/*.pdf
# Logs
logs

Binary file not shown.

Binary file not shown.

View File

@ -160,7 +160,7 @@ export class CarnetApplicationController {
async PrintCarnet(@Body() body: PrintCarnetDTO, @Res({ passthrough: true }) res: Response) {
const fileName = 'carnet.pdf';
const filePath = join(process.cwd(), 'public/carnet-pdf', fileName);
let filesArray = ['p1.pdf', 'p2.pdf', fileName]
const filesArray = ['p2.pdf', fileName];
try {
await this.carnetApplicationService.PrintCarnet(body);

View File

@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { OracleDBService } from 'src/db/db.service';
import * as oracledb from 'oracledb'
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import { closeOracleDbConnection, deleteFilesAsync, fetchCursor, generateFinalPDF, generateGeneralistPDF1, generateGeneralistPDF2, generateGreenCoverPDF, handleError, pdfCarnetData, pdfGLData, setEmptyStringsToNull } from 'src/utils/helper';
import { closeOracleDbConnection, deleteFilesAsync, fetchCursor, generateFinalPDF, generateGeneralistPDF1, generateGeneralistPDF2, handleError, pdfCarnetData, pdfGLData, setEmptyStringsToNull } from 'src/utils/helper';
import {
CarnetProcessingCenterDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO,
@ -1195,18 +1195,9 @@ export class CarnetApplicationService {
const carnetData: pdfCarnetData = {
carnetNo: fres[0].CARNETNO,
AUTHREP: fres[0].AUTHREP,
PRINTGOODSTOBEEXPORTED: fres[0].PRINTGOODSTOBEEXPORTED,
ISSUEDATE: fres[0].ISSUEDATE,
ISSUEDBY: fres[0].ISSUEDBY,
EXPDATE: fres[0].EXPDATE,
CONTINUATIONSHEETS: fres[0].CONTINUATIONSHEETS,
HOLDERDATATOPRINT: fres[0].HOLDERDATATOPRINT,
contPageNo: 0
}
const p1Status = await generateGreenCoverPDF(carnetData);
let p2Status: string = "";
if (body.P_PRINTGL === 'Y') {
@ -1215,7 +1206,7 @@ export class CarnetApplicationService {
p2Status = await generateGeneralistPDF2(carnetData.carnetNo);
}
if (p1Status === "p1 done" && p2Status === "p2 done") {
if (p2Status === "p2 done") {
await generateFinalPDF(['p2.pdf'], 'carnet.pdf');
}

View File

@ -645,7 +645,7 @@ export class ManageHoldersService {
END;`,
{
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
P_HOLDERID: { val: body.P_HOLDERID, 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_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }

View File

@ -12,7 +12,7 @@ const PDFMerger = require('pdf-merger-js').default;
import * as fsPromises from 'fs/promises';
import { BadRequestException as BR } from 'src/exceptions/badRequest.exception';
import { existsSync, readFileSync } from 'fs';
import { PDFDocument as pdfl, PDFTextField, PDFCheckBox, PDFRadioGroup, PDFDropdown, PDFOptionList } from 'pdf-lib';
import { PDFDocument as pdfl } from 'pdf-lib';
const logger = new Logger('Helper');
@ -78,14 +78,7 @@ export interface pdfGLData {
export interface pdfCarnetData {
carnetNo: string;
AUTHREP: string;
PRINTGOODSTOBEEXPORTED: string;
ISSUEDATE: string;
ISSUEDBY: string;
EXPDATE: string;
CONTINUATIONSHEETS: number;
HOLDERDATATOPRINT: string;
contPageNo: number; // for GL table only
contPageNo: number;
}
function formatNumber(num) {
@ -96,7 +89,7 @@ function formatNumber(num) {
export const generateGeneralistPDF1 = async (jsonData: pdfGLData[], headerData: pdfCarnetData) => {
const doc = new PDFDocument({
size: 'Letter',
size: 'A4',
margins: {
top: 50,
bottom: 50,
@ -577,7 +570,7 @@ export const generateGeneralistPDF1 = async (jsonData: pdfGLData[], headerData:
export const generateGeneralistPDF2 = async (carnetNumber: string) => {
// 1. Create a new PDF document instance
const doc = new PDFDocument({
size: 'Letter',
size: 'A4',
margins: {
top: 50,
bottom: 50,
@ -629,202 +622,16 @@ export const generateGeneralistPDF2 = async (carnetNumber: string) => {
});
};
function toUSDateTime(isoString) {
const date = new Date(isoString);
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const year = date.getFullYear();
let hours = date.getHours();
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12 || 12;
// return `${month}-${day}-${year}, ${hours}:${minutes}:${seconds} ${ampm}`;
return `${month}-${day}-${year}`;
}
export const generateGreenCoverPDFX = async (carnetData: pdfCarnetData) => {
const templatePath = path.join(__dirname, '../../..', 'public/pdf-templates', '1GreenCover.pdf');
export const generateGreenCoverPDF = async () => {
const templatePath = path.join(__dirname, '../../..', 'public/pdf-templates', '2GeneralList.pdf');
const existingPdfBytes = fs.readFileSync(templatePath);
const pdfDoc = await pdfl.load(existingPdfBytes);
const form = pdfDoc.getForm();
const CURRENT_FONT = 11;
let fields = form.getFields();
// const fieldNames = fields.map(f => f.getName());
const fieldInfo = fields.map(f => {
let type = 'unknown';
if (f instanceof PDFTextField) type = 'text';
else if (f instanceof PDFCheckBox) type = 'checkbox';
else if (f instanceof PDFRadioGroup) type = 'radio';
else if (f instanceof PDFDropdown) type = 'dropdown';
else if (f instanceof PDFOptionList) type = 'option-list';
return {
name: f.getName(),
type,
};
});
fieldInfo.map(x => {
if (x.type === "text" && x.name === 'CarnetNo') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.carnetNo);
}
else if (x.type === "text" && x.name === 'AuthBy') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.AUTHREP);
}
else if (x.type === "text" && x.name === 'ContnSheetNo') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.CONTINUATIONSHEETS + "");
}
else if (x.type === "text" && x.name === 'GoodstobeExportedas') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.PRINTGOODSTOBEEXPORTED);
}
else if (x.type === "text" && x.name === 'IssuedOn') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
const formattedDate = toUSDateTime(carnetData.ISSUEDATE)
nameField.setText(formattedDate);
}
else if (x.type === "text" && x.name === 'IssuedBy') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.ISSUEDBY);
}
else if (x.type === "text" && x.name === 'ValidUntil') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
const formattedDate = toUSDateTime(carnetData.EXPDATE)
nameField.setText(formattedDate);
}
else if (x.type === "text" && x.name === 'HolderNameAddress') {
const nameField = form.getTextField(x.name);
nameField.enableMultiline();
nameField.setFontSize(CURRENT_FONT);
const multilineAddress = carnetData.HOLDERDATATOPRINT.replace(/~/g, "\n");
nameField.setText(multilineAddress);
}
})
form.flatten();
const filledPdfBytes = await pdfDoc.save();
const outputPath = path.join(__dirname, '../../..', 'public/carnet-pdf', '1GreenCover.pdf');
fs.writeFileSync(outputPath, filledPdfBytes);
return fieldInfo;
}
export const generateGreenCoverPDF = (carnetData: pdfCarnetData) => {
return new Promise(async (resolve, reject) => {
try {
const templatePath = path.join(__dirname, '../../..', 'public/pdf-templates', '1GreenCover.pdf');
const existingPdfBytes = fs.readFileSync(templatePath);
const pdfDoc = await pdfl.load(existingPdfBytes);
const form = pdfDoc.getForm();
const CURRENT_FONT = 11;
const fields = form.getFields();
const fieldInfo = fields.map(f => {
let type = 'unknown';
if (f instanceof PDFTextField) type = 'text';
else if (f instanceof PDFCheckBox) type = 'checkbox';
else if (f instanceof PDFRadioGroup) type = 'radio';
else if (f instanceof PDFDropdown) type = 'dropdown';
else if (f instanceof PDFOptionList) type = 'option-list';
return { name: f.getName(), type };
});
fieldInfo.forEach(x => {
if (x.type === "text" && x.name === 'CarnetNo') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.carnetNo);
}
else if (x.type === "text" && x.name === 'AuthBy') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.AUTHREP);
}
else if (x.type === "text" && x.name === 'ContnSheetNo') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.CONTINUATIONSHEETS + "");
}
else if (x.type === "text" && x.name === 'GoodstobeExportedas') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.PRINTGOODSTOBEEXPORTED);
}
else if (x.type === "text" && x.name === 'IssuedOn') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
const formattedDate = toUSDateTime(carnetData.ISSUEDATE)
nameField.setText(formattedDate);
}
else if (x.type === "text" && x.name === 'IssuedBy') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
nameField.setText(carnetData.ISSUEDBY);
}
else if (x.type === "text" && x.name === 'ValidUntil') {
const nameField = form.getTextField(x.name);
nameField.setFontSize(CURRENT_FONT);
const formattedDate = toUSDateTime(carnetData.EXPDATE)
nameField.setText(formattedDate);
}
else if (x.type === "text" && x.name === 'HolderNameAddress') {
const nameField = form.getTextField(x.name);
nameField.enableMultiline();
nameField.setFontSize(CURRENT_FONT);
const multilineAddress = carnetData.HOLDERDATATOPRINT.replace(/~/g, "\n");
nameField.setText(multilineAddress);
}
});
form.flatten();
const filledPdfBytes = await pdfDoc.save();
const outputPath = path.join(__dirname, '../../..', 'public/carnet-pdf', 'p1.pdf');
const writeStream = fs.createWriteStream(outputPath);
writeStream.write(filledPdfBytes);
writeStream.end();
writeStream.on('finish', () => {
console.log("PDF has been successfully created and saved.");
resolve("p1 done"); // wait until file fully written
});
writeStream.on('error', err => {
console.error("Error writing PDF to file:", err);
reject(err);
});
} catch (err) {
reject(err);
}
});
};
export const generateFinalPDF = async (inputFiles: string[], outputFile: string) => {
const merger = new PDFMerger();