Skip to content
Snippets Groups Projects
process.js 58.3 KiB
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);
}

/*
 *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 + "/";
    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>
 * @param {String} pBaseUrl          <p>
 *                                      The base url for relative links<br>                                      
 * @param {String} pMailLogId        <p>
 *                                      The mail log id for contact id replacement<br>                                          
BulkMailUtils.getRedirectLink = function(pLinkId, pBaseUrl, pMailLogId)
        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();
        
        link = StringUtils.replaceAll(link, "{@contactid@}", contactId);
        if(link[0] == "/")
        {
            link = pBaseUrl + link;
        }
        return link;
    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>                                                 
 **/

Sebastian Listl's avatar
Sebastian Listl committed
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")
        });
        .and("MAIL_LOG.OPENER_LINK_CLICK_ID is null")
        .updateFields({"OPENER_LINK_CLICK_ID": linkClickId});
/* Gets the Ip Address out of the http header
 * 
 * @param {Object} pHttpHeader the http header object
 * @return {String} the original ip address of the recipient
BulkMailUtils.getIpAddressFromHeader = function(pHttpHeader)
{
    return pHttpHeader["X-forwarded-for"].split(",")[0];
BulkMailUtils.startBulkmailWorkFlow = function(pMailLogId, pLinkId)
{
    if (!pMailLogId || !pLinkId) 
    {
    var [linkActionType, workflowKey, signalName] = newSelect(["ACTION_TYPE", "WORKFLOWPROCESSDEFINITION_KEY", "WORKFLOWSIGNAL_NAME"])
Sebastian Listl's avatar
Sebastian Listl committed
        .from("WEBLINK")
        .where("WEBLINK.WEBLINKID", pLinkId)
        .arrayRow();
    
    var contactId = newSelect("CONTACT_ID")
        .from("MAIL_LOG")
        .where("MAIL_LOG.MAIL_LOGID", pMailLogId)
        .cell();
    
    var processVariables = {
Sebastian Listl's avatar
Sebastian Listl committed
        "mailLogId": pMailLogId,
        "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);
/* Checks if the Content is just the default empty html
 * 
 * @param {String} pContent content
 *
 * @return {Boolean} true if content is just empty html tag
 **/

BulkMailUtils.isNotEmptyHtml = function(pContent)
{
    return pContent !== "<html></html>";
}

Johannes Hörmann's avatar
Johannes Hörmann committed
function SerialLetterUtils () {}

/**
 * Adds recipients to a serial letter.<br>
Johannes Hörmann's avatar
Johannes Hörmann committed
 * 
 * @param {String} pSerialLetterId      <p>
 *                                      The id of the serial letter.<br>
 * @param {String[]} pContactIds        <p>
 *                                      Contact ids of the recipients.<br>
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
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>
Johannes Hörmann's avatar
Johannes Hörmann committed
 * 
 * @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
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
SerialLetterUtils.openAddRecipientView = function (pContext, pContactIds, pFilter)
Johannes Hörmann's avatar
Johannes Hörmann committed
{
    if (!Utils.isString(pContactIds))
        pContactIds = JSON.stringify(pContactIds);
    if (!Utils.isString(pFilter))
        pFilter = JSON.stringify(pFilter);
    
Pascal Neub's avatar
Pascal Neub committed
    var recipe = neonFilter.createEntityRecordsRecipeBuilder().parameters({
        "ObjectType_param": pContext,
        "ContactIds_param": pContactIds,
        "ContactFilter_param": pFilter
Pascal Neub's avatar
Pascal Neub committed
    }).toString();
    neon.openContextWithRecipe("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", recipe, neon.OPERATINGSTATE_VIEW);
 * Executes a server process that builds a serial letter.<br>
Johannes Hörmann's avatar
Johannes Hörmann committed
 * 
 * @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>
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
S.Listl's avatar
S.Listl committed
SerialLetterUtils.buildSerialLetterOnServer = function (pSerialLetterId, pRecipientIds)
Johannes Hörmann's avatar
Johannes Hörmann committed
{
S.Listl's avatar
S.Listl committed
    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>
S.Listl's avatar
S.Listl committed
 * 
 * @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>
S.Listl's avatar
S.Listl committed
 */
SerialLetterUtils.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
{
    var [templateId, title] = newSelect("DOCUMENTTEMPLATE_ID, TITLE")
                                .from("SERIALLETTER")
                                .where("SERIALLETTER.SERIALLETTERID", pSerialLetterId)
                                .arrayRow(true);
S.Listl's avatar
S.Listl committed

    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());
S.Listl's avatar
S.Listl committed

    if (pRecipientIds && pRecipientIds.length > 0)
S.Listl's avatar
S.Listl committed
        contactIdsSelect.and("LETTERRECIPIENT.LETTERRECIPIENTID", pRecipientIds, SqlBuilder.IN());
S.Listl's avatar
S.Listl committed

    var contactIds = contactIdsSelect.table();
    
    if(template != null)
    {
        return {
            content : template.getSerialLetterByContactIds(contactIds),
            filename : template.filename,
            title : title
        };
    }
    else
    {
 * Checks if a contact is a recipient of a serial letter.<br>
Johannes Hörmann's avatar
Johannes Hörmann committed
 * 
 * @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>
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
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>
 */
Johannes Hörmann's avatar
Johannes Hörmann committed
SerialLetterUtils.openSerialLetter = function (pSerialLetterId)
{
Pascal Neub's avatar
Pascal Neub committed
    var recipe = neonFilter.createEntityRecordsRecipeBuilder().uidsIncludelist([pSerialLetterId]).toString();
    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>
Johannes Hörmann's avatar
Johannes Hörmann committed
 * 
 * @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>
Johannes Hörmann's avatar
Johannes Hörmann committed
 */
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 = {
Pascal Neub's avatar
Pascal Neub committed
        "ContactIds_param": pContactIds
Pascal Neub's avatar
Pascal Neub committed
    var recipe = neonFilter.createEntityRecordsRecipeBuilder().parameters(params).toString();
    neon.openContextWithRecipe("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", recipe, neon.OPERATINGSTATE_VIEW);
}

/**
 * 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 = {
Pascal Neub's avatar
Pascal Neub committed
        "ContactIds_param": pCondition,
        "comingFrom_param": pSourceTableName
    };
    var recipe = neonFilter.createEntityRecordsRecipeBuilder().parameters(params).toString();
    neon.openContextWithRecipe("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", recipe, neon.OPERATINGSTATE_VIEW);
}

/**
 * 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()
                    .rejected()
                    .existNoSettings()
                    .buildCondition())