From 2baa745da164631858da425e399f5d241694383f Mon Sep 17 00:00:00 2001
From: Sebastian Listl <s.listl@adito.de>
Date: Tue, 1 Jun 2021 14:52:17 +0000
Subject: [PATCH] M 1080687 contact filter extensions

---
 .../BulkMailRecipient_entity.aod              |  1 +
 .../CommunicationSettings_entity.aod          |  2 +
 .../entityfields/date_edit/stateProcess.js    | 10 +++
 .../entityfields/date_new/stateProcess.js     | 10 +++
 .../Organisation_entity.aod                   | 54 +++++++++++++++
 .../containername_param/valueProcess.js       |  4 ++
 .../filterConditionProcess.js                 | 23 +++++++
 .../filterConditionProcess.js                 | 21 ++++++
 .../filterConditionProcess.js                 | 21 ++++++
 .../filterFieldsProcess.js                    | 25 +++++++
 entity/Person_entity/Person_entity.aod        | 65 +++++++++++++++++++
 .../containername_param/valueProcess.js       |  4 ++
 .../filterConditionProcess.js                 | 23 +++++++
 .../filterConditionProcess.js                 | 21 ++++++
 .../filterConditionProcess.js                 | 21 ++++++
 .../filterFieldsProcess.js                    | 25 +++++++
 .../filterConditionProcess.js                 | 23 +++++++
 .../_____LANGUAGE_EXTRA.aod                   |  6 +-
 .../_____LANGUAGE_de/_____LANGUAGE_de.aod     | 20 +++++-
 .../_____LANGUAGE_en/_____LANGUAGE_en.aod     |  6 +-
 neonContext/BulkMail/BulkMail.aod             |  5 ++
 .../BulkMailLookup_view.aod                   | 37 +++++++++++
 process/MarketingCondition_lib/process.js     |  6 ++
 23 files changed, 425 insertions(+), 8 deletions(-)
 create mode 100644 entity/CommunicationSettings_entity/entityfields/date_edit/stateProcess.js
 create mode 100644 entity/CommunicationSettings_entity/entityfields/date_new/stateProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js
 create mode 100644 entity/Organisation_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js
 create mode 100644 entity/Organisation_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js
 create mode 100644 entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js
 create mode 100644 entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js
 create mode 100644 entity/Person_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js
 create mode 100644 entity/Person_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js
 create mode 100644 entity/Person_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js
 create mode 100644 entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js
 create mode 100644 entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js
 create mode 100644 entity/Person_entity/recordcontainers/db/filterextensions/interestlink_filter/filterConditionProcess.js
 create mode 100644 neonView/BulkMailLookup_view/BulkMailLookup_view.aod

diff --git a/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod b/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod
index d4a7182fc4..7f856b4de3 100644
--- a/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod
+++ b/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod
@@ -109,6 +109,7 @@
       <children>
         <entityActionField>
           <name>removeWithCommRestriction</name>
+          <title>Remove recipients with communication rejection</title>
           <onActionProcess>%aditoprj%/entity/BulkMailRecipient_entity/entityfields/recipientactions/children/removewithcommrestriction/onActionProcess.js</onActionProcess>
           <isObjectAction v="false" />
           <iconId>VAADIN:BAN</iconId>
diff --git a/entity/CommunicationSettings_entity/CommunicationSettings_entity.aod b/entity/CommunicationSettings_entity/CommunicationSettings_entity.aod
index cfa279a1e8..42abe2d268 100644
--- a/entity/CommunicationSettings_entity/CommunicationSettings_entity.aod
+++ b/entity/CommunicationSettings_entity/CommunicationSettings_entity.aod
@@ -35,6 +35,7 @@
       <title>Created on</title>
       <contentType>DATE</contentType>
       <state>READONLY</state>
+      <stateProcess>%aditoprj%/entity/CommunicationSettings_entity/entityfields/date_new/stateProcess.js</stateProcess>
       <valueProcess>%aditoprj%/entity/CommunicationSettings_entity/entityfields/date_new/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
@@ -42,6 +43,7 @@
       <title>Last change</title>
       <contentType>DATE</contentType>
       <state>READONLY</state>
+      <stateProcess>%aditoprj%/entity/CommunicationSettings_entity/entityfields/date_edit/stateProcess.js</stateProcess>
       <valueProcess>%aditoprj%/entity/CommunicationSettings_entity/entityfields/date_edit/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
