Something went wrong on our end
-
Martin Groppe authored
[Projekt: xRM-Marketing][TicketNr.: 1079868][Redesign: Opener Link Ersetzung muss auf Grund Mosaico Einschränkungen überarbeitet werden]
Martin Groppe authored[Projekt: xRM-Marketing][TicketNr.: 1079868][Redesign: Opener Link Ersetzung muss auf Grund Mosaico Einschränkungen überarbeitet werden]
process.js 35.69 KiB
import("system.logging");
import("system.entities");
import("MarketingCondition_lib");
import("system.fileIO");
import("system.project");
import("Util_lib");
import("system.translate");
import("ActivityTask_lib");
import("system.util");
import("Contact_lib");
import("system.datetime");
import("system.neon");
import("Employee_lib");
import("system.vars");
import("KeywordRegistry_basic");
import("Sql_lib");
import("system.db");
import("DocumentTemplate_lib");
import("Communication_lib");
import("Email_lib");
import("system.process");
import("system.notification");
import("Document_lib");
import("system.db");
import("system.workflow");
import("system.logging");
/**
* Functions for bulk mails.
*/
function BulkMailUtils () {}
/**
* Executes a process to send bulk mails on the server and creates a notification when finished.
*
* @param {String} pBulkMailId <p>
* Id of the bulk mail.<br>
* @param {Bool} pTestRun (optional) <p>
* True indicates a Testrun<br>
* @param {String} pUser=currentUser (optional) <p>
* User that will get the notification, <br>
* if null (not undefined!), no notification<br>
* will be created.<br>
*/
BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pTestRun, pUser)
{
if (pUser === undefined)
pUser = EmployeeUtils.getCurrentUserId();
var processConfig = process.createStartAsyncConfig()
.setName("sendBulkMail_serverProcess")
.setLocalVariables({
bulkMailId : pBulkMailId,
testRun : pTestRun,
user : pUser || ""
})
.setUser(pUser||"mailbridge")
process.startAsync(processConfig);
}
/**
* Sends a bulk mail. You should only call this function on the server because it
* can take some time to execute, use BulkMailUtils.sendBulkMailOnServer instead.
*
* @param {String} pBulkMailId <p>
* Id of the bulk mail.<br>
* @param {Bool} pIsTestRun (optional) <p>
* True indicates a Testrun<br>
* @return {Object} <p>
* Count of sucessful and failed mails.<br>
*/
BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
{
if (pIsTestRun == undefined)
{
pIsTestRun = false;
}
var [templateId, subject, emailSender, createActivity, bulkMailName, useTemplateAttachments] =
newSelect("DOCUMENTTEMPLATE_ID, SUBJECT, SENDER_EMAIL_ADDRESS, CREATEACTIVITIES, NAME, USE_TEMPLATE_ATTACHMENTS")
.from("BULKMAIL")
.where("BULKMAIL.BULKMAILID", pBulkMailId)
.arrayRow();
useTemplateAttachments = Utils.toBoolean(useTemplateAttachments);
var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId, true, useTemplateAttachments);
var recipientData;
var testRecipientData;
var recipientLoadConfig = entities.createConfigForLoadingRows()
.fields(["BULKMAILRECIPIENTID", "CONTACT_ID", "EMAIL_ADDRESS", "PERSON_ID", "ORGANISATION_ID"])
.entity("BulkmailRecipient_entity")
.provider("RecipientsToBeMailed")
.addParameter("BulkMailId_param", pBulkMailId)
.addParameter("IsTestMail_param", pIsTestRun);
recipientData = entities.getRows(recipientLoadConfig);
if (pIsTestRun)
{
testRecipientData = newSelect("BULKMAILTESTRECIPIENT.CONTACT_ID, BULKMAILTESTRECIPIENT.EMAIL_ADDRESS")
.from("BULKMAILTESTRECIPIENT")
.where("BULKMAILTESTRECIPIENT.BULKMAIL_ID", pBulkMailId)
.table();
}
var mailrunId = util.getNewUUID();
new SqlBuilder()
.tableName("MAIL_RUN")
.insertFields({
"MAIL_RUNID": mailrunId,
"OBJECT_ROWID": pBulkMailId,
"OBJECT_TYPE": "Bulkmail",
"DATE_RUN_START": vars.get("$sys.date"),
"STATUS": $KeywordRegistry.bulkMailStatus$beingSent(),
"TESTRUN": pIsTestRun ? 1 : 0
});
var mailLogIds = new Map();
var contactIds = recipientData.map(function (recipient)
{
var contactId = recipient["CONTACT_ID"];
mailLogIds.set(contactId, util.getNewUUID());
return contactId;
});
var baseUrl = vars.get("$sys.origin") + "/services/rest/redirect_rest?";
var linkPlaceholders = newSelect(["PLACEHOLDER", "WEBLINKID", "URL", "ISREDIRECT"])
.from("WEBLINK")
.table()
.map(function ([placeholder, weblinkId, url, isRedirect])
{
if (Utils.toBoolean(isRedirect))
{
var linkFn;
//Mosaico places a url in front of the placeholder if it gets placed inside image src
//so we temporarily create the whole html tag with a placeholder for the opener until this is solved
if (placeholder == "pixel")
{
linkFn = function (pContactId)
{
return "<img src=\""+baseUrl + "link=" + weblinkId + "&log=" + mailLogIds.get(pContactId)+"\" alt=\"\" width=\"1\" height=\"1\" border=\"0\" hspace=\"0\" vspace=\"0\" align=\"top\">";
}
}
else
{
linkFn = function (pContactId)
{
return baseUrl + "link=" + weblinkId + "&log=" + mailLogIds.get(pContactId);
}
}
return new Placeholder(placeholder, Placeholder.types.CALLBACKFUNCTION, linkFn);
}
return new Placeholder(placeholder, Placeholder.types.FIXEDVALUE, url);
});
var successIds = [];
var failedIds = [];
var sentDate = vars.get("$sys.date");
var mails = template.getReplacedEmailsByContactIds(contactIds, linkPlaceholders);
var subjectTemplate = new DocumentTemplate(subject, DocumentTemplate.types.PLAIN);
var subjects = subjectTemplate.getReplacedContentByContactIds(contactIds);
var bulkMailLink = [["BulkMail", pBulkMailId]];
var activitySubject = translate.withArguments("Bulk mail \"%0\" sent", [bulkMailName]);
if (!pIsTestRun)
{
recipientData.forEach(function (recipient)
{
let isSuccess = false;
let recipientId = recipient["BULKMAILRECIPIENTID"];
let contactId = recipient["CONTACT_ID"];
let emailAddress = recipient["EMAIL_ADDRESS"];
let personId = recipient["PERSON_ID"];
let organisationId = recipient["ORGANISATION_ID"];
let email = mails[contactId];
let mailLogId = mailLogIds.get(contactId);
if (email !== undefined && emailAddress)
{
email.toRecipients = [emailAddress];
email.sender = emailSender;
email.subject = subjects[contactId];
BulkMailUtils.storeEmlFile(pBulkMailId, mailrunId, mailLogId,email.getEML());
isSuccess = email.send();
}
//set the recipient status to 'sent' or 'failed'
new SqlBuilder()
.tableName("MAIL_LOG")
.insertFields({
"MAIL_LOGID": mailLogId,
"MAIL_RUN_ID": mailrunId,
"CONTACT_ID": contactId,
"STATUS": isSuccess ? $KeywordRegistry.bulkMailRecipientStatus$sent() : $KeywordRegistry.bulkMailRecipientStatus$failed(),
"SENDER_EMAIL": emailSender,
"RECIPIENT_EMAIL": emailAddress,
"MAILING_SUBJECT": subjects[contactId],
"DATE_SEND": vars.get("$sys.date")
});
//TODO: Klären was von alter Logik noch bleiben soll. Status macht nur Sinn wenn jede Bulkmail nur einmal gesendet wird. Bleiben Activitys?
Array.prototype.push.call(isSuccess ? successIds : failedIds, recipientId);
if (isSuccess && createActivity == "1")
{
let activityData = {
categoryKeywordId : $KeywordRegistry.activityCategory$mail(),
directionKeywordId : $KeywordRegistry.activityDirection$outgoing(),
subject : activitySubject,
content : email.body
};
let contactLink = [[ContactUtils.getContextByPersOrg(personId, organisationId), contactId]];
ActivityUtils.insertNewActivity(activityData, bulkMailLink.concat(contactLink));
}
});
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds, SqlBuilder.IN())
.updateFields({
"STATUS": $KeywordRegistry.bulkMailRecipientStatus$sent(),
"SENTDATE": sentDate
});
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds, SqlBuilder.IN())
.updateFields({
"STATUS": $KeywordRegistry.bulkMailRecipientStatus$failed(),
"SENTDATE": sentDate
});
newWhere("MAIL_RUN.MAIL_RUNID", mailrunId)
.updateFields({
"STATUS": $KeywordRegistry.bulkMailStatus$sent(),
"DATE_RUN_FINISHED": vars.get("$sys.date")
});
newWhere("BULKMAIL.BULKMAILID", pBulkMailId)
.updateFields({
"STATUS": $KeywordRegistry.bulkMailStatus$sent()
});
}
else
{
for (let i = 0, l = recipientData.length; i < l; i++)
{
let isSuccess = false;
let contactId = recipientData[i]["CONTACT_ID"];
let email = mails[contactId];
if (email !== undefined)
{
email.sender = emailSender;
email.subject = "Test: "+subjects[contactId];
for (let j =0; j<testRecipientData.length;j++)
{
if(testRecipientData[j][1])
{
email.toRecipients = [testRecipientData[j][1]];
isSuccess = email.send();
Array.prototype.push.call(isSuccess ? successIds : failedIds, recipientData[i]["BULKMAILRECIPIENTID"]);
if (testRecipientData[j][0])
{
let mailLogId = util.getNewUUID();
db.insertData("MAIL_LOG", ["MAIL_LOGID","MAIL_RUN_ID","CONTACT_ID","STATUS","SENDER_EMAIL","RECIPIENT_EMAIL","MAILING_SUBJECT","DATE_SEND"], null, [mailLogId,mailrunId,testRecipientData[j][0],(isSuccess ?$KeywordRegistry.bulkMailRecipientStatus$sent(): $KeywordRegistry.bulkMailRecipientStatus$failed()),emailSender,testRecipientData[j][1],email.subject,vars.get("$sys.date")]);
this.storeEmlFile(pBulkMailId, mailrunId, mailLogId,email.getEML());
}
}
}
}
}
newWhere("MAIL_RUN.MAIL_RUNID",mailrunId)
.updateData(true,"MAIL_RUN",["STATUS","DATE_RUN_FINISHED"],null,[$KeywordRegistry.bulkMailStatus$sent(),vars.get("$sys.date")]);
}
return {
sucessful : successIds.length,
failed : failedIds.length
};
}
/**
* Opens a context to select a bulk mail 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
*/
BulkMailUtils.openAddRecipientView = function (pContext, pContactIds, pFilter)
{
if (!Utils.isString(pContactIds))
pContactIds = JSON.stringify(pContactIds);
if (!Utils.isString(pFilter))
pFilter = JSON.stringify(pFilter);
neon.openContext("BulkMailAddRecipients", "BulkMailAddRecipientsEdit_view", null, neon.OPERATINGSTATE_VIEW, {
"ObjectType_param": pContext,
"ContactIds_param": pContactIds,
"ContactFilter_param": pFilter
});
}
/**
* Deletes all bulk mail recipients that have a commrestriction for emails.<br>
*
* @param {String} pBulkMailId <p>
* The mail id.<br>
*/
BulkMailUtils.removeCommRestrictionRecipients = function (pBulkMailId)
{
var recipientIds = newSelect("BULKMAILRECIPIENTID")
.from("BULKMAILRECIPIENT")
.join("CONTACT", "BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
.where("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
.and(new CommunicationSettingsCondition()
.emails("BULKMAILRECIPIENT.EMAIL_ADDRESS")
.rejected()
.existSettings()
.buildCondition())
.arrayColumn();
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds, SqlBuilder.IN())
.deleteData();
}
/**
* Adds recipients to a bulkmail.<br>
*
* @param {String} pBulkMailId <p>
* Bulk mail id.<br>
* @param {String[]} pContactIds <p>
* Contact ids of the recipients.<br>
*/
BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
{
if (pContactIds.length > 0)
{
var contactData = newSelect(["CONTACTID", "(" + CommUtil.getStandardSubSqlMail(newWhere("COMMUNICATION.CONTACT_ID = CONTACTID")) + ")"])
.from("CONTACT")
.where("CONTACT.CONTACTID", pContactIds, SqlBuilder.IN())
.table();
var sqlBuilder = new SqlBuilder();
var inserts = contactData.map(function([contactId, standardMail])
{
return sqlBuilder.buildInsertStatement({
"BULKMAIL_ID": pBulkMailId,
"CONTACT_ID": contactId,
"STATUS": $KeywordRegistry.bulkMailRecipientStatus$pending(),
"EMAIL_ADDRESS": standardMail
}, "BULKMAILRECIPIENT", "BULKMAILRECIPIENTID");
});
db.inserts(inserts);
}
}
/**
* Loads the document template of a bulk mail. If the bulk mail
* itself has a template, it is preferred over the documentTemplate-id.
*
* @param {String} pBulkMailId <p>
* The id of the bulk mail.<br>
* @param {String} pDocumentTemplateId <p>
* The id of the document template.<br>
* @param {Boolean} pResolveSubtemplates=true (optional) <p>
* If true subtemplates are resolved (if the type is html)
* @param {Boolean} pUseTemplateAttachments=false <p>
* If true the attachments from the document template is always used
* @param {FileUpload} pUpload (optional) <p>
* The upload value if a custom template is used.<br>
* @return {DocumentTemplate} <p>
* The document template, null if no content was found.<br>
*/
BulkMailUtils.getBulkMailTemplate = function (pBulkMailId, pDocumentTemplateId, pResolveSubtemplates, pUseTemplateAttachments, pUpload)
{
if (pUpload && pUpload.isFilled() && BulkMailUtils.isValidMimeType(pUpload.mimeType))
return DocumentTemplate.fromUpload(pUpload);
var bulkTemplate = DocumentTemplate.loadTemplate(pBulkMailId, "BULKMAIL", pResolveSubtemplates);
var documentTemplate = DocumentTemplate.loadTemplate(pDocumentTemplateId, undefined, pResolveSubtemplates);
if (!bulkTemplate.content)
{
return documentTemplate;
}
else
{
if (pUseTemplateAttachments)
bulkTemplate.setAttachments(documentTemplate.getAttachments());
return bulkTemplate;
}
}
/**
* Checks if a contact is a recipient of a bulk mail.<br>
*
* @param {String} pBulkMailId <p>
* The id of the bulk mail.<br>
* @param {String} pContactId <p>
* The contact id.<br>
* @param {String} pRecipientId <p>
* The contact id of the contact where,<br>
* the bulk mail shall sent to.<br>
* @return {boolean} <p>
* True, if the contact is a recipient.<br>
*/
BulkMailUtils.isRecipient = function (pBulkMailId, pContactId, pRecipientId)
{
return newSelect("count(*)")
.from("BULKMAILRECIPIENT")
.where("BULKMAILRECIPIENT.CONTACT_ID", pContactId)
.and("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
.andIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", pRecipientId, SqlBuilder.NOT_EQUAL())
.cell() != "0"; //TODO: is there a way exists could be used?
}
/**
* Opens the BulkMail context in new mode.<br>
*
* @param {String[]} pRecipients (optional) <p>
* Recipients that should be added after creation.<br>
*/
BulkMailUtils.newBulkMail = function (pRecipients)
{
var params = {
"PresetRecipients_param" : JSON.stringify(pRecipients)
};
neon.openContext("BulkMail", "BulkMailEdit_view", null, neon.OPERATINGSTATE_NEW, params);
}
/**
* 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} pBulkMailId id of the bulk mail the contacts should be added to
* @param {String[]} pContactIds contacts to filter
* @return {String[]} contacts that can be added as recipients
*/
BulkMailUtils.filterNewRecipients = function (pBulkMailId, pContactIds)
{
return newSelect("CONTACTID")
.from("CONTACT")
.whereIfSet("CONTACT.CONTACTID", pContactIds, SqlBuilder.IN())
// only add contacts that aren't already recipients
.and(null, newSelect("BULKMAILRECIPIENTID")
.from("BULKMAILRECIPIENT")
.where("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
.and("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
, SqlBuilder.NOT_EXISTS())
// check if there's a commrestriction
.and(new CommunicationSettingsCondition()
.emails(CommUtil.getStandardSubSqlMail())
.rejected()
.existNoSettings()
.buildCondition())
.arrayColumn();
}
/**
* Opens the given bulk mail.
*
* @param {String} pBulkMailId <p>
* The id of the bulk mail.<br>
*/
BulkMailUtils.openBulkMail = function (pBulkMailId)
{
neon.openContext("BulkMail", "BulkMailMain_view", [pBulkMailId], neon.OPERATINGSTATE_VIEW, null);
}
/**
* Checks is the given mime type can be used for a bulk mail.<br>
*
* @param {String} pMimeType <p>
* The mime type.<br>
* @return {Boolean} <p>
* Whether the type is usable or not.<br>
*/
BulkMailUtils.isValidMimeType = function (pMimeType)
{
var templateType = DocumentTemplate.types.fromMimeType(pMimeType);
return BulkMailUtils.isValidTemplateType(templateType)
}
/**
* Checks is the given template type can be used for a bulk mail.<br>
*
* @param {String} pTemplateType <p>
* Template type.<br>
* @return {Boolean} <p>
* Whether the type is usable or not.<br>
*/
BulkMailUtils.isValidTemplateType = function (pTemplateType)
{
switch (pTemplateType)
{
case DocumentTemplate.types.EML:
case DocumentTemplate.types.HTML:
case DocumentTemplate.types.TXT:
return true;
default:
return false;
}
}
/**
* Checks whether the given status id matches,<br>
* to the status of a bulk mail which is sent or<br>
* not.
*
* @param {String} pStatus <p>
* The key id of the current status.<br>
* @return {Boolean} <p>
* True if the status is "sent" or "sending".<br>
*/
BulkMailUtils.isStatusSendingOrSent = function (pStatus)
{
return pStatus == $KeywordRegistry.bulkMailStatus$sent() || pStatus == $KeywordRegistry.bulkMailStatus$beingSent()
}
/**
* Opens BulkMail context in new mode, with the given bulk mail id.<br>
*
* @param {String} pBulkMailId <p>
* The id of the bulk mail.<br>
*/
BulkMailUtils.copy = function(pBulkMailId)
{
var params = {
"CopyBulkMailId_param" : pBulkMailId
};
neon.openContext("BulkMail", null, null, neon.OPERATINGSTATE_NEW, params);
}
/*
*Stores the Eml file for a bulkmailrecipient in 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>
**/
BulkMailUtils.storeEmlFile = function(pBulkMailId,pMailRunId, pMailLogId,pFile)
{
var locationoption = project.getPreferenceValue("bulkmail.fileStorage","/bulkMailFiles/");
var path = vars.get("$sys.serverdata")+locationoption +pBulkMailId+"/"+pMailRunId+"/";
var filename = pMailLogId+".eml"
var fullPath = path + filename;
fileIO.storeData(fullPath, pFile, util.DATA_BINARY, false);
}
/*
*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.getPreferenceValue("bulkmail.fileStorage","/bulkMailFiles/");
var path = vars.get("$sys.serverdata")+locationoption +pBulkMailId+"/"+pMailRunId+"/";
var filename = pMailLogId+".eml"
var fullPath = path + filename;
return (fileIO.getData(fullPath,util.DATA_BINARY));
}
/*
*Gets the redirecturl for a link in a bulkmail
*
* @param {String} pLinkId <p>
* The id of the link.<br>
*
* @return {String} <p>
* The url<br>
**/
BulkMailUtils.getRedirectLink = function(pLinkId)
{
if (pLinkId)
{
return newSelect("WEBLINK.URL").from("WEBLINK").where("WEBLINK.WEBLINKID", pLinkId).cell();
}
return null;
}
/*
*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)
{
return;
}
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")
});
newWhere("MAIL_LOG.MAIL_LOGID", pMailLogId)
.and("MAIL_LOG.OPENER_LINK_CLICK_ID is null")
.updateFields({"OPENER_LINK_CLICK_ID": linkClickId});
}
/*@TODO: Abändern nachdem geklärt ist wie wir IP-Adresse erhalten. Momentan bekommen wir nur Loadbalancer Ip.
*
**/
BulkMailUtils.getIpAddressFromHeader = function(pHttpHeader)
{
return pHttpHeader["X-forwarded-for"].split(",")[0];
}
BulkMailUtils.startBulkmailWorkFlow = function(pMailLogId, pLinkId)
{
if (!pMailLogId || !pLinkId)
{
return
}
var [actionType, workflowKey, signalName] = newSelect(["ACTION_TYPE", "WORKFLOWPROCESSDEFINITION_KEY", "WORKFLOWSIGNAL_NAME"])
.from("WEBLINK")
.where("WEBLINK.WEBLINKID", pLinkId)
.arrayRow();
var variables = {
"mailLogId": pMailLogId,
"linkId": pLinkId
};
if (actionType == $KeywordRegistry.weblinkActionType$startWorkflow() && workflowKey)
{
workflow.startProcessByKey(workflowKey, variables);
}
else if (actionType == $KeywordRegistry.weblinkActionType$sendWorkflowSignal() && signalName)
{
workflow.signalEventReceived(signalName, variables);
}
}
function SerialLetterUtils () {}
/**
* 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);
neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_VIEW, {
"ObjectType_param": pContext,
"ContactIds_param": pContactIds,
"ContactFilter_param": pFilter
});
}
/**
* 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 user = EmployeeUtils.getCurrentUserId();
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()
.postalAddress("LETTERRECIPIENT.ADDRESS_ID")
.rejected()
.existNoSettings()
.buildCondition());
if (pRecipientIds && pRecipientIds.length > 0)
contactIdsSelect.and("LETTERRECIPIENT.LETTERRECIPIENTID", pRecipientIds, SqlBuilder.IN());
var contactIds = contactIdsSelect.table();
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)
{
return newSelect("count(*)")
.from("LETTERRECIPIENT")
.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)
{
neon.openContext("SerialLetter", "SerialLetterMain_view", [pSerialLetterId], neon.OPERATINGSTATE_VIEW, null);
}
/**
* 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;
}
/**
* 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 = {
"ContactIds_param" : pContactIds
};
neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_VIEW, params);
}
/**
* 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}
neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_VIEW, params);
}
/**
* 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()
.postalAddress("CONTACT.ADDRESS_ID")
.rejected()
.existNoSettings()
.buildCondition())
.arrayColumn();
}