1685 lines
67 KiB
TypeScript
1685 lines
67 KiB
TypeScript
import {
|
||
BadRequestException,
|
||
InternalServerErrorException,
|
||
Logger,
|
||
} from '@nestjs/common';
|
||
import * as oracledb from 'oracledb';
|
||
|
||
const PDFDocument = require('pdfkit');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
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, TextAlignment, PDFTextField, PDFCheckBox, PDFRadioGroup, PDFDropdown, PDFOptionList } from 'pdf-lib';
|
||
import { PrintCarnetDTO, PrintGLDTO } from 'src/dto/property.dto';
|
||
|
||
const logger = new Logger('Helper');
|
||
|
||
export enum ResponseStatus {
|
||
created = 'Created Successfully',
|
||
updated = 'Updated Successfully',
|
||
defaultSpContactAdded = "Default contact was added successfully for SP",
|
||
inActivate = 'Inactivated Successfully',
|
||
reActivate = 'Reactivated Successfully',
|
||
clientRegistrationDone = 'Client registration initiated successfully',
|
||
lockedUserDone = 'Locked Successfully',
|
||
transmitted = 'Transmitted Successfully',
|
||
added = 'Added Successfully',
|
||
deleted = 'Deleted Successfully',
|
||
processed = 'Processed Successfully',
|
||
voided = 'Voided Successfully',
|
||
copied = 'Coppied Successfully',
|
||
duplicated = 'Duplicated Successfully',
|
||
addl_completed = 'Additional sets completed',
|
||
extended = 'Extended Successfully',
|
||
saved = 'Saved Successfully',
|
||
closed = 'Closed Successfully',
|
||
reset_successfull = 'Reset Successfull'
|
||
|
||
}
|
||
|
||
export function extractSubdomain(domain: string): string | null {
|
||
try {
|
||
const url = new URL(domain);
|
||
const hostname = url.hostname; // e.g., "der.asd.com", "localhost", "121.1.21.123"
|
||
|
||
// Return the full hostname if it's an IP address or 'localhost'
|
||
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) || hostname === 'localhost') {
|
||
return hostname;
|
||
}
|
||
|
||
const parts = hostname.split('.');
|
||
|
||
if (parts.length < 3) {
|
||
// Not enough parts to have a subdomain (e.g., "asd.com")
|
||
return null;
|
||
}
|
||
|
||
// Return the subdomain (leftmost part)
|
||
return parts[0];
|
||
} catch (e) {
|
||
console.error('Invalid domain:', domain, e);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
|
||
export function normalizeKeysToUpperCase(obj) {
|
||
return Object.keys(obj).reduce((acc, key) => {
|
||
acc[key.toUpperCase()] = obj[key];
|
||
return acc;
|
||
}, {});
|
||
}
|
||
|
||
export function toUpperCaseKeys(rows: Record<string, any>[]): Record<string, any>[] {
|
||
return rows.map(row => {
|
||
const transformedRow: Record<string, any> = {};
|
||
for (const key in row) {
|
||
transformedRow[key.toUpperCase()] = row[key];
|
||
}
|
||
return transformedRow;
|
||
});
|
||
}
|
||
|
||
|
||
|
||
export const handleError = (error: any, context: string = 'UnknownService'): never => {
|
||
if (error instanceof BadRequestException || error instanceof BR) {
|
||
logger.warn(`[${context}] ${error.message}`);
|
||
throw error;
|
||
}
|
||
|
||
if (error.message?.includes('NJS-107')) {
|
||
logger.warn(`[${context}] Invalid cursor encountered: ${error.message}`);
|
||
throw new BadRequestException('Invalid database response.');
|
||
}
|
||
|
||
if (error.message?.includes('ORA-')) {
|
||
logger.error(`[${context}] Oracle error occurred: ${error.message}`);
|
||
throw new InternalServerErrorException(error.message);
|
||
}
|
||
|
||
logger.error(`[${context}] Unexpected error:`, error.stack || error);
|
||
throw new InternalServerErrorException(error.message || 'Internal error');
|
||
};
|
||
|
||
export const handlePgError = (error: any, context: string = 'UnknownService'): never => {
|
||
if (error instanceof BadRequestException || error instanceof BR) {
|
||
logger.warn(`[${context}] ${error.message}`);
|
||
throw error;
|
||
}
|
||
logger.error(`[${context}] Unexpected error:`, error.message);
|
||
throw new InternalServerErrorException(error.message || 'Internal error');
|
||
}
|
||
|
||
export function releasePgClient(client: any) {
|
||
if (client && typeof client.release === 'function') {
|
||
try {
|
||
client.release();
|
||
} catch (err) {
|
||
console.error('Error releasing client:', err);
|
||
}
|
||
}
|
||
}
|
||
|
||
export const checkPgUserDefinedErrors = (fetchResult: any) => {
|
||
if (fetchResult?.rows?.[0]?.errormesg) {
|
||
throw new BadRequestException(fetchResult?.rows?.[0]?.errormesg);
|
||
}
|
||
}
|
||
|
||
|
||
export const closeOracleDbConnection = async (connection: any, context: string = 'UnknownService'): Promise<void> => {
|
||
if (connection) {
|
||
try {
|
||
await connection.close();
|
||
} catch (closeErr) {
|
||
logger.error(`[${context}] Failed to close DB connection`, closeErr.stack || closeErr);
|
||
}
|
||
}
|
||
};
|
||
|
||
export const fetchCursor = async <T>(cursor: oracledb.ResultSet<T>, context: string = 'UnknownService'): Promise<T[]> => {
|
||
try {
|
||
const rows = await cursor.getRows();
|
||
await cursor.close();
|
||
return rows;
|
||
} catch (err) {
|
||
logger.error(`[${context}] Failed to fetch from cursor`, err.stack || err);
|
||
throw new InternalServerErrorException('Error reading data from database.');
|
||
}
|
||
};
|
||
|
||
export const setEmptyStringsToNull = (obj: any): void => {
|
||
Object.keys(obj).forEach((key) => {
|
||
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
||
setEmptyStringsToNull(obj[key]);
|
||
} else if (obj[key] === '') {
|
||
obj[key] = null;
|
||
}
|
||
});
|
||
}
|
||
|
||
export interface pdfGLData {
|
||
itemNo: number;
|
||
description: string;
|
||
noOfPieces: number;
|
||
weight: string;
|
||
itemValue: number;
|
||
countryOfOrigin: string
|
||
}
|
||
|
||
export interface pdfCarnetData {
|
||
carnetNo: string;
|
||
ISSUEDBY: string;
|
||
ISSUEDATE: string;
|
||
EXPDATE: string;
|
||
AUTHREP: string;
|
||
NOOFUSSETS: number;
|
||
NOOFFOREIGNSETS: number;
|
||
NOOFTRANSITSETS: number;
|
||
PRINTGOODSTOBEEXPORTED: string;
|
||
HOLDERDATATOPRINT: string;
|
||
CONTINUATIONSHEETS: number;
|
||
NEXTUSCFNO: number;
|
||
NEXTFOREIGNCFNO: number;
|
||
NEXTTRANSITCFNO: number;
|
||
contPageNo: number; // for GL table only
|
||
}
|
||
|
||
function formatNumber(num) {
|
||
if (isNaN(num)) return 'N/A';
|
||
return num.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||
}
|
||
|
||
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 `${year}-${month}-${day}`;
|
||
}
|
||
|
||
export function replaceSlashWithDash(input) {
|
||
return input.replace(/\//g, '-');
|
||
}
|
||
|
||
const PDF_LOCAL_PATH: string = "../../../public/carnet-pdf";
|
||
const PDF_SERVER_PATH: string = "../../public/carnet-pdf";
|
||
const PDF_URL = PDF_SERVER_PATH
|
||
|
||
export const generateGreenCoverPDF = (carnetData: pdfCarnetData) => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '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, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}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 generateUSCounterFoilFront = (carnetData: pdfCarnetData, t1: string, t2: string, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '3USCounterFoilFront.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 };
|
||
});
|
||
|
||
// console.log(fieldInfo);
|
||
|
||
|
||
fieldInfo.forEach(x => {
|
||
if (x.type === "text" && x.name === 'Document No1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else 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 === 'Document No2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t1);
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t2);
|
||
}
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}USFront.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
|
||
pn++;
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${dn}USFront.pdf has been successfully created and saved.`);
|
||
resolve(Number(dn)); // 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 generateUSCounterFoilBack = (carnetData: pdfCarnetData, t1: string, t2: string, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '4USCounterFoilBack.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 === 'Document No1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else 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 === 'Document No2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t1);
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t2);
|
||
}
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}USBack.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
pn++
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${pn}USBack.pdf` + " has been successfully created and saved.");
|
||
resolve(Number(dn)); // 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 generateFNCounterFoilFront = (carnetData: pdfCarnetData, t1: string, t2: string, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '6ForeignCounterfoilFront.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 };
|
||
});
|
||
|
||
// console.log(fieldInfo);
|
||
|
||
|
||
fieldInfo.forEach(x => {
|
||
if (x.type === "text" && x.name === 'DocumentNo1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else 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 === 'DocumentNo2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t1);
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t2);
|
||
}
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}FNFront.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
|
||
pn++;
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${dn}FNFront.pdf has been successfully created and saved.`);
|
||
resolve(Number(dn)); // 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 generateFNCounterFoilBack = (carnetData: pdfCarnetData, t1: string, t2: string, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '7ForeignCounterFoilBack.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 === 'DocumentNo1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else 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 === 'DocumentNo2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t1);
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t2);
|
||
}
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}FNBack.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
pn++
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${pn}FNBack.pdf` + " has been successfully created and saved.");
|
||
resolve(Number(dn)); // 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 generateTSCounterFoilFront = (carnetData: pdfCarnetData, t1: string, t2: string, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '8TransitCounterFoilFront.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 };
|
||
});
|
||
|
||
// console.log(fieldInfo);
|
||
|
||
|
||
fieldInfo.forEach(x => {
|
||
if (x.type === "text" && x.name === 'DocumentNo1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else 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 === 'DocumentNo2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t1);
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t2);
|
||
}
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}TSFront.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
|
||
pn++;
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${dn}TSFront.pdf has been successfully created and saved.`);
|
||
resolve(Number(dn)); // 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 generateTSCounterFoilBack = (carnetData: pdfCarnetData, t1: string, t2: string, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '9TransitCounterfoilBack.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 === 'DocumentNo1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else 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 === 'DocumentNo2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t2 === "VALUE") {
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else {
|
||
nameField.setText("VOID");
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText1') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t1);
|
||
}
|
||
}
|
||
else if (x.type === "text" && x.name === 'PrintVoidText2') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
if (t1 === "VOID") {
|
||
nameField.setAlignment(TextAlignment.Center);
|
||
nameField.setText(t1);
|
||
}
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}TSBack.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
pn++
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${pn}TSBack.pdf` + " has been successfully created and saved.");
|
||
resolve(Number(dn)); // 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 generateFNImportV = (carnetData: pdfCarnetData, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '10ImportVoucher.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 };
|
||
});
|
||
|
||
// console.log(fieldInfo);
|
||
|
||
|
||
fieldInfo.forEach(x => {
|
||
if (x.type === "text" && x.name === 'Valid Until') {
|
||
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 === 'CarnetNo') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.carnetNo);
|
||
}
|
||
else if (x.type === "text" && x.name === 'HolderNameAddress') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
const multilineAddress = carnetData.HOLDERDATATOPRINT.replace(/~/g, "\n");
|
||
nameField.setText(multilineAddress);
|
||
}
|
||
else if (x.type === "text" && x.name === 'VoucherNo') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else if (x.type === "text" && x.name === 'AuthorizedBy') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.AUTHREP);
|
||
}
|
||
else if (x.type === "text" && x.name === 'GoodsDescription') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.PRINTGOODSTOBEEXPORTED);
|
||
}
|
||
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 === 'Issued') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
const formattedDate = toUSDateTime(carnetData.ISSUEDATE)
|
||
nameField.setText(formattedDate);
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}FNImportV.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
|
||
pn++;
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${dn}FNImportV.pdf has been successfully created and saved.`);
|
||
resolve(Number(dn)); // 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 generateFNExportV = (carnetData: pdfCarnetData, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '11ExportVoucher.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 };
|
||
});
|
||
|
||
// console.log(fieldInfo);
|
||
|
||
|
||
fieldInfo.forEach(x => {
|
||
if (x.type === "text" && x.name === 'Valid Until') {
|
||
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 === 'CarnetNo') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.carnetNo);
|
||
}
|
||
else if (x.type === "text" && x.name === 'HolderNameAddress') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
const multilineAddress = carnetData.HOLDERDATATOPRINT.replace(/~/g, "\n");
|
||
nameField.setText(multilineAddress);
|
||
}
|
||
else if (x.type === "text" && x.name === 'VoucherNo') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else if (x.type === "text" && x.name === 'AuthorizedBy') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.AUTHREP);
|
||
}
|
||
else if (x.type === "text" && x.name === 'GoodsDescription') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.PRINTGOODSTOBEEXPORTED);
|
||
}
|
||
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 === 'Issued') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
const formattedDate = toUSDateTime(carnetData.ISSUEDATE)
|
||
nameField.setText(formattedDate);
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}FNExportV.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
|
||
pn++;
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${dn}FNExportV.pdf has been successfully created and saved.`);
|
||
resolve(Number(dn)); // 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 generateTNV = (carnetData: pdfCarnetData, dn: number, pn: number): Promise<number | any> => {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '12TransitVoucher.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 };
|
||
});
|
||
|
||
// console.log(fieldInfo);
|
||
|
||
|
||
fieldInfo.forEach(x => {
|
||
if (x.type === "text" && x.name === 'Valid Until') {
|
||
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 === 'CarnetNo') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.carnetNo);
|
||
}
|
||
else if (x.type === "text" && x.name === 'HolderNameAddress') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
const multilineAddress = carnetData.HOLDERDATATOPRINT.replace(/~/g, "\n");
|
||
nameField.setText(multilineAddress);
|
||
}
|
||
else if (x.type === "text" && x.name === 'VoucherNo') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(dn + "");
|
||
dn++;
|
||
}
|
||
else if (x.type === "text" && x.name === 'AuthorizedBy') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.AUTHREP);
|
||
}
|
||
else if (x.type === "text" && x.name === 'GoodsDescription') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(carnetData.PRINTGOODSTOBEEXPORTED);
|
||
}
|
||
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 === 'Issued') {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
const formattedDate = toUSDateTime(carnetData.ISSUEDATE)
|
||
nameField.setText(formattedDate);
|
||
}
|
||
});
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}${pn}TNV.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(filledPdfBytes);
|
||
writeStream.end();
|
||
|
||
pn++;
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log(`${dn}TNV.pdf has been successfully created and saved.`);
|
||
resolve(Number(dn)); // wait until file fully written
|
||
});
|
||
|
||
writeStream.on('error', err => {
|
||
console.error("Error writing PDF to file:", err);
|
||
reject(err);
|
||
});
|
||
|
||
} catch (err) {
|
||
reject(err);
|
||
}
|
||
});
|
||
}
|
||
|
||
function getPatternArray(n) {
|
||
if (n < 1) {
|
||
return [];
|
||
}
|
||
|
||
const numFours = Math.floor((n - 1) / 4);
|
||
|
||
// Create an array with the leading 4s
|
||
const result = Array(numFours).fill(4);
|
||
|
||
// Calculate and add the final number
|
||
const lastNumber = (n - 1) % 4 + 1;
|
||
result.push(lastNumber);
|
||
|
||
return result;
|
||
}
|
||
|
||
export function generateGL1(carnetData: pdfCarnetData): Promise<any> {
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '2GeneralListSeeattached.pdf');
|
||
const existingPdfBytes = fs.readFileSync(templatePath);
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`);
|
||
const writeStream = fs.createWriteStream(outputPath);
|
||
|
||
writeStream.write(existingPdfBytes);
|
||
writeStream.end();
|
||
|
||
writeStream.on('finish', () => {
|
||
// console.log("PDF has been successfully created and saved.");
|
||
resolve("p2 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 async function processGlDataInBatches(
|
||
glDataArray: pdfGLData[],
|
||
batchSize: number,
|
||
carnetData: pdfCarnetData, // carnetData is a parameter here
|
||
body: PrintGLDTO,
|
||
batchCallback: (batch: pdfGLData[], batchNumber: number, startIndex: number, endIndex: number) => Promise<void>
|
||
): Promise<number> {
|
||
if (!Array.isArray(glDataArray)) {
|
||
throw new Error("Input 'glDataArray' must be an array.");
|
||
}
|
||
|
||
const totalLength: number = glDataArray.length;
|
||
console.log(`✨ [Batch Processor] Starting batch processing for ${totalLength} items.`);
|
||
console.log(`📦 [Batch Processor] Batch size set to ${batchSize} items.`);
|
||
|
||
if (totalLength === 0) {
|
||
console.log("ℹ️ [Batch Processor] Array is empty. No batches to process.");
|
||
return 0;
|
||
}
|
||
|
||
let batchNumber: number = 1;
|
||
for (let i: number = 0; i < totalLength; i += batchSize) {
|
||
const startIndex: number = i;
|
||
const endIndex: number = Math.min(i + batchSize, totalLength);
|
||
|
||
// console.log("item i : ", i);
|
||
|
||
|
||
// Extract the current batch using slice, creating a new array for the batch
|
||
const currentBatch: pdfGLData[] = glDataArray.slice(startIndex, endIndex);
|
||
|
||
// Log the particular batch data here
|
||
// console.log(`🔍 [Batch Processor] Details for Batch ${batchNumber} (Items ${startIndex} to ${endIndex - 1}):`, JSON.stringify(currentBatch, null, 2));
|
||
|
||
// Define pdfGeneration function *inside* the loop for each iteration
|
||
// Modified to accept and log batchNumber for clearer output
|
||
|
||
async function pdfGeneration(data: pdfCarnetData, currentBatchNumber: number) {
|
||
// console.log(`📄 [PDF Generation] Calling PDF generation for Batch ${currentBatchNumber}. Carnet Data:`, JSON.stringify(data, null, 2));
|
||
// Added a small delay to ensure logs are flushed
|
||
// await new Promise(resolve => setTimeout(resolve, 50));
|
||
// return;
|
||
function transformGlDataForDisplay(glDataArray: any[]): any[] {
|
||
if (!Array.isArray(glDataArray)) {
|
||
console.error("Input for transformGlDataForDisplay must be an array.");
|
||
return [];
|
||
}
|
||
|
||
const transformedData: any[] = [];
|
||
|
||
glDataArray.forEach((item, index) => {
|
||
const rowNumber = index + 1; // 1-based index for "RowX"
|
||
transformedData.push(
|
||
{ name: `Item NoRow${rowNumber}`, value: item.itemNo, type: "text" },
|
||
{ name: `DescriptionRow${rowNumber}`, value: item.description, type: "text" },
|
||
{ name: `No of piecesRow${rowNumber}`, value: item.noOfPieces, type: "text" },
|
||
{ name: `WeightRow${rowNumber}`, value: item.weight, type: "text" },
|
||
{ name: `Item ValueRow${rowNumber}`, value: item.itemValue, type: "text" },
|
||
{ name: `Origin CountryRow${rowNumber}`, value: item.countryOfOrigin, type: "text" }
|
||
);
|
||
});
|
||
|
||
return transformedData;
|
||
}
|
||
|
||
function calculateTotalItemValue(glDataArray: any[]): number {
|
||
if (!Array.isArray(glDataArray)) {
|
||
console.error("Input for calculateTotalItemValue must be an array.");
|
||
return 0;
|
||
}
|
||
|
||
let totalItemValue = 0;
|
||
for (const item of glDataArray) {
|
||
if (typeof item.itemValue === 'number') {
|
||
totalItemValue += item.itemValue;
|
||
} else {
|
||
console.warn(`Non-numeric itemValue encountered for itemNo: ${item.itemNo}. Skipping value.`);
|
||
}
|
||
}
|
||
let value = formatNumber(totalItemValue)
|
||
|
||
// console.log(`total for batch ${batchNumber} : `, value);
|
||
|
||
return value;
|
||
}
|
||
|
||
return new Promise(async (resolve, reject) => {
|
||
try {
|
||
const templatePath = path.join(__dirname, PDF_URL, '2GeneralList.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 };
|
||
});
|
||
|
||
// console.log(fieldInfo);
|
||
|
||
const fdata = transformGlDataForDisplay(currentBatch);
|
||
|
||
fdata.forEach(x => {
|
||
// if (x.type === "text" && x.name === 'CarnetNo') {
|
||
// const nameField = form.getTextField(x.name);
|
||
// // nameField.setFontSize(CURRENT_FONT);
|
||
// nameField.setText(carnetData.carnetNo);
|
||
// }
|
||
|
||
if (/^Item ValueRow\d+$/.test(x.name)) {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
let ThousandSeparatorValue = formatNumber(x.value);
|
||
nameField.setAlignment(TextAlignment.Right);
|
||
nameField.setText(ThousandSeparatorValue + "");
|
||
}
|
||
else {
|
||
const nameField = form.getTextField(x.name);
|
||
// nameField.setFontSize(CURRENT_FONT);
|
||
nameField.setText(x.value + "");
|
||
}
|
||
|
||
});
|
||
|
||
const TotPageItemValue = form.getTextField('TotPageItemValue');
|
||
TotPageItemValue.setFontSize(CURRENT_FONT);
|
||
let totalValue = calculateTotalItemValue(currentBatch);
|
||
TotPageItemValue.setAlignment(TextAlignment.Right);
|
||
TotPageItemValue.setText(totalValue + "");
|
||
|
||
const carnetNoField = form.getTextField('Carnet No');
|
||
carnetNoField.setFontSize(CURRENT_FONT);
|
||
carnetNoField.setText(data.carnetNo + "");
|
||
|
||
const contnSheetNoField = form.getTextField('ContnSheet No');
|
||
contnSheetNoField.setFontSize(CURRENT_FONT);
|
||
contnSheetNoField.setText((currentBatchNumber - 1) + "");
|
||
|
||
form.flatten();
|
||
const filledPdfBytes = await pdfDoc.save();
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, `${body.P_HEADERID}p2gl${currentBatchNumber}.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);
|
||
}
|
||
});
|
||
}
|
||
|
||
// Call pdfGeneration for *each* batch, passing the carnetData and current batch number
|
||
await pdfGeneration(carnetData, batchNumber);
|
||
|
||
|
||
// Await the processing of the current batch to ensure sequential execution.
|
||
await batchCallback(currentBatch, batchNumber, startIndex, endIndex);
|
||
|
||
batchNumber++; // Increment batch number for the next iteration
|
||
}
|
||
|
||
|
||
console.log(`✅ [Batch Processor] Batch processing complete. Total batches processed: ${batchNumber - 1}`);
|
||
return batchNumber
|
||
}
|
||
|
||
export async function generateGL(glData: pdfGLData[], carnetData: pdfCarnetData, body: PrintGLDTO): Promise<any> {
|
||
const BATCH_SIZE = 38;
|
||
const totalLength = glData.length;
|
||
|
||
console.log(`--- Initiating generateGL for ${totalLength} items ---`);
|
||
|
||
// The inner function that logs the received array length
|
||
// This is passed as the batchCallback to processGlDataInBatches
|
||
const innerLogFunction = async (batch: pdfGLData[], batchNumber: number) => {
|
||
console.log(`Received batch ${batchNumber}. Array length: ${batch.length}`);
|
||
// Added a small delay to ensure logs are flushed
|
||
await new Promise(resolve => setTimeout(resolve, 50));
|
||
};
|
||
|
||
// Call the existing processGlDataInBatches function and await its completion
|
||
try {
|
||
const loop = await processGlDataInBatches(glData, BATCH_SIZE, carnetData, body, innerLogFunction);
|
||
console.log("--- generateGL function completed ---");
|
||
let fileArray: string[] = []
|
||
for (let i = 1; i < loop; i++) {
|
||
fileArray.push(`${body.P_HEADERID}p2gl${i}.pdf`)
|
||
}
|
||
return { fileArray, batch: loop - 1 };
|
||
} catch (error) {
|
||
console.error("Error in generateGL batch processing:", error);
|
||
throw error; // Re-throw the error for the caller to handle
|
||
}
|
||
}
|
||
|
||
export function generateMockGlData(count: number): any[] {
|
||
const mockData: any[] = [];
|
||
for (let i: number = 1; i <= count; i++) {
|
||
mockData.push({
|
||
ITEMNO: i,
|
||
ITEMDESCRIPTION: `Product Component ${i}`,
|
||
NOOFPIECES: Math.floor(Math.random() * 20) + 1,
|
||
WEIGHT: `${(Math.random() * 100).toFixed(2)} kg`,
|
||
ITEMVALUE: parseFloat((Math.random() * 5000).toFixed(2)),
|
||
GOODSORIGINCOUNTRY: ['USA', 'Canada', 'Germany', 'China', 'Japan'][
|
||
Math.floor(Math.random() * 5)
|
||
],
|
||
});
|
||
}
|
||
return mockData;
|
||
}
|
||
|
||
// console.log(generateMockGlData(40))
|
||
|
||
|
||
export async function usCounterFoil(carnetData: pdfCarnetData) {
|
||
let documentNo = carnetData.NEXTUSCFNO;
|
||
let fpdf = 1;
|
||
const set = getPatternArray(carnetData.NOOFUSSETS)
|
||
|
||
const generatedFiles: any = [];
|
||
|
||
for (const s of set) {
|
||
// console.log(" Current pattern value (s): ", s);
|
||
|
||
// This is where you would use the 's' value to determine arguments
|
||
// For now, let's keep the arguments constant as per your example
|
||
const funFrontSecondArg = s > 1 ? "VALUE" : "VOID";
|
||
const funBackFirstArg = s > 2 ? "VALUE" : "VOID";
|
||
const funBackSecondArg = s > 3 ? "VALUE" : "VOID";
|
||
|
||
// Step 1: Await front PDF generation
|
||
let inc1: number = await generateUSCounterFoilFront(carnetData, "VALUE", funFrontSecondArg, documentNo, fpdf);
|
||
documentNo = inc1;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}USFront.pdf`);
|
||
|
||
// Step 2: Await back PDF generation
|
||
let inc2: number = await generateUSCounterFoilBack(carnetData, funBackFirstArg, funBackSecondArg, documentNo, fpdf);
|
||
documentNo = inc2;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}USBack.pdf`);
|
||
|
||
// Increment fpdf for the next loop
|
||
fpdf++;
|
||
}
|
||
|
||
// console.log("All US Counter Foil PDFs have been completely generated.");
|
||
// console.log(generatedFiles);
|
||
|
||
|
||
// Return the list of generated filenames
|
||
return generatedFiles;
|
||
}
|
||
|
||
export async function fnCounterFoil(carnetData: pdfCarnetData) {
|
||
let documentNo = carnetData.NEXTFOREIGNCFNO;
|
||
let fpdf = 1;
|
||
const set = getPatternArray(carnetData.NOOFFOREIGNSETS)
|
||
|
||
const generatedFiles: any = [];
|
||
|
||
for (const s of set) {
|
||
|
||
// This is where you would use the 's' value to determine arguments
|
||
// For now, let's keep the arguments constant as per your example
|
||
const funFrontSecondArg = s > 1 ? "VALUE" : "VOID";
|
||
const funBackFirstArg = s > 2 ? "VALUE" : "VOID";
|
||
const funBackSecondArg = s > 3 ? "VALUE" : "VOID";
|
||
|
||
// Step 1: Await front PDF generation
|
||
let inc1: number = await generateFNCounterFoilFront(carnetData, "VALUE", funFrontSecondArg, documentNo, fpdf);
|
||
documentNo = inc1;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}FNFront.pdf`);
|
||
|
||
// Step 2: Await back PDF generation
|
||
let inc2: number = await generateFNCounterFoilBack(carnetData, funBackFirstArg, funBackSecondArg, documentNo, fpdf);
|
||
documentNo = inc2;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}FNBack.pdf`);
|
||
|
||
// Increment fpdf for the next loop
|
||
fpdf++;
|
||
}
|
||
|
||
// console.log("All US Counter Foil PDFs have been completely generated.");
|
||
// console.log(generatedFiles);
|
||
|
||
// Return the list of generated filenames
|
||
return generatedFiles;
|
||
}
|
||
|
||
export async function tsCounterFoil(carnetData: pdfCarnetData) {
|
||
let documentNo = carnetData.NEXTTRANSITCFNO;
|
||
let fpdf = 1;
|
||
const set = getPatternArray(carnetData.NOOFTRANSITSETS)
|
||
|
||
const generatedFiles: any = [];
|
||
|
||
for (const s of set) {
|
||
// console.log(" Current pattern value (s): ", s);
|
||
|
||
// This is where you would use the 's' value to determine arguments
|
||
// For now, let's keep the arguments constant as per your example
|
||
const funFrontSecondArg = s > 1 ? "VALUE" : "VOID";
|
||
const funBackFirstArg = s > 2 ? "VALUE" : "VOID";
|
||
const funBackSecondArg = s > 3 ? "VALUE" : "VOID";
|
||
|
||
// console.log("document no : ", s, " : ", documentNo);
|
||
|
||
|
||
// Step 1: Await front PDF generation
|
||
let inc1: number = await generateTSCounterFoilFront(carnetData, "VALUE", funFrontSecondArg, documentNo, fpdf);
|
||
|
||
documentNo = inc1;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}TSFront.pdf`);
|
||
|
||
// Step 2: Await back PDF generation
|
||
let inc2: number = await generateTSCounterFoilBack(carnetData, funBackFirstArg, funBackSecondArg, documentNo, fpdf);
|
||
|
||
documentNo = inc2;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}TSBack.pdf`);
|
||
|
||
|
||
// Increment fpdf for the next loop
|
||
fpdf++;
|
||
}
|
||
|
||
// console.log("All US Counter Foil PDFs have been completely generated.");
|
||
// console.log(generatedFiles);
|
||
|
||
// Return the list of generated filenames
|
||
return generatedFiles;
|
||
}
|
||
|
||
export async function fnVochers(carnetData: pdfCarnetData, body: PrintCarnetDTO) {
|
||
let importNo = 1;
|
||
let exportNo = 1;
|
||
let fpdf = 1;
|
||
const set = (carnetData.NOOFFOREIGNSETS)
|
||
|
||
const generatedFiles: any = [];
|
||
|
||
for (let i = 1; i <= set; i++) {
|
||
|
||
// Step 1: Await back PDF generation
|
||
let inc1: number = await generateFNImportV(carnetData, importNo, fpdf);
|
||
importNo = inc1;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}FNImportV.pdf`);
|
||
if (body.P_PRINTGL === 'Y') {
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`);
|
||
}
|
||
|
||
// Step 2: Await back PDF generation
|
||
let inc2: number = await generateFNExportV(carnetData, exportNo, fpdf);
|
||
exportNo = inc2;
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}FNExportV.pdf`);
|
||
if (body.P_PRINTGL === 'Y') {
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`);
|
||
}
|
||
|
||
// Increment fpdf for the next loop
|
||
fpdf++;
|
||
}
|
||
|
||
// console.log("All US Counter Foil PDFs have been completely generated.");
|
||
// console.log(generatedFiles);
|
||
|
||
|
||
// Return the list of generated filenames
|
||
return generatedFiles;
|
||
}
|
||
|
||
export async function tnVochers(carnetData: pdfCarnetData, body: PrintCarnetDTO) {
|
||
let tnNo = 1;
|
||
let fpdf = 1;
|
||
const set = (carnetData.NOOFTRANSITSETS)
|
||
|
||
const generatedFiles: any = [];
|
||
|
||
for (let i = 1; i <= set; i++) {
|
||
// console.log(" Current pattern value (s): ", s);
|
||
|
||
let inc1: number = await generateTNV(carnetData, tnNo, fpdf);
|
||
tnNo = inc1;
|
||
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}${fpdf}TNV.pdf`);
|
||
if (body.P_PRINTGL === 'Y') {
|
||
generatedFiles.push(`${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`);
|
||
}
|
||
|
||
fpdf++;
|
||
}
|
||
|
||
// console.log("All US Counter Foil PDFs have been completely generated.");
|
||
// console.log(generatedFiles);
|
||
|
||
return generatedFiles;
|
||
}
|
||
|
||
export const generateFinalPDF = async (inputFiles: string[], outputFile: string) => {
|
||
|
||
const merger = new PDFMerger();
|
||
|
||
for (const fileName of inputFiles) {
|
||
const filePath = path.join(__dirname, PDF_URL, fileName);
|
||
// console.log(`Does the file exist? ${existsSync(filePath)}`);
|
||
// console.log(`📄 Adding: ${filePath}`);
|
||
|
||
try {
|
||
const fileData = readFileSync(filePath);
|
||
await merger.add(fileData);
|
||
} catch (err) {
|
||
console.error(`❌ Failed to add PDF: ${fileName}`, err);
|
||
}
|
||
}
|
||
|
||
const outputPath = path.join(__dirname, PDF_URL, outputFile);
|
||
|
||
try {
|
||
await merger.save(outputPath);
|
||
// console.log(`✅ Merged PDF saved to ${outputPath}`);
|
||
} catch (err) {
|
||
console.error(`❌ Failed to save merged PDF`, err);
|
||
throw new Error("Failed to save merged PDF");
|
||
}
|
||
};
|
||
|
||
export const deleteFilesAsync = async (relativeFilePaths: string[]): Promise<void> => {
|
||
for (const relativeFilePath of relativeFilePaths) {
|
||
const filePath = path.join(__dirname, PDF_URL, relativeFilePath);
|
||
|
||
if (fs.existsSync(filePath)) {
|
||
try {
|
||
await fsPromises.unlink(filePath);
|
||
// console.log(`🗑️ Deleted: ${filePath}`);
|
||
} catch (err) {
|
||
console.error(`❌ Error deleting file: ${filePath}`, err);
|
||
}
|
||
} else {
|
||
console.warn(`⚠️ File not found: ${filePath}`);
|
||
}
|
||
}
|
||
}; |