From edba4b68176b70add0755f7973d399980eb0cffc Mon Sep 17 00:00:00 2001
From: Sebastian Listl <s.listl@adito.de>
Date: Mon, 19 Oct 2020 15:10:54 +0200
Subject: [PATCH] VisitRecommendation filters added

---
 .../VisitRecommendation_entity.aod            |  17 +-
 .../recordcontainers/jdito/contentProcess.js  | 255 +++++++++++-------
 2 files changed, 170 insertions(+), 102 deletions(-)

diff --git a/entity/VisitRecommendation_entity/VisitRecommendation_entity.aod b/entity/VisitRecommendation_entity/VisitRecommendation_entity.aod
index 2aed7529f6..6010af8787 100644
--- a/entity/VisitRecommendation_entity/VisitRecommendation_entity.aod
+++ b/entity/VisitRecommendation_entity/VisitRecommendation_entity.aod
@@ -176,11 +176,16 @@
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityField>
+      <name>ADDRESS_ZIP</name>
+      <title>Zip</title>
+    </entityField>
   </entityFields>
   <recordContainers>
     <jDitoRecordContainer>
       <name>jDito</name>
       <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
+      <isFilterable v="true" />
       <contentProcess>%aditoprj%/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js</contentProcess>
       <onInsert>%aditoprj%/entity/VisitRecommendation_entity/recordcontainers/jdito/onInsert.js</onInsert>
       <onUpdate>%aditoprj%/entity/VisitRecommendation_entity/recordcontainers/jdito/onUpdate.js</onUpdate>
@@ -196,13 +201,9 @@
         </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>ORGANISATION_POINT_OF_CONTACT.value</name>
-          <isFilterable v="true" />
-          <isLookupFilter v="true" />
         </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>ORGANISATION_ADDRESS.value</name>
-          <isFilterable v="true" />
-          <isLookupFilter v="true" />
         </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>PRIORITY.value</name>
@@ -217,20 +218,20 @@
         </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>DUE_DATE.value</name>
-          <isFilterable v="true" />
-          <isLookupFilter v="true" />
         </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>INFO.value</name>
         </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>CONTACT_ID.value</name>
-          <isFilterable v="true" />
-          <isLookupFilter v="true" />
         </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>PRIORITY_SOURCE.displayValue</name>
         </jDitoRecordFieldMapping>
+        <jDitoRecordFieldMapping>
+          <name>ADDRESS_ZIP.value</name>
+          <isFilterable v="true" />
+        </jDitoRecordFieldMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js b/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js
index 2dcf9d4752..7effd511c0 100644
--- a/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js
@@ -1,3 +1,4 @@
+import("system.SQLTYPES");
 import("system.eMath");
 import("system.tools");
 import("PostalAddress_lib");
@@ -16,59 +17,77 @@ import("AttributeRegistry_basic");
 import("KeywordRegistry_basic");
 import("Util_lib");
 import("Address_lib");
+import("JditoFilter_lib");
 
-var recommendationData = [];
-var tmpData = [];
-var activitySubQuery = "";
+var sqlMasker = new SqlMaskingUtils();
 
-activitySubQuery = newSelect("max(ENTRYDATE)")
+var activitySubQuery = newSelect("max(ENTRYDATE)")
                                 .from("ACTIVITY")
                                 .join("ACTIVITYLINK", "ACTIVITYID = ACTIVITY_ID")
                                 .where("ACTIVITYLINK.OBJECT_ROWID = org.ORGANISATIONID")
                                 .and("ACTIVITY.CATEGORY", "VISIT")
 
-var idValues = false;
+var idValues = null;
 if (vars.exists("$local.idvalues") && vars.get("$local.idvalues"))
-    idValues = true
+    idValues = vars.get("$local.idvalues");
 
 //dynamic Recommendations
 //recommended Organisations containing the attribute Visit Frequency
 
