diff --git a/dictionary/jsonXmlConversion.js b/dictionary/jsonXmlConversion.js index e3045e6..839ada0 100644 --- a/dictionary/jsonXmlConversion.js +++ b/dictionary/jsonXmlConversion.js @@ -972,13 +972,368 @@ const formExceptions = { } } }, + "HR0080R": { + "rootName": "Replacement", + "subRoots": ["FormInstance"], + "wrapperTags": [], + "allowCheckboxWithNoChange": [], + "omitFields": [], + "addFields": { + "FormInstanceId": null, + "CaseWorkerId": null, + "SRNum": null, + "CaseId": null, + "Category": null, + "CaseOfficeAddrCity": null, + "CaseOfficeAddrCountry": null, + "CaseOfficeAddrLine1": null, + "CaseOfficeAddrLine2": null, + "CaseOfficeAddrLine3": null, + "CaseOfficeAddrPostalCode": null, + "CaseOfficeAddrProvince": null, + "CaseType": null, + "SRId": null, + "Template": null, + "TemplateLocation": null, + "CaseName": null, + "CaseOfficeAddrComplete": null, + "CaseOfficeAddrCompleteCity": null, + "ListOfContact": { + "Contact":{ + "CaseRelTypeCode": null, + "EmailAddress": null, + "PHN": null, + "PersonUId": null + } + }, + "ListOfCase": { + "Case": { + "ListOfICMSSAAExpenseVBC": { + "ICMSSAAExpenseVBC": { + "CaseId": null, + "CaseRelTypeCode": null, + "PhoneBasicRate": null, + "RoomandBoardpaidtofamily": null + } + }, + "CaseNum": null, + "ClosedDate": null, + "Name": null, + "Status": null, + "Type": null, + "LastName2": null, + "CloseReason": null, + "LegacyFileNumber": null, + "ReopenedDate": null, + "ListOfApplicant": { + "Applicant": { + "ListOfICMSSAAApplicantAdditionalIncome": { + "ICMSSAAApplicantAdditionalIncome": { + } + }, + "ListOfICMSSAAApplicantIncome": { + "ICMSSAAApplicantIncome": { + "Boarder": null, + "SupportMaintenance": null, + "WorkersCompensation": null, + "EmploymentInsurance": null, + "ExtendedSpousesAllowance": null, + "CPPQPPOverride": null, + "CaseId": null, + "InterestDividends": null + + } + } + + }, + "ContactFullName": null, + "Age": null, + "Role": null, + "PHN": null, + "MovedFrmProvince": null, + "SelfIdentified": null, + "YRIndMet": null, + "DateSeparated": null, + "PossiblyAboriginal": null, + "AboriginalOriginCode": null, + "AboriginBand": null, + "DivorcedDate": null, + "ContactFullNameMiddle": null + }, + "ListOfSpouse": { + "Spouse": { + "ListOfICMSSAASpouseAdditionalIncome": { + "ICMSSAASpouseAdditionalIncome": { + + } + }, + "ListOfICMSSAASpouseIncome": { + "ICMSSAASpouseIncome": { + "WorkersCompensation": null, + "ExtendedSpousesAllowance": null, + "CPPQPPOverride": null, + "CaseId": null, + "InterestDividends": null + + } + }, + "ContactFullName": null, + "Gender": null, + "Age": null, + "Role": null, + "PHN": null, + "HomePhone": null, + "MovedFrmProvince": null, + "SelfIdentified": null, + "AboriginBand": null, + "AboriginalOriginCode": null, + "WorkPhone": null, + "ImmigrationEntryType": null, + "CurrentImmigrationType": null, + "YRIndMet": null, + "DateSeparated": null, + "PossiblyAboriginal": null, + "ContactFullNameMiddle": null, + + } + }, + "ListOfDependent": null, + "ListOfOccupant": null, + "ListOfICMCaseAddress": { + "ICMCaseAddress": { + "Country": null, + "CompleteAddressCity": null, + + } + } + } + } + }, + "versions": { + "1": { + "omitFields": [] + }, + "2": { + "omitFields": [] + } + } + }, "HR3687E": { "rootName": "ListOfDtFormInstanceLw", "subRoots": ["FormInstance"], "wrapperTags": [], "allowCheckboxWithNoChange": [], "omitFields": [], - "addFields": {}, + "addFields": { + "FormInstanceId": null, + "CreatedBy": null, + "SRNum": null, + "BenefitPlanId": null, + "CaseId": null, + "Category": null, + "ContactId": null, + "DocFileName": null, + "DocFileSize": null, + "DocFileSrcType": null, + "FinalFlag": null, + "ICPId": null, + "MISCaseNum": null, + "SRId": null, + "SubCategory": null, + "Template": null, + "RenderFlatFlag": null, + "Bool01": null, + "Bool02": null, + "Bool03": null, + "Bool04": null, + "Bool05": null, + "TemplateLocation": null, + "Date01": null, + "Date02": null, + "Date03": null, + "Date04": null, + "Date05": null, + "String01": null, + "String02": null, + "String03": null, + "String04": null, + "String05": null, + "String06": null, + "String07": null, + "String08": null, + "String09": null, + "String10": null, + "String11": null, + "String12": null, + "AuxName": null, + "AuxType": null, + "Number01": null, + "Number02": null, + "Number03": null, + "Number04": null, + "Number05": null, + "Bool06": null, + "Bool07": null, + "Bool08": null, + "Bool09": null, + "Bool10": null, + "Date06": null, + "Date07": null, + "Bool11": null, + "Bool12": null, + "Bool13": null, + "Bool14": null, + "Bool15": null, + "Bool16": null, + "Bool17": null, + "Bool18": null, + "Bool19": null, + "Bool20": null, + "Bool21": null, + "Bool22": null, + "Bool23": null, + "Bool24": null, + "Bool25": null, + "Bool26": null, + "Bool27": null, + "Bool28": null, + "Bool29": null, + "Bool30": null, + "Bool31": null, + "Bool32": null, + "Bool33": null, + "Bool34": null, + "Bool35": null, + "Bool36": null, + "Bool37": null, + "Bool38": null, + "Bool39": null, + "Bool40": null, + "Bool41": null, + "Bool42": null, + "Bool43": null, + "Bool44": null, + "Bool45": null, + "Bool46": null, + "Bool47": null, + "Bool48": null, + "Bool49": null, + "Bool50": null, + "String13": null, + "String14": null, + "String15": null, + "String16": null, + "String17": null, + "String18": null, + "String19": null, + "String20": null, + "String21": null, + "String22": null, + "String23": null, + "String24": null, + "String25": null, + "String26": null, + "String27": null, + "String28": null, + "String29": null, + "String30": null, + "String31": null, + "String32": null, + "String33": null, + "String34": null, + "String35": null, + "String36": null, + "String37": null, + "String38": null, + "String39": null, + "String40": null, + "String41": null, + "String42": null, + "String43": null, + "String44": null, + "String45": null, + "String46": null, + "String47": null, + "String48": null, + "String49": null, + "String50": null, + "String51": null, + "String52": null, + "String53": null, + "String54": null, + "String55": null, + "String56": null, + "String57": null, + "String58": null, + "String59": null, + "String60": null, + "String61": null, + "String62": null, + "String63": null, + "String64": null, + "String65": null, + "ListOfContact": { + "Contact": { + "BirthDate": null, + "CaseRelTypeCode": null, + "ClientIDNumber": null, + "FullName": null, + "FullNameMiddle": null, + "MF": null, + "MiddleName": null, + "MiddleNameInitial": null, + "SIN": null, + "WorkPhone": null, + "ListOfContactAddresses": null + }, + "ListOfCase": { + "Case": { + "PrimaryOrganizationName": null, + "Name": null, + "Status": null, + "AssignToFN": null, + "AssignToLN": null, + "ListOfICMCaseAddress": null + } + }, + "ListOfEmployee": { + "Employee": { + "EMailAddr": null, + "Emp": null, + "Fax": null, + "FirstName": null, + "Login": null, + "FullName": null, + "FullNameMiddle": null, + "JobTitle": null, + "LastName": null, + "MiddleName": null, + "MiddleNameInitial": null, + "WorkPhoneNumber": null + } + }, + "ListOfAttCreatedBy": { + "AttCreatedBy": { + "Id": null, + "Emp": null, + "FullName": null, + "JobTitle": null + } + }, + "ListOfOffice": { + "Office": { + "OfficeRegion": null, + "OfficeAddressLine2": null, + "OfficeAddressLine3": null, + "OfficeAddressCountry": null, + "OfficeAddressUnit": null, + "OfficePhone": null, + "OfficeFax": null, + "OfficeAddressCompleteCity": null + } + } + } + }, "versions": { "1": { "omitFields": [] diff --git a/generateHandler.js b/generateHandler.js index f764690..89d7ece 100644 --- a/generateHandler.js +++ b/generateHandler.js @@ -106,6 +106,8 @@ async function generateNewTemplate(req, res) { params = { ...params, ...configOpt }; const template_id = params["formId"]; const attachment_Id = params["attachmentId"]; + const authHeader = req.get('Authorization') || ''; + const rawToken = authHeader.split(' ')[0] === 'Bearer'? authHeader.split(' ')[1] : authHeader || null; if (!template_id) { return res .status(400) @@ -168,7 +170,16 @@ async function generateNewTemplate(req, res) { return res.status(400).send({ error: getErrorMessage("INVALID_AREA") }); } } - + + const icmOfficeName = icm_metadata?.["Office Name"]; + const requestOfficeName = typeof params.OfficeName === "string" ? params.OfficeName.trim() : ""; + console.log('RequestOfficeName:', requestOfficeName); + console.log('IcmOfficeName:', icmOfficeName); + if (!requestOfficeName && icmOfficeName) { + params.OfficeName = icmOfficeName; + } + console.log("Params:",params); + const formJson = await constructFormJson(template_id, params); if (formJson != null) { @@ -180,7 +191,7 @@ async function generateNewTemplate(req, res) { const saveDataForLater = JSON.stringify(formJson) const id = await storeData(saveDataForLater); const endPointForGenerate = process.env.GENERATE_KILN_URL + "?jsonId=" + id; - const isGenerateSuccess = await performGenerateFunction(endPointForGenerate); + const isGenerateSuccess = await performGenerateFunction(endPointForGenerate,rawToken,username); deleteData(id); //if successfully generated send back response @@ -209,7 +220,7 @@ async function generateNewTemplate(req, res) { } } -async function performGenerateFunction(url) { +async function performGenerateFunction(url,token,username) { try { const browser = await puppeteer.launch({ @@ -227,12 +238,41 @@ async function performGenerateFunction(url) { //const browser = await puppeteer.launch(); const page = await browser.newPage(); + page.on('console', msg => { + console.log('Browser logs:', msg.type(), msg.text()); + }); + + page.on('request', req => { + console.log('Request:', req.url(), req.failure()); + }); + // Set the HTML content of the page await page.goto(url,{ timeout: 200000, // 60 seconds waitUntil: 'domcontentloaded', // You can also use 'networkidle2' or 'domcontentloaded' }); // Replace with your actual URL console.log('Page loaded.'); + const appUrl = new URL(url); + const cookies = []; + + if (token) { + cookies.push({ + name: 'token', + value: token, + url: appUrl.origin + }); + } + + if (username) { + cookies.push({ + name: 'username', + value: username, + url: appUrl.origin + }); + } + if (cookies.length) { + await browser.setCookie(...cookies); + } // Step 2: Wait for the button to be available await page.waitForSelector('#generate',{ timeout: 200000 }); // Use the actual selector diff --git a/generatePDFHandler.js b/generatePDFHandler.js index b3003f3..ea0b166 100644 --- a/generatePDFHandler.js +++ b/generatePDFHandler.js @@ -104,6 +104,14 @@ async function generatePDFFromHTML(req, res) { ], }); const page = await browser.newPage(); + + page.on('console', msg => { + console.log('Browser logs:', msg.type(), msg.text()); + }); + + page.on('request', req => { + console.log('Request:', req.url(), req.failure()); + }); // Set the HTML content of the page await page.setContent(htmlContent, { waitUntil: 'load' }); @@ -160,10 +168,10 @@ async function generatePDFFromURL(req, res) { async function getPDFFromURL(url) { // Increases to 5000 seemed to be working well (could also set the params in env file if needed) - const HYDRATE_MS = Number(process.env.PDF_HYDRATE_MS ?? 5000); + /* const HYDRATE_MS = Number(process.env.PDF_HYDRATE_MS ?? 5000); const CLICK_WINDOW_MS = Number(process.env.PDF_CLICK_WINDOW_MS ?? 3000); const CLICK_RETRY_EVERY_MS = Number(process.env.PDF_CLICK_INTERVAL_MS ?? 200); - const POST_CLICK_MS = Number(process.env.PDF_POST_CLICK_MS ?? 2500); + const POST_CLICK_MS = Number(process.env.PDF_POST_CLICK_MS ?? 2500); */ const browser = await puppeteer.launch({ executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || "/usr/bin/chromium", @@ -180,13 +188,25 @@ async function getPDFFromURL(url) { //const browser = await puppeteer.launch(); const page = await browser.newPage(); + page.on('console', msg => { + console.log('Browser logs:', msg.type(), msg.text()); + }); + + page.on('request', req => { + console.log('Request:', req.url(), req.failure()); + }); + // Optional: Adjust the page's viewport for better PDF layout await page.setViewport({ width: 1280, height: 800 }); // Set the HTML content of the page await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 150000 }); - // Let app hydrate + //The below code block clicks the show letter button on the UI. This functionality is not needed any more + // as the PRINT directly should show the letter setting/resetting visible_pdf and visbile_web flags + // in the form definition. This below code takes a lot of await times and is making the process delayed as a whole + // Until confirmed the commenting out doesnt pose any issues, leave this here just in case to put it back. + /* // Let app hydrate await sleep(HYDRATE_MS); // Click “Show Letter” with a short retry window @@ -229,10 +249,12 @@ async function getPDFFromURL(url) { try { clicked = await f.evaluate(clickScript); if (clicked) break; } catch {} } } - } + } */ + //here // Give it time to assemble the printable view - await sleep(POST_CLICK_MS); + //await sleep(POST_CLICK_MS); + console.log("Waiting for print button..."); @@ -242,6 +264,19 @@ async function getPDFFromURL(url) { // Try main document try { await page.waitForSelector("#print", { visible: true, timeout: 1000 }); + // Wait until enabled + await page.waitForFunction( + sel => { + const el = document.querySelector(sel); + if (!el) return false; + if (el.disabled) return false; + if (el.getAttribute("aria-disabled") === "true") return false; + if (el.classList.contains("disabled")) return false; + return true; + }, + { timeout: 5000 }, + "#print" + ); await page.click("#print"); clickedPrint = true; console.log("Clicked print button on main page"); @@ -252,6 +287,18 @@ async function getPDFFromURL(url) { for (const frame of page.frames()) { try { await frame.waitForSelector("#print", { visible: true, timeout: 1000 }); + await frame.waitForFunction( + sel => { + const el = document.querySelector(sel); + if (!el) return false; + if (el.disabled) return false; + if (el.getAttribute("aria-disabled") === "true") return false; + if (el.classList.contains("disabled")) return false; + return true; + }, + { timeout: 5000 }, + "#print" + ); await frame.click("#print"); clickedPrint = true; console.log("Clicked print button inside iframe"); @@ -261,7 +308,7 @@ async function getPDFFromURL(url) { await sleep(250); // avoid hot-looping } - //await sleep(POST_CLICK_MS); + if (clickedPrint) { console.log("Waiting for printable layout to finish…"); @@ -278,23 +325,23 @@ async function getPDFFromURL(url) { } // Svelte stabilization - console.log("Waiting for Svelte DOM stability…"); - await page.waitForFunction(() => { - const now = performance.now(); - if (!window.__lastMutationTime) window.__lastMutationTime = now; - - if (!window.__mutationObserverInstalled) { - const observer = new MutationObserver(() => { - window.__lastMutationTime = performance.now(); - }); - observer.observe(document.body, { - childList: true, - subtree: true, - attributes: true, - characterData: true - }); - window.__mutationObserverInstalled = true; - } + console.log("Waiting for Svelte DOM stability…"); + await page.waitForFunction(() => { + const now = performance.now(); + if (!window.__lastMutationTime) window.__lastMutationTime = now; + + if (!window.__mutationObserverInstalled) { + const observer = new MutationObserver(() => { + window.__lastMutationTime = performance.now(); + }); + observer.observe(document.body, { + childList: true, + subtree: true, + attributes: true, + characterData: true + }); + window.__mutationObserverInstalled = true; + } return performance.now() - window.__lastMutationTime > 600; }, { timeout: 20000 });