DockerERTFF/public/js/libProcessScript.js

277 lines
9.0 KiB
JavaScript

// JavaScript Document
// Replaces libPDFscripts.js
// NEW - Process Scripts
//
// ** OFFICIAL SCRIPT TO USE WHEN IN PRODUCTION
//
// Function to add Authenticator validation https://www.npmjs.com/package/speakeasy
// Utility to fetch PDF bytes
console.log("LIBRARY: libProcessScript.js")
const dd = createDebugLogger(true, "dd"); // code function at bottom of the page
// Wrapper function to fetch, update, and download PDF
async function processAndDownloadPdf(filePath, ...dataSources) {
console.log(filePath)
try {
const pdfBytes = await fetchPdfBytes(filePath);
const updatedPdfBytes = await updatePdfFields(pdfBytes, dataSources);
const fileName = generateRandomFilename(8, "ERT_", ".pdf");
//const saveFilePath = await savePdfToFile(pdfBytes);
//dd("[PDF PATH]", saveFilePath);
downloadPdf(updatedPdfBytes, fileName);
} catch (err) {
dd("Error Processing PDF", err)
//console.error("Error processing the PDF:", err);
}
}
async function fetchPdfBytes(filePath) {
try {
const response = await fetch(filePath);
if (!response.ok) throw new Error(`Failed to fetch PDF from ${filePath}`);
return await response.arrayBuffer();
} catch (err) {
console.error("Error fetching PDF bytes:", err);
throw err;
}
}
// Update form fields in the PDF
async function updatePdfFields(
pdfBytes,
dataSources,
//skipMissingFields = false
) {
console.log("Datasources Count:", dataSources.length)
console.log(JSON.stringify(dataSources, null, 2));
// try {
const pdfDoc = await PDFLib.PDFDocument.load(pdfBytes);
const form = pdfDoc.getForm();
dataSources.forEach((dataSource, dsIndex) => {
console.log(`Processing dataSource[${dsIndex}]:`, dataSource);
if (!Array.isArray(dataSource)) {
console.warn(`dataSource[${dsIndex}] is not an array. Skipping.`);
return;
}
let ii = 0
dataSource.forEach((record, recIndex) => {
if (ii == 0) {
console.log(JSON.stringify(record, null, 2))
}
console.log(`Processing record[${recIndex}]:`, record);
if (!record || typeof record !== 'object') {
console.warn(`record[${recIndex}] is undefined or not an object. Skipping.`);
return;
}
// Extract numSection and pointValue dynamically or other 'key' components.
/**
* Working area - to wrap assignment of numSection, pointValue or a Key-Value for other datasources.
* so far this is working and success on downloading the PDF prefilled on the score.
*/
const recordToKeyArray = Object.keys(record).includes("$id")
if (recordToKeyArray) { console.log("$ID EXIST") }
const { numSection, pointValue } = record;
const rKey = numSection
const rValue = pointValue
//const pointValue = record.pointValue || record.Points; // Fallback to Points if pointValue is missing
console.log(`[numSection 2 key ==>] ${rKey} --> ${rValue}`)
if (numSection && pointValue) {
console.log(`Updating PDF field: ${numSection} with value: ${pointValue}`);
try {
// Use numSection as the dynamic field name
//const formField = form.getTextField(numSection);
const formField = form.getFieldMaybe(String(numSection)); // if cannot find, then just returns 'undefined' rather than throw err.
if (formField) {
ii++
formField.setText(String(pointValue));
console.log(`Field "${numSection}" updated with value "${pointValue}".`);
} else {
console.warn(`Field "${numSection}" not found in PDF.`);
}
} catch (err) {
console.error(`Error updating field "${numSection}":`, err);
}
} else {
console.warn(`Missing numSection or pointValue in record[${recIndex}].`);
}
});
console.log(`${ii} Form field updates complete.`);
ii = 0;
});
return await pdfDoc.save(); /// MOVE TO the Main PROCESS and DOWNLOD PDF function or as last call. (need await??) Maybe make it an actual 'ready' to download button.
}
// Function to trigger download of the updated PDF
function downloadPdf(pdfBytes, fileName) {
const blob = new Blob([pdfBytes], { type: "application/pdf" });
const url = URL.createObjectURL(blob);
const link = Object.assign(document.createElement("a"), {
href: url,
download: fileName,
});
console.log("DOWNLOAD Filled PDF")
link.click();
URL.revokeObjectURL(url); // Clean up the URL immediately
}
function generateRandomFilename(length = 8, prefix = "", suffix = "") {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const array = Array.from({ length }, () =>
characters.charAt(Math.floor(Math.random() * characters.length))
);
const filename = `${prefix}${array.join("")}${suffix}`;
//dd("Random Filename:", filename);
return filename;
}
// Example Usage:
async function savePdfToFile(pdfBytes) {
const randomFilename = generateRandomFilename(12, "", ".pdf");
File.path;
const filePath = Filehandle.path.join(__dirname, "PDF", randomFilename);
dd("[SAVE TO DISK]", randomFilename);
// Save the file to disk
await fs.writeFile(filePath, Buffer.from(pdfBytes));
// Return a URL or file path based on your server setup
return `/PDF/${randomFilename}`;
}
function createDebugLogger(debug, prefix = "DD") {
return function (message, ...optionalParams) {
switch (debug) {
case true:
console.log(
`[${prefix}]`.toUpperCase(), `${message}`, ...optionalParams);
break
}
};
}
function saveSignature_OFF() { //Testing a new function under dummyfunctions section
const canvas = document.getElementById('signatureCanvas');
const imageData = canvas.toDataURL('image/png');
dd(imageData.length)
// Trigger the server action and handle the response
dmx.parse('serverconnect_sign.load({imageData: "' + imageData + '"})');
//dmx.parse('serverconnect_sign.load({ image: imageData })');
/**
dmx.parse('serverconnect_sign.load', { image: imageData }).then((response) => {
//dmx.parse('serverconnect_sign.load({image: "' + imageData + '"})').then((response) => {
const uploadedSignature = document.getElementById('uploadedSignature');
uploadedSignature.src = response.fileUrl; // Use the file path returned from the server
dd(response.fileUrl)
}).catch((error) => {
console.error("Error uploading signature:", error);
});
*/
}
// ************** DUMMY TEST FUNCTIONS BELOW ****************** //
function runMyFunction() {
// alert("function run")
let result = generateRandomIdentifier(9);
// Use Wappler dmx.set to bind result to a Wappler variable if needed
//<p>{{myResult}}</p>
console.log(result)
dmx.global.set('myResult', result);
}
function generateRandomIdentifier(v) {
return generateRandomFilename(v)
}
function saveSignature() {
const canvas = document.getElementById('signatureCanvas');
const imageData = canvas.toDataURL('image/png'); // Convert the canvas to a Base64 image string
dd("Got Signature:", imageData)
dmx.parse('serverconnect_sign.load({image: "' + imageData + '"})').then((response) => {
const uploadedSignature = document.getElementById('uploadedSignature');
dd(uploadedSignature)
dd("Response:", response.fileUrl)
uploadedSignature.src = response.fileUrl; // Set the uploaded file URL to the image element
}).catch((error) => {
console.error("Error uploading signature:", error);
});
}
function saveSignatureAsBase64() {
//const canvas = document.getElementById('signatureCanvas');
return document.getElementById('signatureCanvas').toDataURL('image/png'); // Get the Base64 string
}
function getSignatureData() {
dmx.global.set('signatureDataEncoded', saveSignatureAsBase64())
dd('SignatureData:', saveSignatureAsBase64())
}
function saveSignatureNew() {
const canvas = document.getElementById('signatureCanvas');
const imageData = canvas.toDataURL('image/png'); // Convert the canvas to a Base64 image string
dd("Got Signature:", imageData)
dmx.app.data.content.serverconnect_sign.__load({ imageData: imageData }).then((response) => {
dd("Success:", response);
const uploadedSignature = document.getElementById('uploadedSignature');
dd(uploadedSignature, "Response:", response.fileUrl)
uploadedSignature.src = response.fileUrl; // Set the uploaded file URL to the image element
}).catch((error) => {
console.error("Error:", error);
});
}