-if(idValues == false)
+if (!idValues)
 {
-    var visitFrequencyData = newSelect(["org.ORGANISATIONID", "NAME", 
-                                            newSelect("CONTACT.CONTACTID")
-                                                        .from("CONTACT")
-                                                        .leftJoin("AB_ATTRIBUTERELATION", "CONTACT.CONTACTID = AB_ATTRIBUTERELATION.OBJECT_ROWID")
-                                                        .leftJoin("AB_ATTRIBUTE", "AB_ATTRIBUTE.AB_ATTRIBUTEID = AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID")
-                                                        .leftJoin("ORGANISATION", "ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID")
-                                                        .where("AB_ATTRIBUTE.AB_ATTRIBUTEID", $AttributeRegistry.visitPlanPointOfContact())
-                                                        .cell(), AddressUtils.formatOnelineSql(), 
-                                                        "visitPlanFrequency.ID_VALUE", "'" + $KeywordRegistry.visitRecommendationPrioSource$visitFrequency()+"'" , activitySubQuery, "CONTACTID",
-                                            newSelect("min(ENTRYDATE)")
-                                                        .from("VISITPLANENTRY") 
-                                                        .where("CONTACT.CONTACTID", "VISITPLANENTRY.ORGANISATION_CONTACT_ID") 
-                                                        .and(newWhere("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$planned())
-                                                            .or("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged()))
-                                                        .and("VISITPLANENTRY.ENTRYDATE", newSelect("min(vp.ENTRYDATE)")
-                                                                                                    .from("VISITPLANENTRY", "vp")
-                                                                                                    .where(["VISITPLANENTRY", "ORGANISATION_CONTACT_ID", "vp"], "visitplanentry.ORGANISATION_CONTACT_ID")
-                                                                                                    .and(["VISITPLANENTRY", "ENTRYDATE", "vp"], datetime.today())
-                                                                                                    .and(newWhere(["VISITPLANENTRY", "STATUS", "vp"], 
-                                                                                                    $KeywordRegistry.visitPlanEntryStatus$planned())
-                                                                                                    .or(["VISITPLANENTRY", "STATUS", "vp"], 
-                                                                                                    $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged()))
-                                                                                                    .cell())])
-                                        .from("CONTACT")
-                                        .join("ORGANISATION", "CONTACT.ORGANISATION_ID = org.ORGANISATIONID", "org")
-                                        .leftJoin("PERSON", "PERSON.PERSONID = CONTACT.PERSON_ID")
-                                        .leftJoin("ADDRESS", "ADDRESS_ID = ADDRESSID")
-                                        .join("AB_ATTRIBUTERELATION", "visitPlanFrequency.OBJECT_ROWID = CONTACT.CONTACTID", "visitPlanFrequency")
-                                        .where(["AB_ATTRIBUTERELATION", "AB_ATTRIBUTE_ID", "visitPlanFrequency"], $AttributeRegistry.visitPlanFrequency())
-                                        .table();
+    var visitFrequencyData = newSelect([
+            "org.ORGANISATIONID", 
+            "NAME", 
+            newSelect("CONTACT.CONTACTID")
+                .from("CONTACT")
+                .leftJoin("AB_ATTRIBUTERELATION", "CONTACT.CONTACTID = AB_ATTRIBUTERELATION.OBJECT_ROWID")
+                .leftJoin("AB_ATTRIBUTE", "AB_ATTRIBUTE.AB_ATTRIBUTEID = AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID")
+                .leftJoin("ORGANISATION", "ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID")
+                .where("AB_ATTRIBUTE.AB_ATTRIBUTEID", $AttributeRegistry.visitPlanPointOfContact()), 
+            AddressUtils.formatOnelineSql(), 
+            "visitPlanFrequency.ID_VALUE", 
+            "'" + $KeywordRegistry.visitRecommendationPrioSource$visitFrequency()+"'" , 
+            activitySubQuery, 
+            "CONTACTID",
+            newSelect("min(ENTRYDATE)")
+                .from("VISITPLANENTRY") 
+                .where("CONTACT.CONTACTID", "VISITPLANENTRY.ORGANISATION_CONTACT_ID") 
+                .and(newWhere("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$planned())
+                    .or("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged()))
+                .and("VISITPLANENTRY.ENTRYDATE", newSelect("min(vp.ENTRYDATE)")
+                    .from("VISITPLANENTRY", "vp")
+                    .where(["VISITPLANENTRY", "ORGANISATION_CONTACT_ID", "vp"], "visitplanentry.ORGANISATION_CONTACT_ID")
+                    .and(["VISITPLANENTRY", "ENTRYDATE", "vp"], datetime.today())
+                    .and(newWhere(["VISITPLANENTRY", "STATUS", "vp"], 
+                    $KeywordRegistry.visitPlanEntryStatus$planned())
+                    .or(["VISITPLANENTRY", "STATUS", "vp"], 
+                    $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged()))
+                    .cell()),
+            "ADDRESS.ZIP"
+        ])
+        .from("CONTACT")
+        .join("ORGANISATION", "CONTACT.ORGANISATION_ID = org.ORGANISATIONID", "org")
+        .leftJoin("PERSON", "PERSON.PERSONID = CONTACT.PERSON_ID")
+        .leftJoin("ADDRESS", "ADDRESS_ID = ADDRESSID")
+        .join("AB_ATTRIBUTERELATION", "visitPlanFrequency.OBJECT_ROWID = CONTACT.CONTACTID", "visitPlanFrequency")
+        .where(["AB_ATTRIBUTERELATION", "AB_ATTRIBUTE_ID", "visitPlanFrequency"], $AttributeRegistry.visitPlanFrequency())
+        .table();
+        
+    
  }
 
-var recommendationSQLData = newSelect(["VISITRECOMMENDATIONID", "VISITRECOMMENDATION.CONTACT_ID", "PRIORITY", "DUE_DATE", "SOURCE", "INFO", AddressUtils.formatOnelineSql(), 
+var prioSubSql = _getPrioByDueDateSubSql("VISITRECOMMENDATION.DUE_DATE", "VISITRECOMMENDATION.PRIORITY");
+
+var recommendationSQLData = newSelect([
+    "VISITRECOMMENDATIONID", 
+    "VISITRECOMMENDATION.CONTACT_ID", 
+    "ORGANISATION.NAME", 
+    prioSubSql, 
+    "VISITRECOMMENDATION.DUE_DATE", 
+    "VISITRECOMMENDATION.SOURCE", 
+    "VISITRECOMMENDATION.INFO", 
+    AddressUtils.formatOnelineSql(), 
     newSelect("CONTACT.CONTACTID")
                 .from("CONTACT")
                 .leftJoin("AB_ATTRIBUTERELATION", "CONTACT.CONTACTID = AB_ATTRIBUTERELATION.OBJECT_ROWID")
@@ -96,92 +115,105 @@ var recommendationSQLData = newSelect(["VISITRECOMMENDATIONID", "VISITRECOMMENDA
                                                                 .from("visitplanentry", "VP")
                                                                 .where(["VISITPLANENTRY", "entrydate", "vp"], datetime.today(), SqlBuilder.GREATER())
                                                                 .and(["VISITPLANENTRY", "STATUS", "vp"], $KeywordRegistry.visitPlanEntryStatus$planned())
-                                                                .or(["VISITPLANENTRY", "STATUS", "vp"], $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged()).cell())
+                                                                .or(["VISITPLANENTRY", "STATUS", "vp"], $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged()).cell()),
+    "ADDRESS.ZIP"
 ])
         .from("VISITRECOMMENDATION")
         .join("CONTACT", "VISITRECOMMENDATION.CONTACT_ID = CONTACT.CONTACTID")
+        .leftJoin("ORGANISATION", "CONTACT.ORGANISATION_ID = ORGANISATION.ORGANISATIONID")
         .join("ADDRESS", "CONTACT.ADDRESS_ID = ADDRESS.ADDRESSID")
-        
-if(idValues == true)
-    recommendationSQLData.where("VISITRECOMMENDATION.VISITRECOMMENDATIONID",   vars.get("$local.idvalues"), SqlBuilder.IN())
-        
-recommendationSQLData = recommendationSQLData.table();
+        .whereIfSet("VISITRECOMMENDATION.VISITRECOMMENDATIONID", idValues, SqlBuilder.IN());
 
-for( let i = 0; i < recommendationSQLData.length; i++)
-{
-    tmpData = [];
-
-    var organisationName = ContactUtils.getFullTitleByContactId(recommendationSQLData[i][1])
-    if(recommendationSQLData[i][2])
-        var prio = recommendationSQLData[i][2]
-
-    else if(recommendationSQLData[i][3])
-        prio = getPrioByDueDate(recommendationSQLData[i][3]);
+var filterCond = new FilterSqlTranslator(vars.get("$local.filter"), "VISITRECOMMENDATION")
+    .addSqlFieldMapping("ORGANISATION_NAME", "ORGANISATION.NAME")
+    .addSqlFieldMapping("ADDRESS_ZIP", "ADDRESS.ZIP")
+    .addSpecialFieldConditionFn("PRIORITY", function (pFilterValue, pOperator)
+    {
+        switch (pOperator)
+        {
+            case "EQUAL":
+                return [prioSubSql[0] + " = ?", prioSubSql[1].concat([[pFilterValue, SQLTYPES.VARCHAR]])];
+            case "NOT_EQUAL":
+                return [prioSubSql[0] + " != ?", prioSubSql[1].concat([[pFilterValue, SQLTYPES.VARCHAR]])];
+            case "ISNULL":
+                return [prioSubSql[0] + " is null", prioSubSql[1]];
+            case "ISNOTNULL":
+                return [prioSubSql[0] + " is not null", prioSubSql[1]];
+            default:
+                return false;
+        }
+    })
+    .getSqlCondition();
 
-    else
-        prio = $KeywordRegistry.visitRecommendationPriority$low();  
+recommendationSQLData = recommendationSQLData.andIfSet(filterCond).table();
 
-    
+var recommendationData = recommendationSQLData.map(function ([uid, contactId, organisationName, priority, dueDate, prioSource, info, address, what, plannedDate, visitContact, addressZip])
+{
     var title = "";
-    if(recommendationSQLData[i][9]){
-        var user = tools.getUserByAttribute(tools.CONTACTID, recommendationSQLData[i][9]);
+    if(visitContact)
+    {
+        var user = tools.getUserByAttribute(tools.CONTACTID, visitContact);
         title = user[tools.TITLE]
     }
-
-    tmpData[0] = recommendationSQLData[i][0];               //UID
-    tmpData[1] = organisationName;                          //Organisation Name
-    tmpData[3] = recommendationSQLData[i][6];               //Address
-    tmpData[4] = prio; 
-    tmpData[5] = recommendationSQLData[i][4];               //Source of Priority (Id)
-    tmpData[7] = recommendationSQLData[i][3];               //Due Date
-    tmpData[8] = recommendationSQLData[i][5];               //Info
-    tmpData[9] = recommendationSQLData[i][1];               //CONTACT_ID
-    tmpData[2] = recommendationSQLData[i][8];               //Data_planned
-    tmpData[6] = KeywordUtils.getViewValue($KeywordRegistry.visitRecommendationPrioSource(), recommendationSQLData[i][4]) //Source of Priority (displayvalue)
     
-
-    recommendationData.push(tmpData);
-}
+    return [
+        uid,
+        organisationName,
+        plannedDate,
+        address,
+        priority,
+        prioSource,
+        KeywordUtils.getViewValue($KeywordRegistry.visitRecommendationPrioSource(), prioSource), //Source of Priority (displayvalue)
+        dueDate,
+        info,
+        contactId,
+        "",
+        addressZip
+    ];
+});
 
 var monthly = parseInt(datetime.ONE_DAY * 31);
 var semiannually = parseInt(datetime.ONE_DAY * 183);
 var quarterly = parseInt(datetime.ONE_DAY * 93);
 var yearly = parseInt(datetime.ONE_DAY * 365);
 
-if(idValues == false)
+if (!idValues)
 {
+    var frequencyData = [];
     for (var i = 0; i < visitFrequencyData.length; i++)
     {
-        tmpData = [];
-
         let title = "";
 
-        if(visitFrequencyData[i][9])
+        if(visitFrequencyData[i][10])
         {
             let user = tools.getUserByAttribute(tools.CONTACTID, visitFrequencyData[i][9]);
             title = user[tools.TITLE]
         }
-
-        tmpData[0] = visitFrequencyData[i][0];                 //UID
-        tmpData[1] = visitFrequencyData[i][1];                 //Organisation Name
-        tmpData[3] = visitFrequencyData[i][2];                 //Address
-        tmpData[5] = visitFrequencyData[i][4];                 //Source of Priority (Id)
-        tmpData[8] = "";
-        tmpData[4] = visitFrequencyData[i][5];                 //last visit
-        tmpData[9] = visitFrequencyData[i][6];                 //ContactId
-        tmpData[2] = visitFrequencyData[i][1];                 //OrganisationId
-        tmpData[6] = KeywordUtils.getViewValue($KeywordRegistry.visitRecommendationPrioSource(), visitFrequencyData[i][4]) //Source of Priority (displayvalue)
+        
+        let tmpData = [
+            visitFrequencyData[i][0],                 //UID
+            visitFrequencyData[i][1],                 //Organisation Name
+            visitFrequencyData[i][2],                 //point of contact
+            visitFrequencyData[i][3],                 //Address
+            "",                                       //prio
+            visitFrequencyData[i][5],                 //Source of Priority (Id)
+            "",                                       //Source of Priority (displayvalue)
+            "",                                       //dueDate
+            "",                                       //info
+            visitFrequencyData[i][7],                 //ContactId
+            "",
+            visitFrequencyData[i][9]
+        ];
         var dueDate = "";
-        var lastVisitDate = "";
+        var lastVisitDate = visitFrequencyData[i][8];
 
-        if((visitFrequencyData[i][5]).length == 0)
+        if (!lastVisitDate)
         {
             dueDate = datetime.date();
         }
         else
         {
-            lastVisitDate = visitFrequencyData[i][5];
-            switch(visitFrequencyData[i][3])
+            switch(visitFrequencyData[i][4])
             {
                 case $AttributeRegistry.visitPlanFrequency$monthly():
                 {
@@ -210,13 +242,16 @@ if(idValues == false)
 
             }
         }
-
-
         tmpData[7] = dueDate;                                       //Due Date
         tmpData[4] = getPrioByDueDate(dueDate);                     //Priority
 
-        recommendationData.push(tmpData);
+        frequencyData.push(tmpData);
     }
+    var recordFilter = vars.get("$local.filter");
+    if (recordFilter && recordFilter.filter)
+        frequencyData = JditoFilterUtils.filterRecords(["UID", "ORGANISATION_NAME", "", "ORGANISATION_ADDRESS", "PRIORITY", "", "", "DUE_DATE", "INFO", "CONTACT_ID", "", "ADDRESS_ZIP"], 
+            frequencyData, recordFilter.filter);
+    recommendationData = recommendationData.concat(frequencyData);
 }
 
 
@@ -232,6 +267,38 @@ ArrayUtils.sort2d(recommendationData, 4, true)
 
 result.object(recommendationData);
 
+function _getPrioByDueDateSubSql (pDueDateField, pPriorityField)
+{
+    var currentDate = datetime.date();
+    var sqlMasker = new SqlMaskingUtils();
+    
+    var subSql = "case when " + pDueDateField + " < ? then '" + $KeywordRegistry.visitRecommendationPriority$critical()
+        + "' when " + pDueDateField + " < ? then '" + $KeywordRegistry.visitRecommendationPriority$veryHigh()
+        + "' when " + pDueDateField + " < ? then '" + $KeywordRegistry.visitRecommendationPriority$high()
+        + "' when " + pDueDateField + " < ? then '" + $KeywordRegistry.visitRecommendationPriority$medium()
+        + "' else '" + $KeywordRegistry.visitRecommendationPriority$low() + "' end";
+    
+    var [table, field] = pDueDateField.split(".");
+    var dateFieldType = db.getColumnTypes(table, [field])[0];
+    
+    var dateDiffs = [
+        0,                      //critical
+        datetime.ONE_DAY * 3,   //very high
+        datetime.ONE_WEEK,      //high
+        datetime.ONE_WEEK * 2   //medium
+    ];
+    
+    var preparedValues = dateDiffs.map(function (dateDiff)
+    {
+        return [(currentDate + dateDiff).toString(), dateFieldType];
+    });
+    
+    if (pPriorityField)
+        subSql = sqlMasker.isNull(pPriorityField, "(" + subSql + ")");
+    
+    return [subSql, preparedValues];
+}
+
 function getPrioByDueDate(pDueDate)
 {
     var prio = "";
-- 
GitLab