From 4762a0247a30f56219cacb68bd039624450f83e4 Mon Sep 17 00:00:00 2001
From: Johannes Hoermann <j.hoermann@adito.de>
Date: Wed, 17 Jul 2019 15:01:52 +0200
Subject: [PATCH] Org report -> html to text

---
 process/Organisation_lib/process.js | 367 ++++++++++++++--------------
 1 file changed, 187 insertions(+), 180 deletions(-)

diff --git a/process/Organisation_lib/process.js b/process/Organisation_lib/process.js
index d510de69cb..d87c940623 100644
--- a/process/Organisation_lib/process.js
+++ b/process/Organisation_lib/process.js
@@ -1,181 +1,188 @@
-import("Util_lib");
-import("system.datetime");
-import("system.translate");
-import("system.db");
-import("Binary_lib");
-import("Report_lib");
-import("Sql_lib");
-import("Keyword_lib");
-import("Attribute_lib");
-import("PostalAddress_lib");
-import("Communication_lib");
-import("KeywordRegistry_basic");
-
-/**
- * a static Utility class for the Org context.
- * 
- * Do not create an instance of this!
- * @class
- */
-function OrgUtils() {}
-
-/**
- * returns the image for a organisation
- * 
- * @param {String} pOrgId the id of the organisation.
- * @param {String} pDefaultText the text, to use for default image generation.
- * @return {String} base64 coded String of the image. If none existed, the given String is used to create an image.
- */
-OrgUtils.getImage = function(pOrgId, pDefaultText)
-{
-    return ImageUtils.get("ORGANISATION", "IMAGE", pOrgId, pDefaultText);
-}
-
-/**
- * sets the image of a organisation
- * 
- * @param {String} pOrgId the id of the organisation.
- * @param {String} pImageDateBase64 base64 coded String of the image.
- * @return {Boolean} if image could be set
- */
-OrgUtils.setImage = function(pOrgId, pImageDateBase64)
-{
-    return ImageUtils.set("ORGANISATION", "IMAGE", pOrgId, pImageDateBase64, "OrgImage", "Image of the organisation");
-}
-
-/**
- * deletes the image of a organisation
- * 
- * @param {String} pOrgId the id of the organisation.
- * @return {Boolean} if image could be removed
- */
-OrgUtils.removeImage = function(pOrgId)
-{
-    return ImageUtils.remove("ORGANISATION", "IMAGE", pOrgId);
-}
-
-/**
- * opens the org-report
- * 
- * @param {String} pOrgId the id of the organization
- */
-OrgUtils.openOrgReport = function(pOrgId)
-{
-    var relationId = pOrgId;
-    
-    //org info
-    var info = db.cell(SqlCondition.begin()
-        .andPrepare("ORGANISATION.ORGANISATIONID", pOrgId)
-        .buildSql("select ORGANISATION.INFO from ORGANISATION"));
-    
-    //communication data of the organization
-    var commSql = "select MEDIUM_ID, ADDR from COMMUNICATION";
-    commSql = SqlCondition.begin()
-        .andPrepare("COMMUNICATION.CONTACT_ID", relationId)
-        .and("STANDARD = 1")
-        .buildSql(commSql);
-    var commData = db.table(commSql);
-    
-    //resolve keyword
-    commData.forEach(function (row)
-    {
-        row[0] = KeywordUtils.getViewValue($KeywordRegistry.communicationMedium(), row[0]);
-    });
-    commData = ReportData.begin(["KINDOFCOMM", "COMMVALUE"]).add(commData);
-    
-    //select people from the organization
-    
-    var persSql = "select SALUTATION, TITLE, FIRSTNAME, LASTNAME "
-        + ",CONTACTROLE as PERSFUNCITON, DEPARTMENT as PERSDEPARTMENT "
-        + ",(" + CommUtil.getStandardSubSqlMail() + ")"
-        + ",(" + CommUtil.getStandardSubSqlPhone() + ")"
-        + ",ORGANISATION_ID, CONTACTID "
-        + "from PERSON join CONTACT on PERSONID = PERSON_ID";
-    persSql = SqlCondition.begin()
-        .andPrepare("CONTACT.ORGANISATION_ID", pOrgId)
-        .and("CONTACT.STATUS = '" + $KeywordRegistry.contactStatus$active() + "'") //TODO: replace this with something that isn't a hard coded id
-        .buildSql(persSql, "", " order by PERSON.LASTNAME asc");
-    var persData = db.table(persSql);
-    
-    for (let i = 0; i < persData.length; i++)
-    {
-        _joinArrayVals(persData[i], 0, 4); //join the full name together
-        _joinArrayVals(persData[i], 3, 2, "\n"); //join communication together
-    }
-    persData = ReportData.begin(["PERSNAMECOMPLETE", "PERSFUNCTION", "PERSDEPARTMENT", "PERSCOMM", "ORGANISATION_ID", "CONTACT_ID"]).add(persData);
-
-    var histSql = "select ENTRYDATE, CATEGORY, FIRSTNAME, LASTNAME, INFO from ACTIVITY "
-        + " join ACTIVITYLINK on ACTIVITYLINK.ACTIVITY_ID = ACTIVITYID "
-        + " join CONTACT on ACTIVITYLINK.OBJECT_ROWID = CONTACTID"
-        + " left join PERSON on CONTACT.PERSON_ID = PERSONID";
-    histSql = SqlCondition.begin()
-        .andPrepare("CONTACT.ORGANISATION_ID", pOrgId)   //= all activities linked to the organization or an employee
-        .buildSql(histSql, "", "order by ENTRYDATE desc");
-    var histData = db.table(histSql);
-    
-    var dateFormat = translate.text("dd.MM.yyyy");
-    histData.forEach(function (row) 
-    {
-        row[0] = datetime.toDate(row[0], dateFormat);
-        row[1] = KeywordUtils.getViewValue($KeywordRegistry.activityCategory(), row[1]);
-        _joinArrayVals(row, 2, 2);
-    });
-    histData = ReportData.begin(["ENTRYDATE", "MEDIUM", "LOGIN", "INFO"]).add(histData);
-    
-    var attr = AttributeRelationUtils.getAllAttributes(pOrgId)
-        .map(function (row) {return row[1] ? row.join(": ") : row[0]})
-        .join("\n");
-    
-    //tasks
-    var taskSql = "select TASK.SUBJECT, TASK.DESCRIPTION, TASK.STATUS, FIRSTNAME, LASTNAME from TASK"
-        + " join CONTACT on EDITOR_CONTACT_ID = CONTACTID"
-        + " left join PERSON on CONTACT.PERSON_ID = PERSONID";
-    taskSql = SqlCondition.begin()
-        .andPrepare("CONTACT.ORGANISATION_ID", pOrgId)
-        .buildSql(taskSql);
-    var taskData = db.table(taskSql);
-    
-    taskData.forEach(function (row) 
-    {
-        row[2] = KeywordUtils.getViewValue($KeywordRegistry.taskStatus(), row[2]);
-        _joinArrayVals(row, 3, 2); //join FIRSTNAME and LASTNAME together
-    });
-    taskData = ReportData.begin(["SUBJECT", "INFOTEXT", "STATUS", "RESPONSIBLE"]).add(taskData);
-    
-    var params = {
-        "ORGAddr" : AddressUtils.getAddress(relationId).toString(), //TODO: use new address logic when available
-        "ORGAttr" : attr,
-        "INFO" : info
-    };
-    
-    var orgReport = new Report("Organisation_report", params);
-    
-    //add subreport data
-    orgReport.addSubReportData("subdataComm", commData);
-    orgReport.addSubReportData("subdataPers", persData);
-    orgReport.addSubReportData("subdataHist", histData);
-    orgReport.addSubReportData("subdataTask", taskData);
-    
-    //add logo
-    //TODO: use an function to get the image when available
-    var imgData = [
-        "meineFirma | Konrad-Zuse-Straße 4  |  DE 84144 Geisenhausen",
-        "base64:iVBORw0KGgoAAAANSUhEUgAAAM4AAABRCAYAAACaL5lSAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDA4QzAyM0IwREIwMTFFNEFGMDREM0VEMjExRjlBRTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDA4QzAyM0MwREIwMTFFNEFGMDREM0VEMjExRjlBRTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMDhDMDIzOTBEQjAxMUU0QUYwNEQzRUQyMTFGOUFFMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMDhDMDIzQTBEQjAxMUU0QUYwNEQzRUQyMTFGOUFFMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhF3nYoAAAlvSURBVHja7J1fjBXV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"
-    ];
-    params["myAddr"] = imgData[0];
-    orgReport.addImage("myLogo", imgData[1]);
-    
-    orgReport.openReport();
-    
-    /*
-     * merges multiple columns in an two-dimensional array into one
-     */
-    function _joinArrayVals (pArr, pIndex, pHowMany, pJoinSeparator)
-    {
-        if (pJoinSeparator == undefined)
-            pJoinSeparator = " ";
-        pArr.splice(pIndex, pHowMany, ArrayUtils.joinNonEmptyFields(
-            pArr.slice(pIndex, pIndex + pHowMany), pJoinSeparator)
-        );
-    }
+import("Util_lib");
+import("system.datetime");
+import("system.translate");
+import("system.db");
+import("system.text");
+import("Binary_lib");
+import("Report_lib");
+import("Sql_lib");
+import("Keyword_lib");
+import("Attribute_lib");
+import("PostalAddress_lib");
+import("Communication_lib");
+import("KeywordRegistry_basic");
+
+/**
+ * a static Utility class for the Org context.
+ * 
+ * Do not create an instance of this!
+ * @class
+ */
+function OrgUtils() {}
+
+/**
+ * returns the image for a organisation
+ * 
+ * @param {String} pOrgId the id of the organisation.
+ * @param {String} pDefaultText the text, to use for default image generation.
+ * @return {String} base64 coded String of the image. If none existed, the given String is used to create an image.
+ */
+OrgUtils.getImage = function(pOrgId, pDefaultText)
+{
+    return ImageUtils.get("ORGANISATION", "IMAGE", pOrgId, pDefaultText);
+}
+
+/**
+ * sets the image of a organisation
+ * 
+ * @param {String} pOrgId the id of the organisation.
+ * @param {String} pImageDateBase64 base64 coded String of the image.
+ * @return {Boolean} if image could be set
+ */
+OrgUtils.setImage = function(pOrgId, pImageDateBase64)
+{
+    return ImageUtils.set("ORGANISATION", "IMAGE", pOrgId, pImageDateBase64, "OrgImage", "Image of the organisation");
+}
+
+/**
+ * deletes the image of a organisation
+ * 
+ * @param {String} pOrgId the id of the organisation.
+ * @return {Boolean} if image could be removed
+ */
+OrgUtils.removeImage = function(pOrgId)
+{
+    return ImageUtils.remove("ORGANISATION", "IMAGE", pOrgId);
+}
+
+/**
+ * opens the org-report
+ * 
+ * @param {String} pOrgId the id of the organization
+ */
+OrgUtils.openOrgReport = function(pOrgId)
+{
+    var relationId = pOrgId;
+    
+    //org info
+    var info = db.cell(SqlCondition.begin()
+        .andPrepare("ORGANISATION.ORGANISATIONID", pOrgId)
+        .buildSql("select ORGANISATION.INFO from ORGANISATION"));
+    
+    //communication data of the organization
+    var commSql = "select MEDIUM_ID, ADDR from COMMUNICATION";
+    commSql = SqlCondition.begin()
+        .andPrepare("COMMUNICATION.CONTACT_ID", relationId)
+        .and("STANDARD = 1")
+        .buildSql(commSql);
+    var commData = db.table(commSql);
+    
+    //resolve keyword
+    commData.forEach(function (row)
+    {
+        row[0] = KeywordUtils.getViewValue($KeywordRegistry.communicationMedium(), row[0]);
+    });
+    commData = ReportData.begin(["KINDOFCOMM", "COMMVALUE"]).add(commData);
+    
+    //select people from the organization
+    
+    var persSql = "select SALUTATION, TITLE, FIRSTNAME, LASTNAME "
+        + ",CONTACTROLE as PERSFUNCITON, DEPARTMENT as PERSDEPARTMENT "
+        + ",(" + CommUtil.getStandardSubSqlMail() + ")"
+        + ",(" + CommUtil.getStandardSubSqlPhone() + ")"
+        + ",ORGANISATION_ID, CONTACTID "
+        + "from PERSON join CONTACT on PERSONID = PERSON_ID";
+    persSql = SqlCondition.begin()
+        .andPrepare("CONTACT.ORGANISATION_ID", pOrgId)
+        .and("CONTACT.STATUS = '" + $KeywordRegistry.contactStatus$active() + "'") //TODO: replace this with something that isn't a hard coded id
+        .buildSql(persSql, "", " order by PERSON.LASTNAME asc");
+    var persData = db.table(persSql);
+    
+    for (let i = 0; i < persData.length; i++)
+    {
+        _joinArrayVals(persData[i], 0, 4); //join the full name together
+        _joinArrayVals(persData[i], 3, 2, "\n"); //join communication together
+    }
+    persData = ReportData.begin(["PERSNAMECOMPLETE", "PERSFUNCTION", "PERSDEPARTMENT", "PERSCOMM", "ORGANISATION_ID", "CONTACT_ID"]).add(persData);
+
+    var histSql = "select ENTRYDATE, CATEGORY, FIRSTNAME, LASTNAME, INFO from ACTIVITY "
+        + " join ACTIVITYLINK on ACTIVITYLINK.ACTIVITY_ID = ACTIVITYID "
+        + " join CONTACT on ACTIVITYLINK.OBJECT_ROWID = CONTACTID"
+        + " left join PERSON on CONTACT.PERSON_ID = PERSONID";
+    histSql = SqlCondition.begin()
+        .andPrepare("CONTACT.ORGANISATION_ID", pOrgId)   //= all activities linked to the organization or an employee
+        .buildSql(histSql, "", "order by ENTRYDATE desc");
+    var histData = db.table(histSql);
+    
+    var dateFormat = translate.text("dd.MM.yyyy");
+    histData.forEach(function (row) 
+    {
+        row[0] = datetime.toDate(row[0], dateFormat);
+        // convert html to text
+        if (row[1] == $KeywordRegistry.activityCategory$mail())
+        {
+            row[4] = text.html2text(row[4]);
+        }
+        
+        row[1] = KeywordUtils.getViewValue($KeywordRegistry.activityCategory(), row[1]);
+        _joinArrayVals(row, 2, 2);
+    });
+    histData = ReportData.begin(["ENTRYDATE", "MEDIUM", "LOGIN", "INFO"]).add(histData);
+    
+    var attr = AttributeRelationUtils.getAllAttributes(pOrgId)
+        .map(function (row) {return row[1] ? row.join(": ") : row[0]})
+        .join("\n");
+    
+    //tasks
+    var taskSql = "select TASK.SUBJECT, TASK.DESCRIPTION, TASK.STATUS, FIRSTNAME, LASTNAME from TASK"
+        + " join CONTACT on EDITOR_CONTACT_ID = CONTACTID"
+        + " left join PERSON on CONTACT.PERSON_ID = PERSONID";
+    taskSql = SqlCondition.begin()
+        .andPrepare("CONTACT.ORGANISATION_ID", pOrgId)
+        .buildSql(taskSql);
+    var taskData = db.table(taskSql);
+    
+    taskData.forEach(function (row) 
+    {
+        row[2] = KeywordUtils.getViewValue($KeywordRegistry.taskStatus(), row[2]);
+        _joinArrayVals(row, 3, 2); //join FIRSTNAME and LASTNAME together
+    });
+    taskData = ReportData.begin(["SUBJECT", "INFOTEXT", "STATUS", "RESPONSIBLE"]).add(taskData);
+    
+    var params = {
+        "ORGAddr" : AddressUtils.getAddress(relationId).toString(), //TODO: use new address logic when available
+        "ORGAttr" : attr,
+        "INFO" : info
+    };
+    
+    var orgReport = new Report("Organisation_report", params);
+    
+    //add subreport data
+    orgReport.addSubReportData("subdataComm", commData);
+    orgReport.addSubReportData("subdataPers", persData);
+    orgReport.addSubReportData("subdataHist", histData);
+    orgReport.addSubReportData("subdataTask", taskData);
+    
+    //add logo
+    //TODO: use an function to get the image when available
+    var imgData = [
+        "meineFirma | Konrad-Zuse-Straße 4  |  DE 84144 Geisenhausen",
+        "base64:iVBORw0KGgoAAAANSUhEUgAAAM4AAABRCAYAAACaL5lSAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDA4QzAyM0IwREIwMTFFNEFGMDREM0VEMjExRjlBRTIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDA4QzAyM0MwREIwMTFFNEFGMDREM0VEMjExRjlBRTIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMDhDMDIzOTBEQjAxMUU0QUYwNEQzRUQyMTFGOUFFMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMDhDMDIzQTBEQjAxMUU0QUYwNEQzRUQyMTFGOUFFMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhF3nYoAAAlvSURBVHja7J1fjBXVHcfPJQJRoe1urQYJRBYlMUJisqwvGNjY3WgEUtN2CeWBIGb3Ju6LElsW+gA8AHe1UfuwTcBASB/Q7CZNG0tjw2pWU15kNzEBJFnLqmvQBNEbU0pbX+jve+9vlrOzM/fOnTtz78zs95P8cv/MOTPnzJzvnN/5zZ+Tu3XrliGE1MYC7gJCKBxCKBxCKBxCKBxCKBxCCIVDCIVDCIVDCIVDyDzmDq8/d+1/PY5trRB7VGyt2BqxVWLLxe4RW6JpbohdF7sq9qnYpNhFsY/Evoi6QKeOvMAWQKITToQ8LPaEWKfYBrFlVdL/SO1BsU3W/1+JnRMbE3tP7DIPHcmicLrFfia2VWxlBOuD4H6pNi32tthfxM7yEJIsCAc9yw6x7WJLYyozhNgvtlPsLbHT2hMRkjrhYPzynNhu/d4IIMxesafEToqdiGMcREhcwnlKe4AtTaoDhHpArF1sSOwdHlYSN/WGo/Niv2+iaGy2aFnyPKwkqT1OTmyf2pIE1Qdh7t+J/VjsqBgfbyWJEU5OXaMDCa0ThHxYbJHYIYqHJMVV25dg0dgc0LIS0nTh5FPWGPdxzEOaLRxEz/YkbEwTxG3bo2UnpOHCQci3XwffaWONln0FDzdptHBwcXNLiuu5RetASMOE02nKdwSknd1aF0IaIpwdGXFzVmhdCIldOLjLeXuG6rtd60RIrMLBowFLM1TfpVonQmITDh5C25rBOm/VuhESi3Dw5ObKDNZ5pdaNkFiE05nhenfy0JM4hIMI1IYM13uD4QVREoNw8DaaZRmu9zKtIyGh8HusYG3UG/pJ6w/NKy89O/P70j+nzSsn/zTz+5EHV5oHlt9rep58fFa+sQ8vmEtXps35C5/4+12PrTMP3H9v6dMGeZAX6/Cp49tsAiRK4TTsnrS771xsdj3TZTrWPeQrCtiljmnzhzfPmH//538zyyC0/l9tLonSC6wT1tmxzgxJ3q+//a4pdSTzx1Vb1SjR/Hr3L3xFY4MeCWnt3wf7d/iKxgYC+83un7vTruLhJ1H3OMsbsfHnpbdAo0Yv8rcPzpsz74/P6i3QU0AgtgA2b1pvPhQXDHltd+7MB+MzPQrSIa/tukE0mzeuN6f+/O6cOuZyubrr0tvb12bK73nDZ/cbbxwfzWKD2Tnw2l75KIiN/rHwYibvwggyobSfcO6Ju3COINDYX5axjsuNKo1PYLue+eksATy9scN0rF1T6q0AxkkYL9l8dvWaOXX1XfPZl9dK+W23zxJY1HXsUtEANK7RBDf+s1reakyJOFa7/utz6ivr6ZLlmTxBhHXVGvawmsfYYxYjf//HrHENBIMexVnmFs2cwIJr+WO33cKo64gGNKXfBzPcZo479Z2voqnU4zQENGz0DpWAaJAOLpoNxGa7dn6cv/jJbHfv/vtiqYu4ZhDN6pQd/5rdLUk/mPETQ109zo2GCOf8hUDpPr4yHTqvu8exAgQ3DCERC+d63BtGT1Ktt3G45uHK+VybmYPbDbSEc52Hn0QtnKtxb7jSuKZaWojOHvfUkt8JKjSijmT+jXEwqdOmeHuc/4bOe7OOvK46etLb24eoWI8pv4/aHhSP+IWZNRx9RX/mJd3xasvlP2wDUSo7wlUaQ8jyYrUKhClnvewceO2Yltkr4maHq0vLEXkz5SijU8duJ6jgXpf8btPfe937Q5YXNU+LpilYaSY0zUiVsrdrObD+FmsR8o1Uyx+kx5mcByeNSa/GLzauB6XdtRgH66w21rqR9aDRDJu5YWGsf1yF5pe3YeWsU2QoW6DQt6a94hLNzP6AYFRY4y7RGN0Hwypav/UXrLwtrsU91fIHFc7FeSCci67G2KIHGQehqL1CDmbK0TLnbFSQtH11brtPbdDaRqu5Hept82hAzShnveDEgN5ltZzNc2pePaFTJ5S9Fel89sewfs876zPlR+GdywAFFZcX7VYPtj5E/kCuGubcxPSBWb1D+iuto01BDwp2YreGl0vo923SEIf17LTXOqhhaHe7c+qa5VUYJRdOvg94uGxRlhMXMStdJu+u41oNyjgRMNzdoq7SNucPdc3y2pC7rBPJNtulQvkkTd7cnp2vx3iHyydUcFP2nzXkD9TjYIKmcxnubc4ZaxIqbazO2XnQbowunB0KV6m9ju2PusdALn/bfZZsVjnrZTCCtPZ+8hyHqLinLMEajzQDbtG48hcr5Q/a44AxU55zM4uMefi4Xg13FtJQJ6Qh2o16IqxwAi5ri7mcsd5vVsNguyhp/co44fPdzZTur7aQxZ0wwW5DqioczO6Mq4dZfO/Aex5uhcO3VqOr5l6EpVih0RcrbL/R5ayHqSj2RwURhdqeFZWzx5s1i62ScDAlOh706s+gcC4npHHVSoshoRDB9Fjjw7qpdq8apkTH7M5LM75fnTNeUc74rSxn5kTjXFtyGLDHUAhE1HDHeCDhYGWYEr13nginBQPwIBcfWc5UsdcKLmyLYoVB3h192mR/GvRRnwE4y5n+3qbdcnErBSvaoxbOmNjJLO9cRKGsgWehylX7rmZdlU9LOdM2RtS7ClqiFg44IfbXtO6thQvvuBkgWd7auePuRqcN8Zi5faGsWaSlnIlAw9yOS1vQIIEjmDb7frkogwMOcNWGTPnNMGl7O8zknYsX/UA+76p2NpcGB/93WBslzugFn+QTzapMWsqZMPLW/sI9ae7l3ToOChxxq2UO0HfEXjXpegAMZX118aKFNwM2SvjAqzXqUvRohPi/tdkv4khLORPU64yoONxjHNyVsD7MbUU5rzd67Nr/eqU8+8UOp2Sf/VbsiN/CU0deYKsioVgQIs9RsUMpqNshLSshkRPmZR23tFF+L7bPJG/69hsqmKNaVkISIRxHPHCBvhHbk6CAwaSOw47x0JIkCscBDfRzU76frdnTuSNcPqRBDEISLRyjDfWSKUdzMCV6o+edQagcF2hPmOzf4UAyJByn8R405bsMMCU6ZneO+8bQf5nyfXSnzdznawhJhXAcxtQQL8fszpioNurnefCMEB53wJ3bvDpOMiEch7NqGHNgotpOU54+MOw7DPCOgHMqSjyEdpmHjmRROA6X1YZ07IPpAzETGqJwmJ8GU21g1gAnpI1QMt6wiZcF4r1niJLhbTQfcfxCkkQuyFwghJDZLOAuIITCIYTCIYTCIYTCIYTCIYRQOIRQOIRQOIRQOIRQOISQWvi/AAMA9UczDEaG0p8AAAAASUVORK5CYII="
+    ];
+    params["myAddr"] = imgData[0];
+    orgReport.addImage("myLogo", imgData[1]);
+    
+    orgReport.openReport();
+    
+    /*
+     * merges multiple columns in an two-dimensional array into one
+     */
+    function _joinArrayVals (pArr, pIndex, pHowMany, pJoinSeparator)
+    {
+        if (pJoinSeparator == undefined)
+            pJoinSeparator = " ";
+        pArr.splice(pIndex, pHowMany, ArrayUtils.joinNonEmptyFields(
+            pArr.slice(pIndex, pIndex + pHowMany), pJoinSeparator)
+        );
+    }
 }
\ No newline at end of file
-- 
GitLab