Something went wrong on our end
process.js 17.60 KiB
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");
/**
* 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 id of the bulk mail
* @param {Array} [pTestRecipients] overwrite the recipients (e.g. for testing)
* @param {String} [pUser=currentUser] User that will get the notification, if null (not undefined!), no notification
* will be created.
*/
BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pTestRecipients, pUser)
{
if (pUser === undefined)
pUser = EmployeeUtils.getCurrentUserId();
process.executeAsync("sendBulkMail_serverProcess",
{
bulkMailId : pBulkMailId,
testRecipients : JSON.stringify(pTestRecipients),
user : pUser || ""
}
, false, pUser, process.THREADPRIORITY_NORM, process.TIMERTYPE_SERVER
);
}
/**
* 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 id of the bulk mail
* @param {Array} [pTestRecipients] overwrite the recipients (e.g. for testing)
*
* @return {Object} count of sucessful and failed mails
*/
BulkMailUtils.sendBulkMail = function (pBulkMailId, pTestRecipients)
{
var [templateId, subject, emailSender, createActivity, bulkMailName, useTemplateAttachments] =
newSelect("DOCUMENTTEMPLATE_ID, SUBJECT, SENDER, CREATEACTIVITIES, NAME, USE_TEMPLATE_ATTACHMENTS")
.from("BULKMAIL")
.where("BULKMAIL.BULKMAILID", pBulkMailId)
.arrayRow();
useTemplateAttachments = useTemplateAttachments == "1";
var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId, true, useTemplateAttachments);
var recipientData;
if (pTestRecipients)
{
recipientData = pTestRecipients.map(function (row)
{
return ["", row[0], row[1], "", ""];
});
}
else
{
recipientData = newSelect("BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, BULKMAILRECIPIENT.EMAIL_ADDRESS, PERSON_ID, ORGANISATION_ID")
.from("CONTACT")
.join("BULKMAILRECIPIENT", "BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
.where("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
.and("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), SqlBuilder.NOT_EQUAL())
.and(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))
.table();
}
var contactIds = recipientData.map(function (e) {return e[1];});
var successIds = [];
var failedIds = [];
var sentDate = vars.get("$sys.date");
var mails = template.getReplacedEmailsByContactIds(contactIds);
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]);
for (let i = 0, l = recipientData.length; i < l; i++)
{
let isSuccess = false;
let contactId = recipientData[i][1];
let email = mails[contactId];
if (email !== undefined && recipientData[i][2])
{
email.toRecipients = [recipientData[i][2]];
email.sender = emailSender;
email.subject = subjects[contactId];
isSuccess = email.send();
}
if (recipientData[i][0]) //set the recipient status to 'sent' or 'failed'
{
Array.prototype.push.call(isSuccess ? successIds : failedIds, recipientData[i][0]);
if (isSuccess && createActivity == "1")
{
let activityData = {
categoryKeywordId : $KeywordRegistry.activityCategory$mail(),
directionKeywordId : $KeywordRegistry.activityDirection$outgoing(),
subject : activitySubject,
content : email.body
};
let contactLink = [[ContactUtils.getContextByPersOrg(recipientData[i][3], recipientData[i][4]), recipientData[i][1]]];
ActivityUtils.insertNewActivity(activityData, bulkMailLink.concat(contactLink));
}
}
}
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds, SqlBuilder.IN())
.updateData(true, "BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$sent(), sentDate]);
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds, SqlBuilder.IN())
.updateData(true, "BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$failed(), sentDate]);
if (!pTestRecipients) //if its just a test run, don't set the status to sent
{
newWhere("BULKMAIL.BULKMAILID", pBulkMailId)
.updateData(true, "BULKMAIL", ["STATUS"], null, [$KeywordRegistry.bulkMailStatus$sent()]);
}
return {
sucessful : successIds.length,
failed : failedIds.length
};
}
/**
* opens a context to select a bulk mail to add recipients to
*
* @param {String[]} pContactIds recipients that should be added
*/
BulkMailUtils.openAddRecipientView = function (pContactIds)
{
var params = {
"ContactIds_param" : pContactIds
};
neon.openContext("BulkMailAddRecipients", "BulkMailAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
}
/**
* deletes all bulk mail recipients that have a commrestriction for emails
*
* @param {String} pBulkMailId
*/
BulkMailUtils.removeCommRestrictionRecipients = function (pBulkMailId)
{
var recipientIds = newSelect("BULKMAILRECIPIENTID")
.from("BULKMAILRECIPIENT")
.join("CONTACT", newWhere()
.and("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
.and(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail())))
.where("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
.arrayColumn();
newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds, SqlBuilder.IN())
.deleteData();
}
/**
* adds recipients to a bulkmail
*
* @param {String} pBulkMailId bulk mail id
* @param {String[]} pContactIds contact ids of the recipients
*/
BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
{
var columns = [
"BULKMAILRECIPIENTID",
"BULKMAIL_ID",
"CONTACT_ID",
"STATUS",
"EMAIL_ADDRESS"
];
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 inserts = contactData.map(function(pContact)
{
//TODO: get columntype for better performance outside loop
return ["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), pBulkMailId, pContact[0], $KeywordRegistry.bulkMailRecipientStatus$pending(), pContact[1]]];
});
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 bulkmail id
* @param {String} pDocumentTemplateId documentTemplate id
* @param {Boolean} [pResolveSubtemplates=true] if true subtemplates are resolved (if the type is html)
* @param {Boolean} [pUseTemplateAttachments=false] if true the attachments from the document template is always used
* @param {FileUpload} [pUpload] the upload value if a custom template is used
*
* @return {DocumentTemplate} the document template, null if no content was found.
*/
BulkMailUtils.getBulkMailTemplate = function (pBulkMailId, pDocumentTemplateId, pResolveSubtemplates, pUseTemplateAttachments, pUpload)
{
if (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
*
* @param {String} pBulkMailId bulkmail id
* @param {String} pContactId contact id
* @param {String} pRecipientId bulkmailrecipient id
* @return {boolean} true, if the contact is a recipient
*/
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
*
* @param {String[]} [pRecipients] recipients that should be added after creation
*/
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(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))
.arrayColumn();
}
/**
* opens the given bulk mail
*/
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
*
* @param {String} pMimeType mime type
* @return {Boolean} wheter the type is usable or not
*/
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
*
* @param {String} pTemplateType template type
* @return {Boolean} wheter the type is usable or not
*/
BulkMailUtils.isValidTemplateType = function (pTemplateType)
{
switch (pTemplateType)
{
case DocumentTemplate.types.EML:
case DocumentTemplate.types.HTML:
case DocumentTemplate.types.TXT:
return true;
default:
return false;
}
}
/**
* @param {String} pStatus the keyid of the current status
* @return {Boolean} true if the status is "sent" or "sending"
*/
BulkMailUtils.isStatusSendingOrSent = function (pStatus)
{
return pStatus == $KeywordRegistry.bulkMailStatus$sent() || pStatus == $KeywordRegistry.bulkMailStatus$beingSent()
}
BulkMailUtils.copy = function(pBulkMailId)
{
var params = {
"CopyBulkMailId_param" : pBulkMailId
};
neon.openContext("BulkMail", null, null, neon.OPERATINGSTATE_NEW, params);
}
function SerialLetterUtils () {}
/**
* adds recipients to a serial letter
*
* @param {String} pSerialLetterId serial letter id
* @param {String[]} pContactIds contact ids of the recipients
*/
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
*
* @param {String[]} pContactIds recipients that should be added
*/
SerialLetterUtils.openAddRecipientView = function (pContactIds)
{
var params = {
"ContactIds_param" : pContactIds
};
neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
}
/**
* executes a server process that builds a serial letter
*
* @param {String} pSerialLetterId serial letter id
* @param {String[]} [pRecipientIds] Letter recipient ids of that should be used.
* If omitted, all recipients of the letter will be used.
*/
SerialLetterUtils.buildSerialLetterOnServer = function (pSerialLetterId, pRecipientIds)
{
var user = EmployeeUtils.getCurrentUserId();
process.executeAsync("buildSerialLetter_serverProcess", {
"serialLetterId" : pSerialLetterId,
"recipientIds" : JSON.stringify(pRecipientIds),
"user" : user
}
, false, vars.get("$sys.user"), process.THREADPRIORITY_NORM, process.TIMERTYPE_SERVER);
}
/**
* executes a server process that builds a serial letter
*
* @param {String} pSerialLetterId serial letter id
* @param {String[]} [pRecipientIds] Letter recipient ids of that should be used.
* If omitted, all recipients of the letter will be used.
*/
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(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$letter(), true));
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
*
* @param {String} pSerialLetterId serial letter id
* @param {String} pContactId contact id
* @param {String} [pRecipientId] letter recipient id
* @return {boolean} true, if the contact is a recipient
*/
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?
}
SerialLetterUtils.openSerialLetter = function (pSerialLetterId)
{
neon.openContext("SerialLetter", "SerialLetterMain_view", [pSerialLetterId], neon.OPERATINGSTATE_VIEW, null);
}
/**
* Loads the document template of a serial letter. If the serial letter itself has a
* template, it is preferred over the documentTemplate-id.
*
* @param {String} pLetterId serial letter id
* @param {String} pDocumentTemplateId documentTemplate id
*
* @return {DocumentTemplate} the document template
*/
SerialLetterUtils.getSerialLetterTemplate = function (pLetterId, pDocumentTemplateId)
{
var template = DocumentTemplate.loadTemplate(pLetterId, "SERIALLETTER");
if (!template.type)
template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
return template;
}