Newer
Older
/*
*Deletes all stored eml files for a bulk mail
*
*@param {String} pBulkMailId <p>
* The id of the bulk mail.<br>
*
**/
BulkMailUtils.deleteAllEmlFiles = function (pBulkMailId)
{
var locationOption = project.getInstanceConfigValue("bulkmail.fileStorage", vars.get("$sys.serverdata"));
var path = locationOption + (locationOption.substr(locationOption.length-1) == "/" ? "" : "/" )+ "bulkmailfiles/" + pBulkMailId;
FileUtils.removeFolder(path);
}
/*
* Stores the eml file of a bounce in the filesystem
*
* @param {String} pBounceId <p>
* The id of the bounce.<br>
* @param {String} pFile
**/
BulkMailUtils.storeBounceEmlFile = function (pBounceId, pFile)
{
var locationOption = project.getInstanceConfigValue("bulkmail.fileStorage", vars.get("$sys.serverdata"));
var path = locationOption + (locationOption.substr(locationOption.length-1) == "/" ? "" : "/" )+ "bulkmailfiles/bounces/";
var filename = pBounceId + ".eml"
var fullPath = path + filename;
fileIO.storeData(fullPath, pFile, util.DATA_TEXT, false);
}
Martin Groppe
committed
/*
*Loads the Eml file for a bulkmailrecipient from the Filesystem
*
* @param {String} pBulkMailId <p>
* The id of the bulk mail.<br>
* @param {String} pMailRunId <p>
* The id of the bulk mail run.<br>
* @param {String} pMailLogId <p>
* The id of the corresponding mail log entry.<br>
* @return {String} <p>
* The file as base64 String<br>
**/
BulkMailUtils.getEmlFile = function(pBulkMailId,pMailRunId, pMailLogId)
{
var locationOption = project.getInstanceConfigValue("bulkmail.fileStorage", vars.get("$sys.serverdata"));
var path = locationOption + (locationOption.substr(locationOption.length-1) == "/" ? "" : "/" )+ "bulkmailfiles/" + pBulkMailId + "/" + pMailRunId + "/";
Martin Groppe
committed
var filename = pMailLogId+".eml"
var fullPath = path + filename;
return (fileIO.getData(fullPath,util.DATA_BINARY));
}
Martin Groppe
committed
/*
*Gets the redirecturl for a link in a bulkmail
*
* @param {String} pLinkId <p>
* The id of the link.<br>
* @param {String} pBaseUrl <p>
* The base url for relative links<br>
Martin Groppe
committed
* @param {String} pMailLogId <p>
* The mail log id for contact id replacement<br>
Martin Groppe
committed
* @return {String} <p>
* The url<br>
**/
Martin Groppe
committed
BulkMailUtils.getRedirectLink = function(pLinkId, pBaseUrl, pMailLogId)
Martin Groppe
committed
if (pLinkId && pMailLogId)
Martin Groppe
committed
var contactId = newSelect("CONTACT_ID")
.from("MAIL_LOG")
.where("MAIL_LOG.MAIL_LOGID", pMailLogId)
.cell();
var link = newSelect("WEBLINK.URL").from("WEBLINK").where("WEBLINK.WEBLINKID", pLinkId).cell();
Martin Groppe
committed
link = StringUtils.replaceAll(link, "{@contactid@}", contactId);
if(link[0] == "/")
{
link = pBaseUrl + link;
}
return link;
Martin Groppe
committed
}
Martin Groppe
committed
}
/*
*Inserts the Redirect into the link_click table.
*
*If its the first Click the Id gets put as opener in mail_log
*
* @param {String} pMailLogId (required)<p>
* The id of the mail log.<br>
* @param {String} pIpAddress <p>
* the ip address of the client.<br>
* @param {String} pLinkId <p>
* The id of link.<br>
* @param {String} pBrowsername <p>
* The browser that was used to open the link.<br>
* @param {String} pOperatingSystemName <p>
* The Operating System that was used to open the link.<br>
* @param {String} pDeviceType <p>
* The device type that was used to open the link.<br>
**/
BulkMailUtils.insertClick = function (pMailLogId,pIpAddress,pLinkId,pBrowsername,pOperatingSystemName,pDeviceType)
{
if (!pMailLogId || !pLinkId)
{
Martin Groppe
committed
}
var linkClickId = util.getNewUUID();
new SqlBuilder()
.tableName("WEBLINK_CLICK")
.insertFields({
"WEBLINK_CLICKID": linkClickId,
"WEBLINK_ID": pLinkId,
"DEVICE_TYPE": pDeviceType || "desktop",
"OPERATING_SYSTEM": pOperatingSystemName,
"BROWSER": pBrowsername,
"IP_ADDRESS": pIpAddress,
"MAIL_LOG_ID": pMailLogId,
"DATE_OPENED": vars.get("$sys.date")
});
Martin Groppe
committed
newWhere("MAIL_LOG.MAIL_LOGID", pMailLogId)
.and("MAIL_LOG.OPENER_LINK_CLICK_ID is null")
.updateFields({"OPENER_LINK_CLICK_ID": linkClickId});
Martin Groppe
committed
}
Martin Groppe
committed
/* Gets the Ip Address out of the http header
*
* @param {Object} pHttpHeader the http header object
Martin Groppe
committed
*
Martin Groppe
committed
* @return {String} the original ip address of the recipient
Martin Groppe
committed
**/
BulkMailUtils.getIpAddressFromHeader = function(pHttpHeader)
{
return pHttpHeader["X-forwarded-for"].split(",")[0];
Martin Groppe
committed
}
BulkMailUtils.startBulkmailWorkFlow = function(pMailLogId, pLinkId)
{
if (!pMailLogId || !pLinkId)
{
Martin Groppe
committed
return
}
var [linkActionType, workflowKey, signalName] = newSelect(["ACTION_TYPE", "WORKFLOWPROCESSDEFINITION_KEY", "WORKFLOWSIGNAL_NAME"])
.from("WEBLINK")
.where("WEBLINK.WEBLINKID", pLinkId)
.arrayRow();
var contactId = newSelect("CONTACT_ID")
.from("MAIL_LOG")
.where("MAIL_LOG.MAIL_LOGID", pMailLogId)
.cell();
"linkId": pLinkId,
"contactId": contactId
if (linkActionType == $KeywordRegistry.weblinkActionType$startWorkflow() && workflowKey)
workflow.startProcessByKey(workflowKey, processVariables);
else if (linkActionType == $KeywordRegistry.weblinkActionType$sendWorkflowSignal() && signalName)
workflow.signalEventReceived(signalName, processVariables);
Martin Groppe
committed
}
}
/* Checks if the Content is just the default empty html
*
* @param {String} pContent content
*
* @return {Boolean} true if content is not just empty html tag and not an empty string
**/
BulkMailUtils.isNotEmptyHtml = function(pContent)
{
return pContent !== "<html></html>" && pContent !== "";
}
Martin Groppe
committed
* Adds recipients to a serial letter.<br>
* @param {String} pSerialLetterId <p>
* The id of the serial letter.<br>
* @param {String[]} pContactIds <p>
* Contact ids of the recipients.<br>
*/
SerialLetterUtils.addRecipients = function (pSerialLetterId, pContactIds)
{
var columns = [
"LETTERRECIPIENTID",
"SERIALLETTER_ID",
"CONTACT_ID"
];
var inserts = [];
for (let i = 0, l = pContactIds.length; i < l; i++)
{
inserts.push(["LETTERRECIPIENT", columns, null, [util.getNewUUID(), pSerialLetterId, pContactIds[i]]]);
}
db.inserts(inserts);
}
/**
* Opens a context to select a serial letter to add recipients to.<br>
* @param {String} pContext the context of the contacts (Person or Organisation)
* @param {String[]} pContactIds Recipients that should be added.<br>
* @param {String|Object} pFilter the filter for the contacts that should be used if no contact is selected
SerialLetterUtils.openAddRecipientView = function (pContext, pContactIds, pFilter)
if (!Utils.isString(pContactIds))
pContactIds = JSON.stringify(pContactIds);
if (!Utils.isString(pFilter))
pFilter = JSON.stringify(pFilter);
var recipe = neonFilter.createEntityRecordsRecipeBuilder().parameters({
"ObjectType_param": pContext,
"ContactIds_param": pContactIds,
"ContactFilter_param": pFilter

Florian Maier
committed
neon.openContextWithRecipe("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", recipe, neon.OPERATINGSTATE_VIEW);
* Executes a server process that builds a serial letter.<br>
* @param {String} pSerialLetterId <p>
* The id of the serial letter.<br>
* @param {String[]} pRecipientIds (optional) <p>
* Letter recipient ids of that should be used.<br>
* If omitted, all recipients of the letter will be used.<br>
SerialLetterUtils.buildSerialLetterOnServer = function (pSerialLetterId, pRecipientIds)
var processConfig = process.createStartAsyncConfig()
.setName("buildSerialLetter_serverProcess")
.setLocalVariables({
"serialLetterId" : pSerialLetterId,
"recipientIds" : JSON.stringify(pRecipientIds),
"user" : user
})
.setUser(vars.get("$sys.user"));
process.startAsync(processConfig);
* Executes a server process that builds a serial letter.<br>
* @param {String} pSerialLetterId <p>
* Serial letter id.<br>
* @param {String[]} pRecipientIds <p>
* Letter recipient ids of that should be used.<br>
* If omitted, all recipients of the letter will be used.<br>
*/
SerialLetterUtils.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
{
var [templateId, title] = newSelect("DOCUMENTTEMPLATE_ID, TITLE")
.from("SERIALLETTER")
.where("SERIALLETTER.SERIALLETTERID", pSerialLetterId)
.arrayRow(true);
var template = SerialLetterUtils.getSerialLetterTemplate(pSerialLetterId, templateId);
var contactIdsSelect = newSelect("CONTACT_ID")
.from("LETTERRECIPIENT")
.join("CONTACT", newWhere("LETTERRECIPIENT.CONTACT_ID = CONTACT.CONTACTID"))
.where("LETTERRECIPIENT.SERIALLETTER_ID", pSerialLetterId)
.andIfSet(new CommunicationSettingsCondition()
.address("CONTACT.ADDRESS_ID")
.rejected()
.existNoSettings()
.buildCondition());
contactIdsSelect.and("LETTERRECIPIENT.LETTERRECIPIENTID", pRecipientIds, SqlBuilder.IN());
if(template != null)
{
return {
content : template.getSerialLetterByContactIds(contactIds),
filename : template.filename,
title : title
};
}
else
{
return{
title : title
* Checks if a contact is a recipient of a serial letter.<br>
* @param {String} pSerialLetterId <p>
* The id of the serial letter.<br>
* @param {String} pContactId <p>
* The contact id of the contact.<br>
* @param {String} pRecipientId (optional) <p>
* Letter recipient id.<br>
* @return {Boolean} <p>
* True, if the contact is a recipient<br>
* and otherwise false.<br>
*/
SerialLetterUtils.isRecipient = function (pSerialLetterId, pContactId, pRecipientId)
{
.where("LETTERRECIPIENT.CONTACT_ID", pContactId)
.and("LETTERRECIPIENT.SERIALLETTER_ID", pSerialLetterId)
.andIfSet("LETTERRECIPIENT.LETTERRECIPIENTID", pRecipientId, SqlBuilder.NOT_EQUAL())
.cell() != "0"; // TODO: is there a way exists could be used?
/**
* Opens the serial letter context in new mode, with<br>
* the given serial letter id.<br>
*
* @param {String} pSerialLetterId <p>
* The id of the serial letter.<br>
*/
SerialLetterUtils.openSerialLetter = function (pSerialLetterId)
{
var recipe = neonFilter.createEntityRecordsRecipeBuilder().uidsIncludelist([pSerialLetterId]).toString();

Florian Maier
committed
neon.openContextWithRecipe("SerialLetter", "SerialLetterMain_view", recipe, neon.OPERATINGSTATE_VIEW);
* Loads the document template of a serial letter. <br>
* If the serial letter itself has a template, it is <br>
* preferred over the documentTemplate-id.<br>
* @param {String} pLetterId <p>
* The id of the serial letter.<br>
* @param {String} pDocumentTemplateId <p>
* The id of the document template.<br>
* @return {DocumentTemplate} <p>
* The document template.<br>
*/
SerialLetterUtils.getSerialLetterTemplate = function (pLetterId, pDocumentTemplateId)
{
var template = DocumentTemplate.loadTemplate(pLetterId, "SERIALLETTER");
if (!template.type)
template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
return template;

Benjamin Ulrich
committed
}
/**
* Adds contacts or organistaions to a serial letter by contactIds.<br>
*
* @param {String} pContactIds <p>
* The contact ids as JSON array.<br>
*/
SerialLetterUtils.addParticipantsByRowIds = function(pContactIds)
{
var params = {

Benjamin Ulrich
committed
};
var recipe = neonFilter.createEntityRecordsRecipeBuilder().parameters(params).toString();

Florian Maier
committed
neon.openContextWithRecipe("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", recipe, neon.OPERATINGSTATE_VIEW);

Benjamin Ulrich
committed
}
/**
* Adds contacts or organistaions to a serial letter by condition (filter).<br>
*
* @param {String} pCondition <p>
* Contact ids.
* @param {String} pSourceTableName <p>
* The source table.<br>
*/
SerialLetterUtils.addParticipantsByCondition = function(pCondition, pSourceTableName)
{
var params = {
"ContactIds_param": pCondition,
"comingFrom_param": pSourceTableName
};
var recipe = neonFilter.createEntityRecordsRecipeBuilder().parameters(params).toString();

Florian Maier
committed
neon.openContextWithRecipe("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", recipe, neon.OPERATINGSTATE_VIEW);

Benjamin Ulrich
committed
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
}
/**
* Filters the given contactIds if they can be added as new recipients.
* Checks if a contact is already a recipient or if there is a advertising ban.
*
* @param {String} pSerialLetterId id of the seroal letter the contacts should be added to
* @param {String[]} pContactIds contacts to filter
* @return {String[]} contacts that can be added as recipients
*/
SerialLetterUtils.filterNewRecipients = function (pSerialLetterId, pContactIds)
{
return newSelect("CONTACTID")
.from("CONTACT")
.whereIfSet("CONTACT.CONTACTID", pContactIds, SqlBuilder.IN())
// only add contacts that aren't already recipients
.and(null, newSelect("LETTERRECIPIENTID")
.from("LETTERRECIPIENT")
.where("LETTERRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
.and("LETTERRECIPIENT.SERIALLETTER_ID", pSerialLetterId)
, SqlBuilder.NOT_EXISTS())
// check if there's a commrestriction
.and(new CommunicationSettingsCondition()

Daniel Tran
committed
.address("CONTACT.ADDRESS_ID")
.rejected()
.existNoSettings()
.buildCondition())

Benjamin Ulrich
committed
.arrayColumn();
}