diff --git a/entity/CommunicationSettings_entity/entityfields/date_edit/stateProcess.js b/entity/CommunicationSettings_entity/entityfields/date_edit/stateProcess.js
new file mode 100644
index 0000000000..44f9deec70
--- /dev/null
+++ b/entity/CommunicationSettings_entity/entityfields/date_edit/stateProcess.js
@@ -0,0 +1,10 @@
+import("system.result");
+import("system.neon");
+import("system.vars");
+
+var state = neon.COMPONENTSTATE_READONLY;
+if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW || vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT)
+{
+    state = neon.COMPONENTSTATE_INVISIBLE;
+}
+result.string(state);
\ No newline at end of file
diff --git a/entity/CommunicationSettings_entity/entityfields/date_new/stateProcess.js b/entity/CommunicationSettings_entity/entityfields/date_new/stateProcess.js
new file mode 100644
index 0000000000..44f9deec70
--- /dev/null
+++ b/entity/CommunicationSettings_entity/entityfields/date_new/stateProcess.js
@@ -0,0 +1,10 @@
+import("system.result");
+import("system.neon");
+import("system.vars");
+
+var state = neon.COMPONENTSTATE_READONLY;
+if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW || vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT)
+{
+    state = neon.COMPONENTSTATE_INVISIBLE;
+}
+result.string(state);
\ No newline at end of file
diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod
index 807391c5e7..2d89d5020c 100644
--- a/entity/Organisation_entity/Organisation_entity.aod
+++ b/entity/Organisation_entity/Organisation_entity.aod
@@ -1333,6 +1333,36 @@
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityConsumer>
+      <name>Campaigns</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Campaign_entity</entityName>
+        <fieldName>Campaigns</fieldName>
+      </dependency>
+    </entityConsumer>
+    <entityConsumer>
+      <name>Bulkmails</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>BulkMail_entity</entityName>
+        <fieldName>#PROVIDER</fieldName>
+      </dependency>
+    </entityConsumer>
+    <entityConsumer>
+      <name>CommunicationSettingStatusKeyword</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>KeywordEntry_entity</entityName>
+        <fieldName>SpecificContainerKeywords</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ContainerName_param</name>
+          <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -1640,6 +1670,30 @@
           <filterConditionProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/filterextensions/commincation_link_filter/filterConditionProcess.js</filterConditionProcess>
           <filtertype>BASIC</filtertype>
         </filterExtension>
+        <filterExtension>
+          <name>CampaignParticipation_filter</name>
+          <title>Campaign participation</title>
+          <contentType>TEXT</contentType>
+          <useConsumer v="true" />
+          <consumer>Campaigns</consumer>
+          <filterConditionProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtension>
+        <filterExtension>
+          <name>BulkmailReceived_filter</name>
+          <title>Received Bulk Mail</title>
+          <contentType>TEXT</contentType>
+          <useConsumer v="true" />
+          <consumer>Bulkmails</consumer>
+          <filterConditionProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtension>
+        <filterExtensionSet>
+          <name>CommunicationSettings_filter</name>
+          <filterFieldsProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js</filterFieldsProcess>
+          <filterConditionProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtensionSet>
       </filterExtensions>
     </dbRecordContainer>
     <indexRecordContainer>
