244 lines
7.1 KiB
JavaScript
244 lines
7.1 KiB
JavaScript
import { gql } from "@apollo/client";
|
|
import { notification } from "antd";
|
|
import axios from "axios";
|
|
import jsreport from "jsreport-browser-client-dist";
|
|
import moment from "moment";
|
|
import { auth } from "../firebase/firebase.utils";
|
|
import { setEmailOptions } from "../redux/email/email.actions";
|
|
import { store } from "../redux/store";
|
|
import client from "../utils/GraphQLClient";
|
|
import { TemplateList } from "./TemplateConstants";
|
|
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
|
|
jsreport.serverUrl = server;
|
|
|
|
const Templates = TemplateList();
|
|
|
|
export default async function RenderTemplate(
|
|
templateObject,
|
|
bodyshop,
|
|
renderAsHtml = false
|
|
) {
|
|
//Query assets that match the template name. Must be in format <<templateName>>.query
|
|
let { contextData, useShopSpecificTemplate } = await fetchContextData(
|
|
templateObject
|
|
);
|
|
|
|
let reportRequest = {
|
|
template: {
|
|
name: useShopSpecificTemplate
|
|
? `/${bodyshop.imexshopid}/${templateObject.name}`
|
|
: `/${templateObject.name}`,
|
|
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
|
|
},
|
|
data: {
|
|
...contextData,
|
|
...templateObject.variables,
|
|
...templateObject.context,
|
|
headerpath: `/${bodyshop.imexshopid}/header.html`,
|
|
bodyshop: bodyshop,
|
|
offset: moment().utcOffset(),
|
|
},
|
|
};
|
|
try {
|
|
const render = await jsreport.renderAsync(reportRequest);
|
|
if (!renderAsHtml) {
|
|
render.download(Templates[templateObject.name].title || "");
|
|
} else {
|
|
return new Promise((resolve, reject) => {
|
|
resolve(render.toString());
|
|
});
|
|
}
|
|
} catch (error) {
|
|
notification["error"]({ message: JSON.stringify(error) });
|
|
}
|
|
}
|
|
|
|
export async function RenderTemplates(
|
|
templateObjects,
|
|
bodyshop,
|
|
renderAsHtml = false
|
|
) {
|
|
//Query assets that match the template name. Must be in format <<templateName>>.query
|
|
let templateAndData = [];
|
|
let proms = [];
|
|
templateObjects.forEach((template) => {
|
|
proms.push(
|
|
(async () => {
|
|
let { contextData, useShopSpecificTemplate } = await fetchContextData(
|
|
template
|
|
);
|
|
templateAndData.push({
|
|
templateObject: template,
|
|
contextData,
|
|
useShopSpecificTemplate,
|
|
});
|
|
})()
|
|
);
|
|
});
|
|
await Promise.all(proms);
|
|
let rootTemplate = templateAndData.shift();
|
|
|
|
let reportRequest = {
|
|
template: {
|
|
name: rootTemplate.useShopSpecificTemplate
|
|
? `/${bodyshop.imexshopid}/${rootTemplate.templateObject.name}`
|
|
: `/${rootTemplate.templateObject.name}`,
|
|
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
|
|
pdfOperations: templateAndData.map((template) => {
|
|
return {
|
|
template: {
|
|
name: template.useShopSpecificTemplate
|
|
? `/${bodyshop.imexshopid}/${template.templateObject.name}`
|
|
: `/${template.templateObject.name}`,
|
|
...(renderAsHtml ? {} : { recipe: "chrome-pdf" }),
|
|
},
|
|
type: "append",
|
|
mergeWholeDocument: true,
|
|
renderForEveryPage: true,
|
|
};
|
|
}),
|
|
},
|
|
data: {
|
|
...extend(
|
|
rootTemplate.contextData,
|
|
...templateAndData.map((temp) => temp.contextData)
|
|
),
|
|
|
|
// ...rootTemplate.templateObject.variables,
|
|
// ...rootTemplate.templateObject.context,
|
|
headerpath: `/${bodyshop.imexshopid}/header.html`,
|
|
bodyshop: bodyshop,
|
|
},
|
|
};
|
|
|
|
console.log("reportRequest", reportRequest);
|
|
|
|
try {
|
|
const render = await jsreport.renderAsync(reportRequest);
|
|
if (!renderAsHtml) {
|
|
render.download("Speed Print");
|
|
} else {
|
|
return new Promise((resolve, reject) => {
|
|
resolve(render.toString());
|
|
});
|
|
}
|
|
} catch (error) {
|
|
notification["error"]({ message: JSON.stringify(error) });
|
|
}
|
|
}
|
|
|
|
export const GenerateDocument = async (template, messageOptions, sendType) => {
|
|
const bodyshop = store.getState().user.bodyshop;
|
|
if (sendType === "e") {
|
|
store.dispatch(
|
|
setEmailOptions({
|
|
messageOptions,
|
|
template,
|
|
})
|
|
);
|
|
} else {
|
|
await RenderTemplate(template, bodyshop);
|
|
}
|
|
};
|
|
|
|
export const GenerateDocuments = async (templates) => {
|
|
const bodyshop = store.getState().user.bodyshop;
|
|
await RenderTemplates(templates, bodyshop);
|
|
};
|
|
|
|
const fetchContextData = async (templateObject) => {
|
|
console.log("Fetching context data", templateObject);
|
|
jsreport.headers["Authorization"] =
|
|
"Bearer " + (await auth.currentUser.getIdToken());
|
|
|
|
const jsReportQueries = await axios.get(
|
|
`${server}/odata/assets?$filter=name eq '${templateObject.name}.query'`
|
|
);
|
|
|
|
let templateQueryToExecute,
|
|
useShopSpecificTemplate = false;
|
|
if (jsReportQueries.data.value.length === 0) {
|
|
//We have no query to execute. Just render the template.
|
|
} else if (jsReportQueries.data.value.length === 1) {
|
|
//We're using the default template. Get the query and execute.
|
|
templateQueryToExecute = atob(jsReportQueries.data.value[0].content);
|
|
} else if (jsReportQueries.data.value.length === 2) {
|
|
//There's a custom template. Use that query instead and execute. We find it because it has a parent folder.
|
|
templateQueryToExecute = atob(
|
|
jsReportQueries.data.value.filter((v) => !!v.folder)[0].content
|
|
);
|
|
useShopSpecificTemplate = true;
|
|
} else {
|
|
//We have too many queries to choose from. Throw an error.
|
|
alert(
|
|
"There are too many queries to choose from. Please ensure there are no conflicting keys."
|
|
);
|
|
throw new Error(
|
|
"There are too many queries to choose from. Please ensure there are no conflicting keys."
|
|
);
|
|
}
|
|
let contextData = {};
|
|
if (templateQueryToExecute) {
|
|
const { data } = await client.query({
|
|
query: gql(templateQueryToExecute),
|
|
variables: { ...templateObject.variables },
|
|
fetchPolicy: "network-only",
|
|
});
|
|
contextData = data;
|
|
}
|
|
|
|
return { contextData, useShopSpecificTemplate };
|
|
};
|
|
|
|
//export const displayTemplateInWindow = (html) => {
|
|
// try {
|
|
// var newWin = window.open("", "_blank", "toolbar=0,location=0,menubar=0");
|
|
// newWin.document.write(html);
|
|
|
|
// setTimeout(function () {
|
|
// newWin.document.close();
|
|
// newWin.focus();
|
|
// newWin.print();
|
|
// newWin.close();
|
|
// }, 500);
|
|
// } catch (error) {
|
|
// console.log("Unable to write to new window.", error);
|
|
// }
|
|
// };
|
|
|
|
// export const displayTemplateInWindowNoprint = (html) => {
|
|
// try {
|
|
// var newWin = window.open("", "_blank", "toolbar=0,location=0,menubar=0");
|
|
// newWin.document.write(html);
|
|
|
|
// setTimeout(function () {
|
|
// newWin.document.close();
|
|
// newWin.focus();
|
|
// //newWin.print();
|
|
// //newWin.close();
|
|
// }, 500);
|
|
// } catch (error) {
|
|
// console.log("Unable to write to new window.", error);
|
|
// }
|
|
// };
|
|
|
|
function extend(o1, o2, o3) {
|
|
var result = {},
|
|
obj;
|
|
|
|
for (var i = 0; i < arguments.length; i++) {
|
|
obj = arguments[i];
|
|
for (var key in obj) {
|
|
if (Object.prototype.toString.call(obj[key]) === "[object Object]") {
|
|
if (typeof result[key] === "undefined") {
|
|
result[key] = {};
|
|
}
|
|
result[key] = extend(result[key], obj[key]);
|
|
} else {
|
|
result[key] = obj[key];
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|