From 6fc514923d9c76859bbbc6eb0593a23ef1d4ab36 Mon Sep 17 00:00:00 2001
From: "S.Listl" <S.Listl@SLISTL.aditosoftware.local>
Date: Thu, 18 Jul 2019 10:03:50 +0200
Subject: [PATCH] DocumentTemplate documentation

---
 process/Bulkmail_lib/process.js               | 439 +++++++++---------
 .../CustomPlaceholder_lib.aod                 |  19 +-
 process/DocumentTemplate_lib/process.js       |  25 +-
 3 files changed, 264 insertions(+), 219 deletions(-)

diff --git a/process/Bulkmail_lib/process.js b/process/Bulkmail_lib/process.js
index 3d6b154a63..3731ae4dc5 100644
--- a/process/Bulkmail_lib/process.js
+++ b/process/Bulkmail_lib/process.js
@@ -1,209 +1,230 @@
-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("Email_lib");
-import("system.process");
-import("system.notification");
-
-/**
- * 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 {String} [pUser=currentUser] User that will get the notification, if null (not undefined!), no notification
- *                                      will be created.
- */
-BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pUser)
-{
-    if (pUser === undefined)
-        pUser = EmployeeUtils.getCurrentUserId();
-    process.execute("sendBulkMail_serverProcess", 
-        {
-            bulkMailId : pBulkMailId,
-            user : pUser || ""
-        }
-    );
-}
-
-/**
- * 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 
- * 
- * @return {Object} count of sucessful and failed mails 
- */
-BulkMailUtils.sendBulkMail = function (pBulkMailId)
-{
-    //TODO: Mailbridge, Werbesperre beachten
-    
-    var [templateId, subject, emailSender] = db.array(db.ROW, SqlCondition.begin()
-        .andPrepare("BULKMAIL.BULKMAILID", pBulkMailId)
-        .buildSql("select DOCUMENTTEMPLATE_ID, SUBJECT, SENDER from BULKMAIL", "1=2")
-    );
-    var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId);
-    
-    var recipientData = db.table(SqlCondition.begin()
-        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
-        .andPrepare("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), "# != ?")
-        .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))
-        .buildSql("select BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, '' from BULKMAILRECIPIENT \n\
-            join CONTACT on BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID", "1=2")
-    );
-    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);
-    
-    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]]; //TODO: email address missing
-            email.sender = emailSender;
-            email.subject = subjects[contactId];
-
-            isSuccess = email.send();
-        }
-        if (isSuccess)
-            successIds.push(recipientData[i][0]); //set the recipient status to 'sent'
-        else
-            failedIds.push(recipientData[i][0]); //set the recipient status to 'failed'
-    }
-    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$sent(), sentDate], 
-        SqlCondition.begin()
-            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds)
-            .build("1=2")
-    );
-    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$failed(), sentDate], 
-        SqlCondition.begin()
-            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds)
-            .build("1=2")
-    );
-        
-    db.updateData("BULKMAIL", ["STATUS"], null, [$KeywordRegistry.bulkMailStatus$sent()], 
-        SqlCondition.equals("BULKMAIL.BULKMAILID", pBulkMailId, "1=2"));
-        
-    return {
-        sucessful : successIds.length,
-        failed : failedIds.length
-    };
-}
-
-BulkMailUtils.openAddRecipientView = function (pContactIds)
-{
-    var params = {
-        "ContactIds_param" : pContactIds
-    };
-    neon.openContext("BulkMailAddRecipients", "BulkMailAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
-}
-
-BulkMailUtils.removeCommRestrictionRecipients = function (pBulkMailId)
-{
-    var recipientIds = db.array(db.COLUMN, SqlBuilder.begin()
-        .select("BULKMAILRECIPIENTID")
-        .from("BULKMAILRECIPIENT")
-        .join("CONTACT", SqlCondition.begin()
-            .and("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
-            .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail())))
-        .where(SqlCondition.begin()
-            .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId))
-        .build());
-
-    if (recipientIds.length)
-    {
-        db.deleteData("BULKMAILRECIPIENT", SqlCondition.begin()
-            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds)
-            .build("1=2"));
-    }
-}
-
-BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
-{
-    var columns = [
-        "BULKMAILRECIPIENTID",
-        "BULKMAIL_ID",
-        "CONTACT_ID",
-        "STATUS"
-    ];
-    var inserts = [];
-    for (let i = 0, l = pContactIds.length; i < l; i++)
-    {
-        inserts.push(["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), pBulkMailId, pContactIds[i], $KeywordRegistry.bulkMailRecipientStatus$pending()]]);
-    }
-    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
- * 
- * @return {DocumentTemplate} the document template, null if no content was found.
- */
-BulkMailUtils.getBulkMailTemplate = function (pBulkMailId, pDocumentTemplateId)
-{
-    var template = DocumentTemplate.loadTemplate(pBulkMailId, "BULKMAIL");
-    if (template === null)
-        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
-    return template;
-}
-
-function SerialLetterUtils () {}
-
-SerialLetterUtils.addRecipients = function (pBulkMailId, 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(), pBulkMailId, pContactIds[i]]]);
-    }
-    db.inserts(inserts);
-}
-
-
-SerialLetterUtils.openAddRecipientView = function (pContactIds)
-{
-    var params = {
-        "ContactIds_param" : pContactIds
-    };
-    neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
-}
-
-SerialLetterUtils.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
-{
-    process.execute("buildSerialLetter_serverProcess", {
-        "serialLetterId" : pSerialLetterId,
-        "recipientIds" : JSON.stringify(pRecipientIds)
-    });
-}
-
-SerialLetterUtils.makeDownloadNotification = function (pTitle, pBinaryId, pUser)
-{
-    notification.addNotification(pContentId, pLinkInfo, pImageInfo, pOriginatorName, pType, pForcedPriority, pDaysToLive, pState, pUser, pCaption, pDescription)
-}
\ No newline at end of file
+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("Email_lib");
+import("system.process");
+import("system.notification");
+
+/**
+ * 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 {String} [pUser=currentUser] User that will get the notification, if null (not undefined!), no notification
+ *                                      will be created.
+ */
+BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pUser)
+{
+    if (pUser === undefined)
+        pUser = EmployeeUtils.getCurrentUserId();
+    process.execute("sendBulkMail_serverProcess", 
+        {
+            bulkMailId : pBulkMailId,
+            user : pUser || ""
+        }
+    );
+}
+
+/**
+ * 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 
+ * 
+ * @return {Object} count of sucessful and failed mails 
+ */
+BulkMailUtils.sendBulkMail = function (pBulkMailId)
+{
+    //TODO: Mailbridge, Werbesperre beachten
+    
+    var [templateId, subject, emailSender] = db.array(db.ROW, SqlCondition.begin()
+        .andPrepare("BULKMAIL.BULKMAILID", pBulkMailId)
+        .buildSql("select DOCUMENTTEMPLATE_ID, SUBJECT, SENDER from BULKMAIL", "1=2")
+    );
+    var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId);
+    
+    var recipientData = db.table(SqlCondition.begin()
+        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
+        .andPrepare("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), "# != ?")
+        .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))
+        .buildSql("select BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, '' from BULKMAILRECIPIENT \n\
+            join CONTACT on BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID", "1=2")
+    );
+    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);
+    
+    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]]; //TODO: email address missing
+            email.sender = emailSender;
+            email.subject = subjects[contactId];
+
+            isSuccess = email.send();
+        }
+        if (isSuccess)
+            successIds.push(recipientData[i][0]); //set the recipient status to 'sent'
+        else
+            failedIds.push(recipientData[i][0]); //set the recipient status to 'failed'
+    }
+    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$sent(), sentDate], 
+        SqlCondition.begin()
+            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds)
+            .build("1=2")
+    );
+    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$failed(), sentDate], 
+        SqlCondition.begin()
+            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds)
+            .build("1=2")
+    );
+        
+    db.updateData("BULKMAIL", ["STATUS"], null, [$KeywordRegistry.bulkMailStatus$sent()], 
+        SqlCondition.equals("BULKMAIL.BULKMAILID", pBulkMailId, "1=2"));
+        
+    return {
+        sucessful : successIds.length,
+        failed : failedIds.length
+    };
+}
+
+
+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 = db.array(db.COLUMN, SqlBuilder.begin()
+        .select("BULKMAILRECIPIENTID")
+        .from("BULKMAILRECIPIENT")
+        .join("CONTACT", SqlCondition.begin()
+            .and("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
+            .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail())))
+        .where(SqlCondition.begin()
+            .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId))
+        .build());
+
+    if (recipientIds.length)
+    {
+        db.deleteData("BULKMAILRECIPIENT", SqlCondition.begin()
+            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds)
+            .build("1=2"));
+    }
+}
+
+/**
+ * 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"
+    ];
+    var inserts = [];
+    for (let i = 0, l = pContactIds.length; i < l; i++)
+    {
+        inserts.push(["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), pBulkMailId, pContactIds[i], $KeywordRegistry.bulkMailRecipientStatus$pending()]]);
+    }
+    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
+ * 
+ * @return {DocumentTemplate} the document template, null if no content was found.
+ */
+BulkMailUtils.getBulkMailTemplate = function (pBulkMailId, pDocumentTemplateId)
+{
+    var template = DocumentTemplate.loadTemplate(pBulkMailId, "BULKMAIL");
+    if (template === null)
+        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
+    return template;
+}
+
+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);
+}
+
+
+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.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
+{
+    process.execute("buildSerialLetter_serverProcess", {
+        "serialLetterId" : pSerialLetterId,
+        "recipientIds" : JSON.stringify(pRecipientIds)
+    });
+}
+
diff --git a/process/CustomPlaceholder_lib/CustomPlaceholder_lib.aod b/process/CustomPlaceholder_lib/CustomPlaceholder_lib.aod
index 6b446aa3df..8e915687a2 100644
--- a/process/CustomPlaceholder_lib/CustomPlaceholder_lib.aod
+++ b/process/CustomPlaceholder_lib/CustomPlaceholder_lib.aod
@@ -1,9 +1,10 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1">
-  <name>CustomPlaceholder_lib</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <process>%aditoprj%/process/CustomPlaceholder_lib/process.js</process>
-  <variants>
-    <element>LIBRARY</element>
-  </variants>
-</process>
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1">
+  <name>CustomPlaceholder_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/CustomPlaceholder_lib/process.js</process>
+  <alias>Data_alias</alias>
+  <variants>
+    <element>LIBRARY</element>
+  </variants>
+</process>
diff --git a/process/DocumentTemplate_lib/process.js b/process/DocumentTemplate_lib/process.js
index adc2d48507..8cfb39ec4c 100644
--- a/process/DocumentTemplate_lib/process.js
+++ b/process/DocumentTemplate_lib/process.js
@@ -184,7 +184,30 @@ DocumentTemplate.prototype.getReplacedContentByContactIds = function (pContactId
  * only for ODT
  * 
  * @param {Array} pContactIds contact ids
- * @param {Array} pTableData 
+ * @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
  */
-- 
GitLab