diff --git a/entity/Organisation_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js b/entity/Organisation_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js
new file mode 100644
index 0000000000..6e90947849
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("KeywordRegistry_basic");
+
+result.string($KeywordRegistry.communicationSettingStatus());
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js b/entity/Organisation_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js
new file mode 100644
index 0000000000..d3faf41218
--- /dev/null
+++ b/entity/Organisation_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js
@@ -0,0 +1,23 @@
+import("KeywordRegistry_basic");
+import("Sql_lib");
+import("system.result");
+import("system.vars");
+
+var bulkmailRecipientSql = newSelect("BULKMAILRECIPIENTID")
+    .from("BULKMAILRECIPIENT")
+    .where("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
+    .and("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent());
+    
+var condType = SqlBuilder.EXISTS();
+var operator = vars.get("$local.comparison");
+
+if (operator == "NOT_EQUAL" || operator == "ISNULL")
+{
+    condType = SqlBuilder.NOT_EXISTS();
+}
+if (operator == "EQUAL" || operator == "NOT_EQUAL")
+{
+    bulkmailRecipientSql.and("BULKMAILRECIPIENT.BULKMAIL_ID", vars.get("$local.rawvalue"));
+}
+
+result.string(newWhere(null, bulkmailRecipientSql, condType));
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js b/entity/Organisation_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js
new file mode 100644
index 0000000000..d3472ac783
--- /dev/null
+++ b/entity/Organisation_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js
@@ -0,0 +1,21 @@
+import("Sql_lib");
+import("system.result");
+import("system.vars");
+
+var campaignParticipantSql = newSelect("CAMPAIGNPARTICIPANTID")
+    .from("CAMPAIGNPARTICIPANT")
+    .where("CAMPAIGNPARTICIPANT.CONTACT_ID = CONTACT.CONTACTID");
+    
+var condType = SqlBuilder.EXISTS();
+var operator = vars.get("$local.comparison");
+
+if (operator == "NOT_EQUAL" || operator == "ISNULL")
+{
+    condType = SqlBuilder.NOT_EXISTS();
+}
+if (operator == "EQUAL" || operator == "NOT_EQUAL")
+{
+    campaignParticipantSql.and("CAMPAIGNPARTICIPANT.CAMPAIGN_ID", vars.get("$local.rawvalue"));
+}
+
+result.string(newWhere(null, campaignParticipantSql, condType));
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js b/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js
new file mode 100644
index 0000000000..b45b894a14
--- /dev/null
+++ b/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js
@@ -0,0 +1,21 @@
+import("Sql_lib");
+import("system.result");
+import("system.vars");
+import("MarketingCondition_lib");
+
+var mediumId = vars.get("$local.name");
+mediumId = mediumId.slice(mediumId.lastIndexOf(".") + 1);
+var condition = new CommunicationSettingsCondition()
+    .medium(mediumId);
+    
+var operator = vars.get("$local.comparison");
+if (operator == "EQUAL" || operator == "NOT_EQUAL")
+{
+    condition.status(vars.get("$local.rawvalue"));
+}
+if (operator == "NOT_EQUAL" || operator == "ISNULL")
+{
+    condition.existNoSettings();
+}
+
+result.string(condition.buildCondition().toString());
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js b/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js
new file mode 100644
index 0000000000..31db294836
--- /dev/null
+++ b/entity/Organisation_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js
@@ -0,0 +1,25 @@
+import("system.translate");
+import("system.result");
+import("KeywordRegistry_basic");
+import("Keyword_lib");
+
+var mediums = KeywordUtils.getEntryNamesAndIdsByContainer($KeywordRegistry.communicationMediumCampaign(), null, true);
+var filterFields = [];
+mediums.forEach(function ([mediumId, mediumTitle])
+{
+    if (mediumId != $KeywordRegistry.communicationMediumCampaign$letter())
+    {
+        filterFields.push({
+            name: mediumId,
+            title: translate.withArguments("Communication Setting: %0", [mediumTitle]),
+            contentType: "TEXT",
+            hasDropDownValues: false,
+            isGroupable: false,
+            groupedRecordField: null,
+            titleRecordField: null,
+            consumer: "CommunicationSettingStatusKeyword"
+        });
+    }
+});
+
+result.string(JSON.stringify(filterFields));
\ No newline at end of file
diff --git a/entity/Person_entity/Person_entity.aod b/entity/Person_entity/Person_entity.aod
index 74e52fd3f8..2f19b8a67a 100644
--- a/entity/Person_entity/Person_entity.aod
+++ b/entity/Person_entity/Person_entity.aod
@@ -1290,6 +1290,38 @@
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityConsumer>
+      <name>Interests</name>
+      <description>Used for the filterExtension "InterestLink_filter"</description>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Interest_entity</entityName>
+        <fieldName>#PROVIDER</fieldName>
+      </dependency>
+    </entityConsumer>
+    <entityConsumer>
+      <name>Bulkmails</name>
+      <description>Used for the filterExtension "BulkmailReceived_filter"</description>
+      <dependency>
+        <name>dependency</name>
+        <entityName>BulkMail_entity</entityName>
+        <fieldName>#PROVIDER</fieldName>
+      </dependency>
+    </entityConsumer>
+    <entityConsumer>
+      <name>CommunicationSettingStatusKeyword</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>KeywordEntry_entity</entityName>
+        <fieldName>SpecificContainerKeywords</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ContainerName_param</name>
+          <valueProcess>%aditoprj%/entity/Person_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -1689,6 +1721,39 @@
           <filterValuesProcess>%aditoprj%/entity/Person_entity/recordcontainers/db/filterextensions/isemployee_filter/filterValuesProcess.js</filterValuesProcess>
           <filterConditionProcess>%aditoprj%/entity/Person_entity/recordcontainers/db/filterextensions/isemployee_filter/filterConditionProcess.js</filterConditionProcess>
         </filterExtension>
+        <filterExtension>
+          <name>InterestLink_filter</name>
+          <title>Interest (subscribed)</title>
+          <contentType>TEXT</contentType>
+          <useConsumer v="true" />
+          <consumer>Interests</consumer>
+          <filterConditionProcess>%aditoprj%/entity/Person_entity/recordcontainers/db/filterextensions/interestlink_filter/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtension>
+        <filterExtensionSet>
+          <name>CommunicationSettings_filter</name>
+          <filterFieldsProcess>%aditoprj%/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js</filterFieldsProcess>
+          <filterConditionProcess>%aditoprj%/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtensionSet>
+        <filterExtension>
+          <name>BulkmailReceived_filter</name>
+          <title>Received Bulk Mail</title>
+          <contentType>TEXT</contentType>
+          <useConsumer v="true" />
+          <consumer>Bulkmails</consumer>
+          <filterConditionProcess>%aditoprj%/entity/Person_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtension>
+        <filterExtension>
+          <name>CampaignParticipation_filter</name>
+          <title>Campaign participation</title>
+          <contentType>TEXT</contentType>
+          <useConsumer v="true" />
+          <consumer>Campaigns</consumer>
+          <filterConditionProcess>%aditoprj%/entity/Person_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtension>
       </filterExtensions>
     </dbRecordContainer>
     <indexRecordContainer>
diff --git a/entity/Person_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js b/entity/Person_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js
new file mode 100644
index 0000000000..63ee095ed6
--- /dev/null
+++ b/entity/Person_entity/entityfields/communicationsettingstatuskeyword/children/containername_param/valueProcess.js
@@ -0,0 +1,4 @@
+import("KeywordRegistry_basic");
+import("system.result");
+
+result.string($KeywordRegistry.communicationSettingStatus());
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js b/entity/Person_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js
new file mode 100644
index 0000000000..d3faf41218
--- /dev/null
+++ b/entity/Person_entity/recordcontainers/db/filterextensions/bulkmailreceived_filter/filterConditionProcess.js
@@ -0,0 +1,23 @@
+import("KeywordRegistry_basic");
+import("Sql_lib");
+import("system.result");
+import("system.vars");
+
+var bulkmailRecipientSql = newSelect("BULKMAILRECIPIENTID")
+    .from("BULKMAILRECIPIENT")
+    .where("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
+    .and("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent());
+    
+var condType = SqlBuilder.EXISTS();
+var operator = vars.get("$local.comparison");
+
+if (operator == "NOT_EQUAL" || operator == "ISNULL")
+{
+    condType = SqlBuilder.NOT_EXISTS();
+}
+if (operator == "EQUAL" || operator == "NOT_EQUAL")
+{
+    bulkmailRecipientSql.and("BULKMAILRECIPIENT.BULKMAIL_ID", vars.get("$local.rawvalue"));
+}
+
+result.string(newWhere(null, bulkmailRecipientSql, condType));
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js b/entity/Person_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js
new file mode 100644
index 0000000000..d3472ac783
--- /dev/null
+++ b/entity/Person_entity/recordcontainers/db/filterextensions/campaignparticipation_filter/filterConditionProcess.js
@@ -0,0 +1,21 @@
+import("Sql_lib");
+import("system.result");
+import("system.vars");
+
+var campaignParticipantSql = newSelect("CAMPAIGNPARTICIPANTID")
+    .from("CAMPAIGNPARTICIPANT")
+    .where("CAMPAIGNPARTICIPANT.CONTACT_ID = CONTACT.CONTACTID");
+    
+var condType = SqlBuilder.EXISTS();
+var operator = vars.get("$local.comparison");
+
+if (operator == "NOT_EQUAL" || operator == "ISNULL")
+{
+    condType = SqlBuilder.NOT_EXISTS();
+}
+if (operator == "EQUAL" || operator == "NOT_EQUAL")
+{
+    campaignParticipantSql.and("CAMPAIGNPARTICIPANT.CAMPAIGN_ID", vars.get("$local.rawvalue"));
+}
+
+result.string(newWhere(null, campaignParticipantSql, condType));
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js b/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js
new file mode 100644
index 0000000000..b45b894a14
--- /dev/null
+++ b/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterConditionProcess.js
@@ -0,0 +1,21 @@
+import("Sql_lib");
+import("system.result");
+import("system.vars");
+import("MarketingCondition_lib");
+
+var mediumId = vars.get("$local.name");
+mediumId = mediumId.slice(mediumId.lastIndexOf(".") + 1);
+var condition = new CommunicationSettingsCondition()
+    .medium(mediumId);
+    
+var operator = vars.get("$local.comparison");
+if (operator == "EQUAL" || operator == "NOT_EQUAL")
+{
+    condition.status(vars.get("$local.rawvalue"));
+}
+if (operator == "NOT_EQUAL" || operator == "ISNULL")
+{
+    condition.existNoSettings();
+}
+
+result.string(condition.buildCondition().toString());
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js b/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js
new file mode 100644
index 0000000000..31db294836
--- /dev/null
+++ b/entity/Person_entity/recordcontainers/db/filterextensions/communicationsettings_filter/filterFieldsProcess.js
@@ -0,0 +1,25 @@
+import("system.translate");
+import("system.result");
+import("KeywordRegistry_basic");
+import("Keyword_lib");
+
+var mediums = KeywordUtils.getEntryNamesAndIdsByContainer($KeywordRegistry.communicationMediumCampaign(), null, true);
+var filterFields = [];
+mediums.forEach(function ([mediumId, mediumTitle])
+{
+    if (mediumId != $KeywordRegistry.communicationMediumCampaign$letter())
+    {
+        filterFields.push({
+            name: mediumId,
+            title: translate.withArguments("Communication Setting: %0", [mediumTitle]),
+            contentType: "TEXT",
+            hasDropDownValues: false,
+            isGroupable: false,
+            groupedRecordField: null,
+            titleRecordField: null,
+            consumer: "CommunicationSettingStatusKeyword"
+        });
+    }
+});
+
+result.string(JSON.stringify(filterFields));
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/filterextensions/interestlink_filter/filterConditionProcess.js b/entity/Person_entity/recordcontainers/db/filterextensions/interestlink_filter/filterConditionProcess.js
new file mode 100644
index 0000000000..daf0725b4a
--- /dev/null
+++ b/entity/Person_entity/recordcontainers/db/filterextensions/interestlink_filter/filterConditionProcess.js
@@ -0,0 +1,23 @@
+import("KeywordRegistry_basic");
+import("Sql_lib");
+import("system.result");
+import("system.vars");
+
+var interestLinkSql = newSelect("INTERESTLINKID")
+    .from("INTERESTLINK")
+    .where("INTERESTLINK.CONTACT_ID = CONTACT.CONTACTID")
+    .and("INTERESTLINK.STATUS", $KeywordRegistry.interestLinkStatus$subscribed());
+    
+var condType = SqlBuilder.EXISTS();
+var operator = vars.get("$local.comparison");
+
+if (operator == "NOT_EQUAL" || operator == "ISNULL")
+{
+    condType = SqlBuilder.NOT_EXISTS();
+}
+if (operator == "EQUAL" || operator == "NOT_EQUAL")
+{
+    interestLinkSql.and("INTERESTLINK.INTEREST_ID", vars.get("$local.rawvalue"));
+}
+
+result.string(newWhere(null, interestLinkSql, condType));
\ No newline at end of file
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index ee70a5fef3..916c36e833 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -8632,9 +8632,6 @@
     <entry>
       <key>show all offers with first approval</key>
     </entry>
-    <entry>
-      <key>No advertising</key>
-    </entry>
     <entry>
       <key>[TEST] Importer</key>
     </entry>
@@ -8743,6 +8740,9 @@
     <entry>
       <key>Exclude existing workflows</key>
     </entry>
+    <entry>
+      <key>Interest (subscribed)</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
   <sqlModels>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index 22bff7f58f..897fbeb0ca 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -66,10 +66,18 @@
       <key>The max participants count can not be equal or less then 0</key>
       <value>Die maximale Teilnehmerzahl muss größer 0 sein!</value>
     </entry>
+    <entry>
+      <key>Communication Setting: %0</key>
+      <value>Werbeeinstellung: %0</value>
+    </entry>
     <entry>
       <key>No advertising</key>
       <value>Keine Werbung</value>
     </entry>
+    <entry>
+      <key>Interest (subscribed)</key>
+      <value>Interesse (abonniert)</value>
+    </entry>
     <entry>
       <key>Value is too small, the minimum is %0</key>
       <value>Wert ist zu klein, das Minimum ist %0</value>
@@ -552,8 +560,8 @@
       <value>Weitere Versionen</value>
     </entry>
     <entry>
-      <key>Remove recipients with advertising ban</key>
-      <value>Empfänger mit Werbesperre entfernen</value>
+      <key>Remove recipients with communication rejection</key>
+      <value>Empfänger mit Werbeablehnung entfernen</value>
     </entry>
     <entry>
       <key>Company group</key>
@@ -1764,6 +1772,10 @@
       <key>Conditions</key>
       <value>Konditionen</value>
     </entry>
+    <entry>
+      <key>Received Bulk Mail</key>
+      <value>Empfangene Serienmail</value>
+    </entry>
     <entry>
       <key>Standard</key>
       <value>Standard</value>
@@ -2407,6 +2419,10 @@
       <key>Social</key>
       <value>Sozial</value>
     </entry>
+    <entry>
+      <key>Campaign participation</key>
+      <value>Kampagnenteilnahme</value>
+    </entry>
     <entry>
       <key>Facebook Feed</key>
       <value>Facebook Feed</value>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 67f5544e63..84471325d6 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -8717,9 +8717,6 @@
     <entry>
       <key>show all offers with first approval</key>
     </entry>
-    <entry>
-      <key>No advertising</key>
-    </entry>
     <entry>
       <key>[TEST] Importer</key>
     </entry>
@@ -8828,6 +8825,9 @@
     <entry>
       <key>Exclude existing workflows</key>
     </entry>
+    <entry>
+      <key>Interest (subscribed)</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonContext/BulkMail/BulkMail.aod b/neonContext/BulkMail/BulkMail.aod
index f87a16ce60..44a1246a9b 100644
--- a/neonContext/BulkMail/BulkMail.aod
+++ b/neonContext/BulkMail/BulkMail.aod
@@ -7,6 +7,7 @@
   <filterView>BulkMailFilter_view</filterView>
   <editView>BulkMailEdit_view</editView>
   <previewView>BulkMailPreview_view</previewView>
+  <lookupView>BulkMailLookup_view</lookupView>
   <entity>BulkMail_entity</entity>
   <references>
     <neonViewReference>
@@ -29,5 +30,9 @@
       <name>6b057fb0-94ac-4bca-88b2-c97fdfcf9d6e</name>
       <view>BulkMailContent_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>9bedd7f4-86ff-432c-b8e2-2ccd14f48990</name>
+      <view>BulkMailLookup_view</view>
+    </neonViewReference>
   </references>
 </neonContext>
diff --git a/neonView/BulkMailLookup_view/BulkMailLookup_view.aod b/neonView/BulkMailLookup_view/BulkMailLookup_view.aod
new file mode 100644
index 0000000000..692f84cd89
--- /dev/null
+++ b/neonView/BulkMailLookup_view/BulkMailLookup_view.aod
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.8">
+  <name>BulkMailLookup_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <tableViewTemplate>
+      <name>Table</name>
+      <columns>
+        <neonTableColumn>
+          <name>b7351c02-5be4-4dd5-a5c2-802b47005015</name>
+          <entityField>ICON</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>9eed19a1-b7a9-4e67-a36c-c80dcbb2b94c</name>
+          <entityField>NAME</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>d098798c-c05c-4445-95f7-f1d4bbcb0878</name>
+          <entityField>SUBJECT</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>33d6ca40-ad13-4584-834f-35a08c01e339</name>
+          <entityField>STATUS</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>f657749a-31c2-43d6-90ae-663c3462b4b1</name>
+          <entityField>DESCRIPTION</entityField>
+        </neonTableColumn>
+      </columns>
+    </tableViewTemplate>
+  </children>
+</neonView>
diff --git a/process/MarketingCondition_lib/process.js b/process/MarketingCondition_lib/process.js
index daad96cdd6..bbabd0e7ce 100644
--- a/process/MarketingCondition_lib/process.js
+++ b/process/MarketingCondition_lib/process.js
@@ -117,6 +117,12 @@ CommunicationSettingsCondition.prototype.pending = function ()
     return this;
 }
 
+CommunicationSettingsCondition.prototype.status = function (pStatus)
+{
+    this._settingStatus = pStatus;
+    return this;
+}
+
 /**
  * Builds a sub select for fetching the communication settings with the properies as configured.
  * 
-- 
GitLab