|
|
|
const PizZip = require('pizzip');
|
|
|
|
const Docxtemplater = require('docxtemplater');
|
|
|
|
const fs = require('fs');
|
|
|
|
const path = require('path');
|
|
|
|
const _ = require("lodash");
|
|
|
|
|
|
|
|
// The error object contains additional information when logged with JSON.stringify (it contains a properties object containing all suberrors).
|
|
|
|
function replaceErrors(key, value) {
|
|
|
|
if (value instanceof Error) {
|
|
|
|
return Object.getOwnPropertyNames(value).reduce(function (error, key) {
|
|
|
|
error[key] = value[key];
|
|
|
|
return error;
|
|
|
|
}, {});
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function errorHandler(error) {
|
|
|
|
console.log(JSON.stringify({
|
|
|
|
error: error
|
|
|
|
}, replaceErrors));
|
|
|
|
|
|
|
|
if (error.properties && error.properties.errors instanceof Array) {
|
|
|
|
const errorMessages = error.properties.errors.map(function (error) {
|
|
|
|
return error.properties.explanation;
|
|
|
|
}).join("\n");
|
|
|
|
console.log('errorMessages', errorMessages);
|
|
|
|
// errorMessages is a humanly readable message looking like this :
|
|
|
|
// 'The tag beginning with "foobar" is unopened'
|
|
|
|
}
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
|
|
|
|
class InspectModule {
|
|
|
|
constructor() {
|
|
|
|
this.inspect = {};
|
|
|
|
}
|
|
|
|
set(obj) {
|
|
|
|
if (obj.inspect) {
|
|
|
|
this.inspect = _.merge({}, this.inspect, obj.inspect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const getTags = function (postParsed) {
|
|
|
|
return postParsed.filter(function (part) {
|
|
|
|
return part.type === "placeholder";
|
|
|
|
}).reduce(function (tags, part) {
|
|
|
|
tags[part.value] = {};
|
|
|
|
if (part.subparsed) {
|
|
|
|
tags[part.value] = getTags(part.subparsed);
|
|
|
|
}
|
|
|
|
return tags;
|
|
|
|
}, {});
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = function (templateInfo, fileName) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
|
|
|
//check empty fields
|
|
|
|
for (const key in templateInfo) {
|
|
|
|
if (!templateInfo[key]) {
|
|
|
|
throw ({
|
|
|
|
eCode: 412,
|
|
|
|
eText: 'هیچ یک از فیلدها نباید خالی باشند'
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let content = fs.readFileSync(path.resolve(__dirname, `../template/${fileName}`), 'binary');
|
|
|
|
let zip = new PizZip(content);
|
|
|
|
let doc;
|
|
|
|
let inspectModule = new InspectModule();
|
|
|
|
|
|
|
|
try {
|
|
|
|
doc = new Docxtemplater(zip, {
|
|
|
|
modules: [inspectModule]
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
errorHandler(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
let postParsed = inspectModule.inspect.postparsed;
|
|
|
|
let placeholders = Object.keys(getTags(postParsed))
|
|
|
|
let templateInfoKeys = Object.keys(templateInfo)
|
|
|
|
|
|
|
|
//compare template placeholders and received fields from client(templateInfo)
|
|
|
|
for (let i = 0; i < placeholders.length; i++) {
|
|
|
|
if (!templateInfoKeys.includes(placeholders[i])) {
|
|
|
|
throw ({
|
|
|
|
eCode: 400,
|
|
|
|
eText: 'اطلاعات وارد شده ناقص است'
|
|
|
|
})
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
doc.setData(templateInfo);
|
|
|
|
|
|
|
|
try {
|
|
|
|
doc.render()
|
|
|
|
} catch (error) {
|
|
|
|
errorHandler(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
let buf = doc.getZip().generate({
|
|
|
|
type: 'nodebuffer'
|
|
|
|
});
|
|
|
|
fs.writeFileSync(path.resolve(__dirname, `../public/files/${templateInfo.firstName}-${templateInfo.lastName}-${fileName}`), buf);
|
|
|
|
resolve(`http://localhost:3000/users/download/${templateInfo.firstName}-${templateInfo.lastName}-${fileName}`)
|
|
|
|
|
|
|
|
.catch(err => {
|
|
|
|
reject({
|
|
|
|
eCode: 500,
|
|
|
|
eText: err
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|