Something went wrong on our end
-
Johannes Hörmann authoredJohannes Hörmann authored
process.js 35.54 KiB
import("Binary_lib");
import("Communication_lib");
import("system.neon");
import("Employee_lib");
import("KeywordRegistry_basic");
import("Document_lib");
import("KeywordData_lib");
import("Sql_lib");
import("Address_lib");
import("system.process");
import("system.vars");
import("system.db");
import("system.util");
import("system.pack");
import("system.fileIO");
import("system.translate");
import("system.datetime");
import("system.question");
import("system.text");
import("system.mail");
import("Keyword_lib");
import("Placeholder_lib");
import("Email_lib");
import("MimeType_lib");
/**
* Object for working with document templates, holds the content and type of the template.
* Provides functions to replace placeholders in the content.
*
* @class
*/
var DocumentTemplate = (function ()
{
/**
* constructor for DocumentTemplate
*
* @param {String} pTemplateContent content, as base64 string (except for DocumentTemplate.types.PLAIN, then it's a normal string)
* @param {String} pType type of the template, use the DocumentTemplate.types constants here
* @param {String} [pFilename=undefined] file name of the template
* @param {Boolean} [pResolveSubtemplates=false] if true subtemplates are resolved (if the type fits)
* @param {String} [pTemplateId=undefined] Provide it, if you have it, because this enables the template to load attachments associated by this ID
*/
function DocumentTemplate(pTemplateContent, pType, pFilename, pResolveSubtemplates, pTemplateId)
{
this.content = pTemplateContent;
this.type = pType;
this.filename = pFilename;
this.templateId = pTemplateId;
this._stringCache = null;
this._attachmentCache = null;
this._subtemplatedContent = null;
if (pResolveSubtemplates)
this._resolveEmbeddedTemplate();
}
/**
* @return {String} the text of the content
*/
DocumentTemplate.prototype.toString = function (pWithSubtemplates)
{
if (this._stringCache == null)
{
var content = this._getTemplatedContent(pWithSubtemplates);
if (this.type == DocumentTemplate.types.PLAIN)
this._stringCache = content;
else
this._stringCache = text.parseDocument(content);
}
return this._stringCache;
}
DocumentTemplate.prototype._resolveEmbeddedTemplate = function ()
{
// currently we support only txt and html as others would need special caution.
if (this.content != null && (this.type == DocumentTemplate.types.TXT || this.type == DocumentTemplate.types.HTML))
{
var replacedContent = util.decodeBase64String(this.content);
var templates = [];
// then load the possible replacement names
if (this.type == DocumentTemplate.types.TXT || this.type == DocumentTemplate.types.HTML)
{
templates = db.table(SqlCondition.begin()
.andPrepare("DOCUMENTTEMPLATE.KIND", $KeywordRegistry.documentTemplateType$textModular())
.andPrepare("DOCUMENTTEMPLATE.CLASSIFICATION", $KeywordRegistry.documentTemplateTypeCategory$textTemplate())
.buildSql("select DOCUMENTTEMPLATEID, REPLACEMENTNAME from DOCUMENTTEMPLATE"));
}
if (this.type == DocumentTemplate.types.HTML)
{
templates = templates.concat(db.table(SqlCondition.begin()
.andPrepare("DOCUMENTTEMPLATE.KIND", $KeywordRegistry.documentTemplateType$textModular())
.andPrepare("DOCUMENTTEMPLATE.CLASSIFICATION", $KeywordRegistry.documentTemplateTypeCategory$htmlTemplate())
.buildSql("select DOCUMENTTEMPLATEID, REPLACEMENTNAME from DOCUMENTTEMPLATE")));
}
var alias = SqlUtils.getBinariesAlias();
// We use callbacks which are called by pString.replace
placeholders = templates.map(function(pTemplate) {
// add function for each placeholder so that the db.getBinaryContent is only called, if the placeholder is replaced.
return [pTemplate[1], function(matched, index, original) {
var templateDocument = db.getBinaryMetadata("DOCUMENTTEMPLATE", "DOCUMENT", pTemplate[0], false, alias, null);
var binaryId = templateDocument[0][db.BINARY_ID];
return util.decodeBase64String(db.getBinaryContent(binaryId, alias));
}];
});
// Note: some embedded templates in embedded templates may be replaced, but this is NOT SUPPORTED, as it only works if the second template is not already replaced at that time.
placeholders.forEach(function(pPlaceholder) {
replacedContent = replacedContent.replace("{@" + pPlaceholder[0] + "@}", pPlaceholder[1], "g")
}, this);
this._subtemplatedContent = util.encodeBase64String(replacedContent);
}
}
DocumentTemplate.prototype._getTemplatedContent = function (pWithSubtemplates) {
if (this._subtemplatedContent != null && pWithSubtemplates)
return this._subtemplatedContent;
else
return this.content;
}
/**
* @return {DocumentTemmplate[]} if the templateId exists, it returns all attachments associated by the id as DocumentTemplate array else it just returns an empty array.
*/
DocumentTemplate.prototype.getAttachments = function ()
{
if (!this.templateId && this._attachmentCache == null)
{
return [];
}
if (this._attachmentCache == null)
{
var attachmentIds = db.array(db.COLUMN, SqlCondition.begin()
.andPrepare("DOCUMENTTEMPLATELINK.DOCUMENTTEMPLATE_ID_PARENT", this.templateId)
.buildSql("select DOCUMENTTEMPLATE_ID_CHILD from DOCUMENTTEMPLATELINK"));
this._attachmentCache = attachmentIds.map(function(pAttachmentId)
{
return DocumentTemplateUtils.getTemplate(pAttachmentId, false);
});
}
return this._attachmentCache;
}
/**
* @param {DocumentTemplate[]} pAttachments array of templates which should be used as attachment
*/
DocumentTemplate.prototype.setAttachments = function (pAttachments)
{
this._attachmentCache = pAttachments;
}
/**
* The types a DocumentTemplate can have. Depending on the type,
* the correct method for replacing the placeholders can be chosen
*
* @enum {String}
*/
DocumentTemplate.types = {
TXT : "txt",
HTML : "html",
EML : "eml",
ODT : "odt",
DOCX : "docx",
PLAIN : "plain", //for simple strings
/**
* chooses the type depending on the file extension
*/
fromFileExtension : function (pFileExtension)
{
switch (pFileExtension)
{
case "html":
case "htm":
return this.HTML;
case "eml":
return this.EML;
case "odt":
return this.ODT;
case "docx":
return this.DOCX;
case "txt":
return this.TXT;
case "msg":
case "oft":
default:
return null;
}
},
/**
* chooses the type depending on the mime type
*/
fromMimeType : function (pMimetype)
{
switch (pMimetype)
{
case MimeTypes.HTML():
return this.HTML;
case MimeTypes.EML():
return this.EML;
case MimeTypes.ODT():
return this.ODT;
case MimeTypes.DOCX():
return this.DOCX;
case MimeTypes.TXT():
return this.TXT;
case MimeTypes.MSG():
default:
return null;
}
},
/**
* chooses the type depending on the extension in the metadata. If the extension doesn't work, try mimetype
* @param {String[]} pBinaryMetadata the binary metadata from system.db
*/
fromBinaryMetadata: function(pBinaryMetadata)
{
let filename = pBinaryMetadata[db.BINARY_FILENAME].split(".");
let type = DocumentTemplate.types.fromFileExtension(filename[filename.length - 1]);
if (type == null)
type = DocumentTemplate.types.fromMimeType(pBinaryMetadata[db.BINARY_MIMETYPE]);
return type;
}
};
/**
* Loads the content of a document template and creates a new DocumentTemplate object with that.
*
* @param {String} pAssignmentRowId id of the assignment (in most cases the document template id)
* @param {String} [pAssignmentTable="DOCUMENTTEMPLATE"] the LOB assignment table
* @param {Boolean} [pResolveSubtemplates=true] if true subtemplates are resolved (if the type fits)
* @return {DocumentTemplate} template object
*/
DocumentTemplate.loadTemplate = function (pAssignmentRowId, pAssignmentTable, pResolveSubtemplates)
{
var alias = SqlUtils.getBinariesAlias();
if (!pAssignmentTable)
pAssignmentTable = "DOCUMENTTEMPLATE";
// if the templateId is accessable, use it, to enable the templateto load attachments
var templateId;
if (pAssignmentTable == "DOCUMENTTEMPLATE")
templateId = pAssignmentRowId;
if (templateId)
{
return DocumentTemplateUtils.getTemplate(templateId, pResolveSubtemplates)
}
var templateDocument = db.getBinaryMetadata(pAssignmentTable, "DOCUMENT", pAssignmentRowId, false, alias, null);
if (!templateDocument[0])
return new DocumentTemplate(undefined, undefined, undefined, undefined, templateId);
var binaryId = templateDocument[0][db.BINARY_ID];
var filename = templateDocument[0][db.BINARY_FILENAME];
var type = DocumentTemplate.types.fromBinaryMetadata(templateDocument[0]);
if (pResolveSubtemplates == undefined) pResolveSubtemplates = true;
return new DocumentTemplate(db.getBinaryContent(binaryId, alias), type, filename, pResolveSubtemplates, templateId);
}
/**
* makes a DocumentTemplate from a upload value
*
* @param {FileUpload} pDocumentUpload FileUpload object
* @return {DocumentTemplate} a document template
*/
DocumentTemplate.fromUpload = function (pDocumentUpload)
{
var type;
//if the mimetype couldn't be determined, check the file extension
if (pDocumentUpload.mimeType == MimeTypes.BIN())
type = DocumentTemplate.types.fromFileExtension(pDocumentUpload.fileExtension);
else
type = DocumentTemplate.types.fromMimeType(pDocumentUpload.mimeType);
return new DocumentTemplate(pDocumentUpload.bindata, type, pDocumentUpload.filename, true);
}
/**
* Function that helps to get the correct template when editing a bulk mail.
* pUploadValue is preferred over pTemplateId, and if pEditedContent is provided,
* it will overwrite the content of the template (but the type will remain the same as
* defined by the upload or templateId, if both are empty, pDefaultType is used)
*
* @param {String} pTemplateId
* @param {FileUpload} pDocumentUpload
* @param {String} [pEditedContent]
* @param {String} [pDefaultType]
* @return {DocumentTemplate} the document template
*/
DocumentTemplate.getSelectedTemplate = function (pTemplateId, pDocumentUpload, pEditedContent, pDefaultType)
{
if (pDocumentUpload.isFilled())
template = DocumentTemplate.fromUpload(pDocumentUpload);
else if (pTemplateId)
template = DocumentTemplate.loadTemplate(pTemplateId);
else
template = new DocumentTemplate(null, pDefaultType || DocumentTemplate.types.TXT, null, true);
if (pEditedContent)
{
if (template.type == DocumentTemplate.types.EML || template.type == DocumentTemplate.types.HTML)
pEditedContent = "<html>" + pEditedContent + "</html>";
template.content = util.encodeBase64String(pEditedContent);
}
return template;
}
/**
* Returns the template content with replaced placeholders by choosing the right
* replace function for the type.
*
* @param {Object} pReplacements map, the structure is {placeholder : value}
* @param {Boolean} pEncoded if the replaced content should be base64 encoded
* (doesn't affect odt/docx)
* @param {Boolean} [pEmlOnlyBody=false] if true for eml's only the body is parsed (e.g. for previews. Note that eml-bodies are not editable!)
*
* @return {String} the replaced content
*/
DocumentTemplate.prototype.getReplacedContent = function (pReplacements, pEncoded, pEmlOnlyBody)
{
// if there exists a _subtemplatedContent we use it because then I assume that the replacements are already based on content + subtemplates
var content = this._getTemplatedContent(true);
switch (this.type)
{
case DocumentTemplate.types.EML:
let emlContent
if (pEmlOnlyBody)
{
// get only body and treat it as html (next case)
var email = Email.fromRFC(content);
content = util.encodeBase64String(email.body);
}
else
{
emlContent = util.decodeBase64String(content);
emlContent = TemplateHelper._replaceText(emlContent, pReplacements, TemplateHelper._getSpecialRegexp(this));
if (pEncoded)
emlContent = util.encodeBase64String(emlContent);
return emlContent;
}
case DocumentTemplate.types.HTML:
// replaces ä, ö, ü, ... with html escape signs
for (let i in pReplacements)
pReplacements[i] = text.text2html(pReplacements[i], false);
case DocumentTemplate.types.TXT:
let decodedContent = util.decodeBase64String(content);
let encodedContent = TemplateHelper._replaceText(decodedContent, pReplacements, TemplateHelper._getSpecialRegexp(this));
if (pEncoded)
encodedContent = util.encodeBase64String(encodedContent);
return encodedContent;
case DocumentTemplate.types.ODT:
return TemplateHelper._getReplacedODT(this, pReplacements);
case DocumentTemplate.types.DOCX:
return TemplateHelper._getReplacedDOCX(this, pReplacements);
case DocumentTemplate.types.PLAIN:
let plainText = TemplateHelper._replaceText(this.content, pReplacements, TemplateHelper._getSpecialRegexp(this));
if (pEncoded)
plainText = util.encodeBase64String(plainText);
return plainText;
default:
return null;
}
}
/**
* replaces the placeholders with data from one contact and returns the result
*/
DocumentTemplate.prototype.getReplacedContentByContactId = function (pContactId, pEncoded, pEmlOnlyBody)
{
var replacements = TemplateHelper._getReplacementsByContactIds(this, [pContactId]);
var content = this.getReplacedContent(replacements[pContactId], pEncoded, pEmlOnlyBody);
return content;
}
/**
* replaces the placeholders with data from the contacts and returns the result
*
* @param {Array} pContactIds contact ids
* @param {boolean} pEncoded if the replaced content should be base64 encoded
*
* @return {Object} replaced content for every contactId
*/
DocumentTemplate.prototype.getReplacedContentByContactIds = function (pContactIds, pEncoded)
{
var replacements = TemplateHelper._getReplacementsByContactIds(this, pContactIds);
var contents = {};
for (let contactId in replacements)
{
contents[contactId] = this.getReplacedContent(replacements[contactId], pEncoded);
}
return contents;
}
/**
* Replaces the placeholders with data from the contacts and returns a serial letter, works
* only for ODT
*
* @param {Array} pContactIds contact ids
* @param {Object[][][]} pTableData Table data for the document, as a three-dimensional array
* of objects (dimensions are: document, table in that document, rows of the table). For the format, see example.
*
* @example
* var contactSql = SqlCondition.begin()
* .andPrepare("CONTACT.ORGANISATION_ID", orgId)
* .buildSql("select FIRSTNAME, LASTNAME from CONTACT join PERSON on CONTACT.PERSON_ID = PERSON.PERSONID");
*
* var contacts = db.table(contactSql);
* var tblRows = [];
* fnamePlaceholder = PlaceholderUtils.formatPlaceholder("fname");
* lnamePlaceholder = PlaceholderUtils.formatPlaceholder("lname");
*
* for (let i = 0; i < contacts.length; i++)
* {
* let names = {};
* names[fnamePlaceholder] = contacts[i][0];
* names[lnamePlaceholder] = contacts[i][1];
* tblRows.push(names);
* }
*
* var tables = [tblRows];
* var template = DocumentTemplate.loadTEmplate(templateId);
* var letter = template.getSerialLetterByContactIds([contactId], [tables]);
*
* @return {Object} the content of the replaced ODT
*/
DocumentTemplate.prototype.getSerialLetterByContactIds = function (pContactIds, pTableData)
{
if (this.type == DocumentTemplate.types.ODT)
{
let replacements = TemplateHelper._getReplacementsByContactIds(this, pContactIds);
let replaceArray = [];
for (let i = 0, l = pContactIds.length; i < l; i++)
replaceArray.push(replacements[pContactIds[i]]);
return TemplateHelper._getReplacedODT(this, replaceArray, pTableData);
}
question.showMessage(DocumentTemplate.serialLetterODTOnlyMessage, question.INFORMATION, translate.text("Action not supported"))
return null;
}
DocumentTemplate.serialLetterODTOnlyMessage = function()
{
return translate.text("Only .odt files are supported for bulkletters.");
}
/**
* Replaces the placeholders with data from the contacts and returns the resulting Emails.
*
* @param {Array} pContactIds contact ids
*
* @return {Object} Object containing the contact ids as keys and the corresponding Email
* objects as values
*/
DocumentTemplate.prototype.getReplacedEmailsByContactIds = function (pContactIds)
{
var replacements = TemplateHelper._getReplacementsByContactIds(this, pContactIds);
var emailObj = {};
for (let contactId in replacements)
{
if (this.type == DocumentTemplate.types.EML)
{
emailObj[contactId] = new Email();
emailObj[contactId].emlFile = this.getReplacedContent(replacements[contactId])
}
else
{
let body = this.getReplacedContent(replacements[contactId]);
if (this.type == DocumentTemplate.types.TXT || this.type == DocumentTemplate.types.PLAIN)
body = text.text2html(body, false);
emailObj[contactId] = new Email();
emailObj[contactId].body = body
}
}
return emailObj;
}
/**
* Provides functions for the DocumentTemplate object that aren't accessible from outside
*/
function TemplateHelper () {}
TemplateHelper._replaceText = function (pText, pReplacements, pSpecialCharFilterRegexpPart)
{
if (pSpecialCharFilterRegexpPart == undefined) pSpecialCharFilterRegexpPart = "";
pText = pText.replace(new RegExp(PlaceholderUtils.getRegexpMatchAll(pSpecialCharFilterRegexpPart), "gi"), function(pFound) {
let foundFiltered = pFound.replace(new RegExp(pSpecialCharFilterRegexpPart, "gi"),"");
return pReplacements[foundFiltered] ? pReplacements[foundFiltered] : pFound;
}, "gi")
return pText;
}
/**
* @param {DocumentTemplate} pTemplate
* @param {String[]} pForcedPlaceholders these placeholders are always loaded
* @return {Object[]} all placeholders needed in this template or null, if
* @private
*/
TemplateHelper._getRequiredPlaceholders = function (pTemplate, pForcedPlaceholders)
{
var content = "";
content = pTemplate.toString(true);
// get special regexp (e.g. to filter '=' in emls)
var filterRegexpPart = TemplateHelper._getSpecialRegexp(pTemplate);
var placeholders = PlaceholderUtils.getPlaceholders();
var placeholderCleanRegexp = new RegExp(filterRegexpPart, "gi");
// get all placeholders which matches the placeholder pattern
var foundPlaceholders = content.match(new RegExp(PlaceholderUtils.getRegexpMatchAll(TemplateHelper._getSpecialRegexp(pTemplate)), "gi"));
if (foundPlaceholders == null)
foundPlaceholders = [];
// clean placeholder from the spechial strings (e.g. to filter '=' in emls)
foundPlaceholders = foundPlaceholders.map(function(pFound) {
return pFound.replace(placeholderCleanRegexp,"");
});
// filter the possible placeholders by all placeholders found
placeholders = placeholders.filter(function(pPlaceholder)
{
return foundPlaceholders.indexOf(pPlaceholder.placeholderName) != -1 || pForcedPlaceholders.indexOf(pPlaceholder.placeholderName) >= 0;
});
return placeholders;
}
/**
* Builds an object with the placeholder data for multiple contacts
*
* @param {DocumentTemplate} pTemplate document template
* @param {Array} pContactIds contact ids
*
* @return {Object} Object containing the data. The structure is like {contactId : {placeholderName : replacementValue, ...}, ...}
*
* @private
*/
TemplateHelper._getReplacementsByContactIds = function (pTemplate, pContactIds)
{
var config = TemplateHelper._getRequiredPlaceholders(pTemplate, ["{@firstname@}", "{@lastname@}"]);
var contactIdPlaceholder = new Placeholder("contactId", Placeholder.types.SQLPART, "CONTACT.CONTACTID");
config = [contactIdPlaceholder].concat(config);
var addressData = getAddressesData(pContactIds, config, EmployeeUtils.getCurrentContactId()); //TODO: add sender selection
var replacements = {};
var placeholderNames = addressData[0];
var contactIdIndex = placeholderNames.indexOf(contactIdPlaceholder.toString());
for (let i = 1; i < addressData.length; i++)
{
let contactId = addressData[i][contactIdIndex];
for (let ii = 0, ll = placeholderNames.length; ii < ll; ii++)
{
if (!(contactId in replacements))
replacements[contactId] = {};
replacements[contactId][placeholderNames[ii]] = addressData[i][ii];
}
}
return replacements;
}
/*
* replaces a given Odt-File on the server and returns the replaced base64-file
*
* @param {DocumentTemplate} pTemplate document template
* @param {Object} pReplacements map of placeholders and replacements
* @param {Array} pTableData
*
* @return {String} base64-encoded replaced file
*
* @private
*/
TemplateHelper._getReplacedODT = function (pTemplate, pReplacements, pTableData)
{
var filename = pTemplate.filename;
if (!filename)
filename = "dummyname.odt";
//save the file on the server so it can be unzipped via pack.getFromZip
var serverFilePath = vars.get("$sys.servertemp") + "/clientid_" + vars.get("$sys.clientid")
+ "/" + util.getNewUUID() + "/" + filename.replace(/\\/g, "/");
fileIO.storeData(serverFilePath, pTemplate.content, util.DATA_BINARY, false);
if (!_replaceODTFile(pReplacements, serverFilePath, pTableData))
return null;
var replacedFileData = fileIO.getData(serverFilePath, util.DATA_BINARY);
fileIO.remove(serverFilePath);
return replacedFileData;
/**
* replaces placeholders in a odt file
*
* @param {Object} pReplacements replacement object
* @param {String} pODTFileName filename of the odt
* @param {Array} pTableData
*
* @return {Boolean}
*/
function _replaceODTFile (pReplacements, pODTFileName, pTableData)
{
var senderRelId = EmployeeUtils.getCurrentContactId();
if (senderRelId == null)
return false;
if (pReplacements.length === undefined)
pReplacements = [pReplacements];
if (!pTableData)
pTableData = [];
if (pReplacements.length !== 0)
{
//replace placeholders in content.xml
var contentXml = util.decodeBase64String(pack.getFromZip(pODTFileName, "content.xml"));
var bodybegin = contentXml.indexOf("<office:body>");
var bodyend = contentXml.indexOf("</office:body>") + 14;
var bodyTemplate = contentXml.substring(bodybegin, bodyend);
var fullBody = ""; //body that contains all pages (required when the replacing is done for several contacts)
var beforeBody = contentXml.substring(0, bodybegin);
var afterBody = contentXml.substr(bodyend);
for (let i = 0, l = pReplacements.length; i < l; i++)
{
let replacements = pReplacements[i];
let currentBody = bodyTemplate;
/* This only works if the text of the placeholders in the odt were not edited since they were written.
* If you edit the odt and change a placeholder (for example: you change '{@addres@}' to '{@address@}'),
* the text is saved in different XML tags and won't be replaced correctly.
*/
for (let placeholder in replacements)
{
currentBody = currentBody.replace(placeholder,
replacements[placeholder].replace(/\n/ig, "<text:line-break/>").replace(/&/ig, "&"), "ig");
}
let tables = pTableData[i] || [];
let fromIndex = 0;
for (let tblIndex = 0; tblIndex < tables.length; tblIndex++) //iterate over all tables in the document
{
let tableData = tables[tblIndex];
if (tableData && tableData.length > 0)
{
fromIndex = currentBody.indexOf("</table:table>", fromIndex) + 14;
if (fromIndex === -1) //stop if there is no table
break;
let rowBegin = currentBody.lastIndexOf("<table:table-row", fromIndex);
let rowEnd = currentBody.indexOf("</table:table-row>", rowBegin) + 18;
let afterTable = currentBody.substr(rowEnd);
let tableRow = currentBody.substring(rowBegin, rowEnd);
currentBody = currentBody.substring(0, rowBegin);
for (let rowIndex = 0; rowIndex < tableData.length; rowIndex++)
{
let tableRowData = tableData[rowIndex];
currentBody += TemplateHelper._replaceText(tableRow, tableRowData);
}
currentBody += afterTable;
}
}
fullBody += currentBody;
}
contentXml = beforeBody + fullBody + afterBody;
pack.addToZip(pODTFileName, "content.xml", util.encodeBase64String(contentXml));
//replace placeholders in styles.xml
var styles = util.decodeBase64String(pack.getFromZip(pODTFileName, "styles.xml"));
for (let placeholder in pReplacements[0])
{
styles = styles.replace(placeholder,
pReplacements[0][placeholder].replace(/\n/ig, "<text:line-break/>").replace(/&/ig, "&"), "ig");
}
pack.addToZip(pODTFileName, "styles.xml", util.encodeBase64String(styles));
return true;
}
return false;
}
}
/*
* This function is used to replace placeholders via DocXTemplater
*
* @param {DocumentTemplate} pTemplate document template
* @param {Object} pReplacements - Must contain an object, which holds the placeholders
*
* @return {String} returns the modified document in a BASE64 coded string
*
* @private
*/
TemplateHelper._getReplacedDOCX = function (pTemplate, pReplacements)
{
var replacements = {};
for (let placeholder in pReplacements) //removes the prefix and postfix, the process needs it like this
replacements[placeholder.slice(2, -2)] = pReplacements[placeholder];
//this is executed as a process because of better performance
var documentData = process.execute("getDocxDocument_serverProcess", {
templateb64: pTemplate.content,
placeholderConfig: JSON.stringify(replacements) //process.execute is only able to handle strings
});
return documentData;
}
TemplateHelper._getSpecialRegexp = function (pTemplate)
{
switch (pTemplate.type)
{
case DocumentTemplate.types.EML:
return "\\s*(=\\r?\\n)?";
default:
return "";
}
}
return DocumentTemplate;
})();
/**
* functions for working with letters (mails)
*/
function LetterUtils () {}
/**
* opens a new letter
*
* @param {String} pContactId id of the contact to fetch the data from
*/
LetterUtils.openNewLetter = function (pContactId)
{
var params = {
"ContactId_param" : pContactId
};
neon.openContext("Letter", "LetterEdit_view", null, neon.OPERATINGSTATE_NEW, params);
}
/**
* utility functions for the DocumentTemplate_entity
*/
function DocumentTemplateUtils () {}
/**
* if pText is provided, it is used as template, otherwise pFileUpload
*
* @param {FileUpload} pFileUpload upload value
* @param {String} pKind kind of template
* @param {String} pText text input
* @param {String} pClassification the classification type. Used if pText is not empty. Defines if it is saved as txt or html.
* @param {String} pTemplateName name of the template
* @param {Boolean} pChangedByUser if false the data in pText is ignored
* @return {FileUpload} a FileUpload object with the data
*/
DocumentTemplateUtils.chooseSuppliedTemplate = function (pFileUpload, pKind, pText, pClassification, pTemplateName, pChangedByUser)
{
if (pFileUpload.isFilled() && pText != "")
{
// use fileUpload but use the custom text as bindata
pFileUpload.bindata = util.encodeBase64String(pText);
}
else if (!pFileUpload.isFilled() && pText != "" && (pChangedByUser == undefined || pChangedByUser))
{
pFileUpload.filename = pTemplateName;
// if it is a htmlTemplate save it with the html extension
if (pClassification == $KeywordRegistry.documentTemplateTypeCategory$htmlTemplate() || pKind == $KeywordRegistry.documentTemplateType$mail())
pFileUpload.fileExtension = "html";
else
pFileUpload.fileExtension = "txt";
pFileUpload.bindata = util.encodeBase64String(pText);
}
return pFileUpload;
}
/**
* inserts a template from a document template into ASYS_BINARIES
*/
DocumentTemplateUtils.insertTemplateData = function (pTemplateId, pFileUpload, pKind, pText, pClassification, pTemplateName)
{
pFileUpload = DocumentTemplateUtils.chooseSuppliedTemplate(pFileUpload, pKind, pText, pClassification, pTemplateName)
if (pFileUpload.isFilled())
{
db.insertBinary("DOCUMENTTEMPLATE", "DOCUMENT", pTemplateId,
"", pFileUpload.bindata, pFileUpload.filename, "", "TEMPLATE", SqlUtils.getBinariesAlias());
}
}
/**
* updates a template from a document template in ASYS_BINARIES
*/
DocumentTemplateUtils.updateTemplateData = function (pTemplateId, pFileUpload, pKind, pText, pClassification, pTemplateName, pChangedByUser)
{
pFileUpload = DocumentTemplateUtils.chooseSuppliedTemplate(pFileUpload, pKind, pText, pClassification, pTemplateName, pChangedByUser)
if (pFileUpload.isFilled())
{
var assignmentTable = "DOCUMENTTEMPLATE";
var assignmentName= "DOCUMENT";
var keyword = "TEMPLATE";
var binMeta = db.getBinaryMetadata(assignmentTable, assignmentName, pTemplateId, false, SqlUtils.getBinariesAlias(), keyword);
if (binMeta.length == 0)
SingleBinaryUtils.insertMainDocument(assignmentTable, assignmentName, pTemplateId, pFileUpload.bindata, pFileUpload.filename, null, SqlUtils.getBinariesAlias());
else
db.updateBinary(binMeta[0][db.BINARY_ID], "", pFileUpload.bindata, pFileUpload.filename, "", keyword, SqlUtils.getBinariesAlias());
}
}
/**
* loads content from a fileUpload or if it's empty from a template in ASYS_BINARIES
* @param {String} pTemplateId the id of the template
* @param {FileUpload} pFileUpload upload object
*
* @return {String[]} [content, type] or ["", type] or ["", null]
* Content is only set, if it is HTML, TXT or EML
*/
DocumentTemplateUtils.getTemplateContent = function (pTemplateId, pFileUpload)
{
var type;
var bindata;
if (pFileUpload.isFilled())
{
type = DocumentTemplate.types.fromFileExtension(pFileUpload.fileExtension);
bindata = pFileUpload.bindata
}
else
{
var template = DocumentTemplateUtils.getTemplate(pTemplateId, false);
if (template != null)
{
bindata = template.content;
type = template.type;
}
}
if (type == DocumentTemplate.types.HTML || type == DocumentTemplate.types.TXT || type == DocumentTemplate.types.EML)
{
return [util.decodeBase64String(bindata), type];
}
return ["", type];
}
/**
* loads a template
* @param {String} pTemplateId the id of the template
* @param {Boolean} pResolveSubtemplates true, if subtemplates should be resolved
*
* @return {DocumentTemplate}
*/
DocumentTemplateUtils.getTemplate = function (pTemplateId, pResolveSubtemplates)
{
var assignmentTable = "DOCUMENTTEMPLATE";
var assignmentName= "DOCUMENT";
var keyword = "TEMPLATE";
var binMeta = db.getBinaryMetadata(assignmentTable, assignmentName, pTemplateId, false, SqlUtils.getBinariesAlias(), keyword);
if (binMeta.length != 0)
{
return new DocumentTemplate(
db.getBinaryContent(binMeta[0][db.BINARY_ID], SqlUtils.getBinariesAlias()),
DocumentTemplate.types.fromBinaryMetadata(binMeta[0]),
binMeta[0][db.BINARY_FILENAME],
pResolveSubtemplates, pTemplateId);
}
return null;
}
/**
* loads the mimetype from a fileUpload or if it's empty from a template in ASYS_BINARIES
* @param {String} pTemplateId the id of the template
* @param {FileUpload} pFileUpload upload object
*
* @return {String} mimetype
*/
DocumentTemplateUtils.getMimeType = function (pTemplateId, pFileUpload)
{
var type;
if (pFileUpload && pFileUpload.isFilled())
{
type = pFileUpload.mimeType;
}
else
{
var assignmentTable = "DOCUMENTTEMPLATE";
var assignmentName= "DOCUMENT";
var keyword = "TEMPLATE";
var binMeta = db.getBinaryMetadata(assignmentTable, assignmentName, pTemplateId, false, SqlUtils.getBinariesAlias(), keyword);
if (binMeta.length != 0)
{
let binMeta = db.getBinaryMetadata(assignmentTable, assignmentName, pTemplateId, false, SqlUtils.getBinariesAlias(), keyword);
type = binMeta[0][db.BINARY_MIMETYPE];
}
}
return type;
}
/**
* loads the type from a fileUpload or if it's empty from a template in ASYS_BINARIES
* @param {String} pTemplateId the id of the template
* @param {FileUpload} pFileUpload upload object
*
* @return {String} type via DocumentTemplate.types or null
*/
DocumentTemplateUtils.getContentType = function (pTemplateId, pFileUpload)
{
var type;
if (pFileUpload.isFilled())
{
type = DocumentTemplate.types.fromFileExtension(pFileUpload.fileExtension);
}
else
{
var assignmentTable = "DOCUMENTTEMPLATE";
var assignmentName= "DOCUMENT";
var keyword = "TEMPLATE";
var binMeta = db.getBinaryMetadata(assignmentTable, assignmentName, pTemplateId, false, SqlUtils.getBinariesAlias(), keyword);
if (binMeta.length != 0)
{
let binMeta = db.getBinaryMetadata(assignmentTable, assignmentName, pTemplateId, false, SqlUtils.getBinariesAlias(), keyword);
type = DocumentTemplate.types.fromBinaryMetadata(binMeta[0]);
}
}
return type;
}