286 lines
10 KiB
JavaScript
286 lines
10 KiB
JavaScript
|
|
const { Documenso } = require("@documenso/sdk-typescript");
|
|
const axios = require("axios");
|
|
const { jsrAuthString } = require("../utils/utils");
|
|
const logger = require("../utils/logger");
|
|
const DOCUMENSO_API_KEY = "api_asojim0czruv13ud";//Done on a by team basis,
|
|
const documenso = new Documenso({
|
|
apiKey: DOCUMENSO_API_KEY,//Done on a by team basis,
|
|
serverURL: "https://stg-app.documenso.com/api/v2",
|
|
});
|
|
const JSR_SERVER = "https://reports.test.imex.online";
|
|
const jsreport = require("@jsreport/nodejs-client");
|
|
const { QUERY_JOB_FOR_SIGNATURE, INSERT_ESIG_AUDIT_TRAIL } = require("../graphql-client/queries");
|
|
|
|
|
|
async function distributeDocument(req, res) {
|
|
try {
|
|
const client = req.userGraphQLClient;
|
|
|
|
const { documentId } = req.body;
|
|
const distributeResult = await documenso.documents.distribute({
|
|
documentId,
|
|
});
|
|
|
|
const auditEntry = await client.request(INSERT_ESIG_AUDIT_TRAIL, {
|
|
obj: {
|
|
jobid: req.body.jobid,
|
|
bodyshopid: req.body.bodyshopid,
|
|
operation: `Esignature document with title ${distributeResult.title} (ID: ${documentId}) distributed to recipients.`,
|
|
useremail: req.user?.email,
|
|
type: 'esig-distribute'
|
|
}
|
|
})
|
|
|
|
res.json({ success: true, distributeResult });
|
|
} catch (error) {
|
|
console.error("Error distributing document:", error?.data);
|
|
logger.log(`esig-distribute-error`, "ERROR", "esig", "api", {
|
|
message: error.message, stack: error.stack,
|
|
body: req.body
|
|
});
|
|
res.status(500).json({ error: "An error occurred while distributing the document." });
|
|
}
|
|
}
|
|
|
|
async function newEsignDocument(req, res) {
|
|
|
|
try {
|
|
const client = req.userGraphQLClient;
|
|
const { bodyshop } = req.body
|
|
const { pdf: fileBuffer, esigData } = await RenderTemplate({ client, req })
|
|
const fileBlob = new Blob([fileBuffer], { type: "application/pdf" });
|
|
|
|
|
|
//Get the Job data.
|
|
const { jobs_by_pk: jobData } = await client.request(QUERY_JOB_FOR_SIGNATURE, { jobid: req.body.jobid });
|
|
|
|
const createDocumentResponse = await documenso.documents.create({
|
|
payload: {
|
|
title: esigData?.title,
|
|
externalId: req.body.jobid,
|
|
recipients: [
|
|
{
|
|
email: "patrick@imexsystems.ca",//jobData.ownr_ea,
|
|
name: `${jobData.ownr_fn} ${jobData.ownr_ln}`,
|
|
role: "SIGNER",
|
|
}
|
|
],
|
|
meta: {
|
|
timezone: bodyshop.timezone,
|
|
dateFormat: "MM/dd/yyyy hh:mm a",
|
|
language: "en",
|
|
subject: esigData?.subject,
|
|
message: esigData?.message,
|
|
|
|
}
|
|
},
|
|
file: fileBlob
|
|
});
|
|
|
|
const documentResult = await documenso.documents.get({
|
|
documentId: createDocumentResponse.id,
|
|
});
|
|
|
|
|
|
if (esigData?.fields && esigData.fields.length > 0) {
|
|
try {
|
|
await documenso.envelopes.fields.createMany({
|
|
envelopeId: createDocumentResponse.envelopeId,
|
|
data: esigData.fields.map(sigField => ({ ...sigField, recipientId: documentResult.recipients[0].id, }))
|
|
|
|
});
|
|
} catch (error) {
|
|
logger.log(`esig-new-fields-error`, "ERROR", "esig", "api", {
|
|
message: error.message, stack: error.stack,
|
|
body: req.body
|
|
});
|
|
}
|
|
}
|
|
|
|
const presignToken = await documenso.embedding.embeddingPresignCreateEmbeddingPresignToken({})
|
|
|
|
//add to job audit trail.
|
|
|
|
const auditEntry = await client.request(INSERT_ESIG_AUDIT_TRAIL, {
|
|
obj: {
|
|
jobid: req.body.jobid,
|
|
bodyshopid: bodyshop.id,
|
|
operation: `Esignature document created. Subject: ${esigData?.subject || "No subject"}, Message: ${esigData?.message || "No message"}. Document ID: ${createDocumentResponse.id} Envlope ID: ${createDocumentResponse.envelopeId}`,
|
|
useremail: req.user?.email,
|
|
type: 'esig-create'
|
|
|
|
}
|
|
})
|
|
|
|
res.json({ token: presignToken.token, documentId: createDocumentResponse.id, envelopeId: createDocumentResponse.envelopeId });
|
|
}
|
|
catch (error) {
|
|
logger.log(`esig-new-error`, "ERROR", "esig", "api", {
|
|
message: error.message, stack: error.stack,
|
|
body: req.body
|
|
});
|
|
res.status(500).json({ error: "An error occurred while creating the e-sign document." });
|
|
}
|
|
}
|
|
|
|
|
|
async function RenderTemplate({ req }) {
|
|
//TODO Refactor to pull
|
|
const jsrAuth = jsrAuthString()
|
|
|
|
const jsreportClient = new jsreport("https://reports.test.imex.online", process.env.JSR_USER, process.env.JSR_PASSWORD);
|
|
const { templateObject, bodyshop } = req.body;
|
|
let { contextData, useShopSpecificTemplate, shopSpecificFolder, esigData } = await fetchContextData({ templateObject, jsrAuth, req });
|
|
|
|
const { ignoreCustomMargins } = { ignoreCustomMargins: false }// Templates[templateObject.name];
|
|
let reportRequest = {
|
|
template: {
|
|
name: useShopSpecificTemplate ? `/${bodyshop.imexshopid}/${templateObject.name}` : `/${templateObject.name}`,
|
|
|
|
recipe: "chrome-pdf",
|
|
...(!ignoreCustomMargins && {
|
|
chrome: {
|
|
marginTop:
|
|
bodyshop.logo_img_path &&
|
|
bodyshop.logo_img_path.headerMargin &&
|
|
bodyshop.logo_img_path.headerMargin > 36
|
|
? bodyshop.logo_img_path.headerMargin
|
|
: "36px",
|
|
marginBottom:
|
|
bodyshop.logo_img_path &&
|
|
bodyshop.logo_img_path.footerMargin &&
|
|
bodyshop.logo_img_path.footerMargin > 50
|
|
? bodyshop.logo_img_path.footerMargin
|
|
: "50px"
|
|
}
|
|
}),
|
|
},
|
|
data: {
|
|
...contextData,
|
|
...templateObject.variables,
|
|
...templateObject.context,
|
|
headerpath: shopSpecificFolder ? `/${bodyshop.imexshopid}/header.html` : `/GENERIC/header.html`,
|
|
footerpath: shopSpecificFolder ? `/${bodyshop.imexshopid}/footer.html` : `/GENERIC/footer.html`,
|
|
bodyshop: bodyshop,
|
|
filters: templateObject?.filters,
|
|
sorters: templateObject?.sorters,
|
|
offset: bodyshop.timezone, //dayjs().utcOffset(),
|
|
defaultSorters: templateObject?.defaultSorters
|
|
}
|
|
};
|
|
const render = await jsreportClient.render(reportRequest);
|
|
|
|
//Check render object and download. It should be the PDF?
|
|
const pdfBuffer = await render.body()
|
|
return { pdf: pdfBuffer, esigData }
|
|
}
|
|
|
|
const fetchContextData = async ({ templateObject, jsrAuth, req, }) => {
|
|
const { bodyshop } = req.body
|
|
|
|
|
|
const folders = await axios.get(`${JSR_SERVER}/odata/folders`, {
|
|
headers: { Authorization: jsrAuth }
|
|
});
|
|
const shopSpecificFolder = folders.data.value.find((f) => f.name === bodyshop.imexshopid);
|
|
|
|
const jsReportQueries = await axios.get(
|
|
`${JSR_SERVER}/odata/assets?$filter=name eq '${templateObject.name}.query'`,
|
|
{ headers: { Authorization: jsrAuth } }
|
|
);
|
|
const jsReportEsig = await axios.get(
|
|
`${JSR_SERVER}/odata/assets?$filter=name eq '${templateObject.name}.esig'`,
|
|
{ headers: { Authorization: jsrAuth } }
|
|
);
|
|
|
|
let templateQueryToExecute;
|
|
let esigData;
|
|
let useShopSpecificTemplate = false;
|
|
// let shopSpecificTemplate;
|
|
|
|
if (shopSpecificFolder) {
|
|
let shopSpecificTemplate = jsReportQueries.data.value.find(
|
|
(f) => f?.folder?.shortid === shopSpecificFolder.shortid
|
|
);
|
|
if (shopSpecificTemplate) {
|
|
useShopSpecificTemplate = true;
|
|
templateQueryToExecute = atob(shopSpecificTemplate.content);
|
|
}
|
|
let shopSpecificEsig = jsReportEsig.data.value.find(
|
|
(f) => f?.folder?.shortid === shopSpecificFolder.shortid
|
|
);
|
|
if (shopSpecificEsig) {
|
|
esigData = (atob(shopSpecificEsig.content));
|
|
}
|
|
}
|
|
|
|
if (!templateQueryToExecute) {
|
|
const generalTemplate = jsReportQueries.data.value.find((f) => !f.folder);
|
|
useShopSpecificTemplate = false;
|
|
templateQueryToExecute = atob(generalTemplate.content);
|
|
}
|
|
if (!esigData) {
|
|
const generalTemplate = jsReportEsig.data.value.find((f) => !f.folder);
|
|
useShopSpecificTemplate = false;
|
|
if (generalTemplate && generalTemplate.content) {
|
|
esigData = atob(generalTemplate?.content);
|
|
}
|
|
}
|
|
|
|
const client = req.userGraphQLClient;
|
|
|
|
|
|
// In the print center, we will never have sorters or filters.
|
|
// We have no template filters or sorters, so we can just execute the query and return the data
|
|
// if (!hasFilters && !hasSorters && !hasDefaultSorters) {
|
|
let contextData = {};
|
|
if (templateQueryToExecute) {
|
|
const data = await client.request(
|
|
templateQueryToExecute,
|
|
templateObject.variables,
|
|
);
|
|
contextData = data;
|
|
}
|
|
|
|
let parsedEsigData
|
|
try {
|
|
parsedEsigData = esigData ? JSON.parse(esigData) : null;
|
|
} catch (error) {
|
|
console.log("Error parsing esig data", error);
|
|
parsedEsigData = {}
|
|
}
|
|
|
|
return {
|
|
contextData,
|
|
useShopSpecificTemplate,
|
|
shopSpecificFolder,
|
|
esigData: parsedEsigData
|
|
};
|
|
// }
|
|
|
|
// return await generateTemplate(templateQueryToExecute, templateObject, useShopSpecificTemplate, shopSpecificFolder);
|
|
};
|
|
|
|
module.exports = {
|
|
newEsignDocument,
|
|
distributeDocument
|
|
}
|
|
|
|
|
|
|
|
// const sample_esig_for_jsr = {
|
|
// "fields": [
|
|
// {
|
|
// "placeholder": "[[signature]]",
|
|
// "type": "SIGNATURE"
|
|
// },
|
|
// {
|
|
// "placeholder": "[[date]]",
|
|
// "type": "DATE"
|
|
// }
|
|
// ],
|
|
// "subject": "CASL Auth Set in JSR",
|
|
// "message": "CASL Message set in JSR",
|
|
// "title": "CASL Title set in JSR"
|
|
// }
|