From 5fdad2a8f4391474c5d298116f33541263ca4aca Mon Sep 17 00:00:00 2001
From: "d.buechler" <d.buechler@adito.de>
Date: Tue, 27 Aug 2019 09:59:55 +0200
Subject: [PATCH] =?UTF-8?q?Aktionen=20in=20der=20Dublettenansicht=20einer?=
 =?UTF-8?q?=20Organisation=20wurden=20entsprechend=20dem=20Person=20pendan?=
 =?UTF-8?q?t=20eingef=C3=BCgt=20und=20angepasst=20Organisationsdubletten?=
 =?UTF-8?q?=20werden=20=20nun=20als=20zus=C3=A4tzlicher=20Reiter=20in=20de?=
 =?UTF-8?q?r=20Org-Mainview=20angezeigt=20Der=20Organisation=20Recordconta?=
 =?UTF-8?q?iner=20wurde=20um=20die=20Duplicate-Teile=20erweitert=20Duplica?=
 =?UTF-8?q?tes=20lib=20Funktion=20refactored?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Organisation_entity.aod                   | 78 +++++++++++++++++++
 .../ignoreduplicate/onActionProcess.js        | 10 +++
 .../children/ignoreduplicate/stateProcess.js  | 11 +++
 .../ignorewholecluster/onActionProcess.js     | 21 +++++
 .../ignorewholecluster/stateProcess.js        | 11 +++
 .../onActionProcess.js                        | 14 ++++
 .../stateProcess.js                           | 11 +++
 .../onActionProcess.js                        | 16 ++++
 .../stateProcess.js                           | 11 +++
 .../duplicateactions/stateProcess.js          | 11 +++
 .../valueProcess.js                           |  2 +
 .../valueProcess.js                           |  3 +
 .../onlyshowcontactids_param/valueProcess.js  | 18 +++++
 .../recordcontainers/db/conditionProcess.js   | 18 ++++-
 .../recordcontainers/db/onDBDelete.js         |  5 ++
 .../valueProcess.js                           |  2 +-
 .../recordcontainers/db/conditionProcess.js   |  2 +-
 .../OrganisationFilter_view.aod               |  1 +
 .../OrganisationMain_view.aod                 |  6 +-
 process/DuplicateScanner_lib/process.js       | 30 ++++---
 20 files changed, 263 insertions(+), 18 deletions(-)
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/onActionProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/stateProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/onActionProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/stateProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/onActionProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/stateProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/onActionProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/stateProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/duplicateactions/stateProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicateactionscontrol_param/valueProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicatecurrentcontactid_param/valueProcess.js
 create mode 100644 entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/onlyshowcontactids_param/valueProcess.js
 create mode 100644 entity/Organisation_entity/recordcontainers/db/onDBDelete.js

diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod
index 630891416a4..007d05af09f 100644
--- a/entity/Organisation_entity/Organisation_entity.aod
+++ b/entity/Organisation_entity/Organisation_entity.aod
@@ -934,6 +934,83 @@
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityProvider>
+      <name>SelfDuplicatesProvider</name>
+      <titlePlural>Duplicates</titlePlural>
+    </entityProvider>
+    <entityConsumer>
+      <name>SelfDuplicatesConsumer</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Organisation_entity</entityName>
+        <fieldName>SelfDuplicatesProvider</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>OnlyShowContactIds_param</name>
+          <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/onlyshowcontactids_param/valueProcess.js</valueProcess>
+        </entityParameter>
+        <entityParameter>
+          <name>DuplicateCurrentContactId_param</name>
+          <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicatecurrentcontactid_param/valueProcess.js</valueProcess>
+        </entityParameter>
+        <entityParameter>
+          <name>DuplicateActionsControl_param</name>
+          <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicateactionscontrol_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityParameter>
+      <name>OnlyShowContactIds_param</name>
+      <expose v="true" />
+    </entityParameter>
+    <entityParameter>
+      <name>DuplicateActionsControl_param</name>
+      <expose v="true" />
+    </entityParameter>
+    <entityParameter>
+      <name>DuplicateCurrentContactId_param</name>
+      <expose v="true" />
+    </entityParameter>
+    <entityActionGroup>
+      <name>DuplicateActions</name>
+      <title>Duplicate actions</title>
+      <state>AUTO</state>
+      <stateProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/stateProcess.js</stateProcess>
+      <children>
+        <entityActionField>
+          <name>IntegrateSelectedIntoCurrentAction</name>
+          <title>Integrate selected into current contact</title>
+          <onActionProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/onActionProcess.js</onActionProcess>
+          <isSelectionAction v="true" />
+          <iconId>NEON:IMPORT</iconId>
+          <stateProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/stateProcess.js</stateProcess>
+        </entityActionField>
+        <entityActionField>
+          <name>IntegrateCurrentIntoSelectedAction</name>
+          <title>Integrate current into selected contact</title>
+          <onActionProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/onActionProcess.js</onActionProcess>
+          <isSelectionAction v="true" />
+          <iconId>NEON:EXPORT</iconId>
+          <stateProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/stateProcess.js</stateProcess>
+        </entityActionField>
+        <entityActionField>
+          <name>IgnoreDuplicate</name>
+          <title>Ignore Duplicate</title>
+          <onActionProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/onActionProcess.js</onActionProcess>
+          <isSelectionAction v="true" />
+          <iconId>VAADIN:CLOSE</iconId>
+          <stateProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/stateProcess.js</stateProcess>
+        </entityActionField>
+        <entityActionField>
+          <name>IgnoreWholeCluster</name>
+          <title>Ignore whole Cluster</title>
+          <onActionProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/onActionProcess.js</onActionProcess>
+          <iconId>VAADIN:CLOSE</iconId>
+          <stateProcess>%aditoprj%/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/stateProcess.js</stateProcess>
+        </entityActionField>
+      </children>
+    </entityActionGroup>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -943,6 +1020,7 @@
       <conditionProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/conditionProcess.js</conditionProcess>
       <orderClauseProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess>
       <onDBUpdate>%aditoprj%/entity/Organisation_entity/recordcontainers/db/onDBUpdate.js</onDBUpdate>
+      <onDBDelete>%aditoprj%/entity/Organisation_entity/recordcontainers/db/onDBDelete.js</onDBDelete>
       <linkInformation>
         <linkInformation>
           <name>5808a4a3-f2c1-4ccd-bad1-4e8a834ec7a4</name>
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/onActionProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/onActionProcess.js
new file mode 100644
index 00000000000..3debf6e5a41
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/onActionProcess.js
@@ -0,0 +1,10 @@
+import("system.neon");
+import("system.vars");
+import("DuplicateScanner_lib");
+
+let sourceContactId = vars.get("$param.DuplicateCurrentContactId_param");
+let selectedContactId = vars.get("$sys.selection");
+let clusterId = DuplicateScannerUtils.GetClusterId(sourceContactId);
+DuplicateScannerUtils.CreateUnrelatedDuplicateRelation(sourceContactId, selectedContactId, clusterId);
+
+neon.refreshAll();
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/stateProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/stateProcess.js
new file mode 100644
index 00000000000..b736eb15f5b
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/ignoreduplicate/stateProcess.js
@@ -0,0 +1,11 @@
+import("system.logging");
+import("system.vars");
+import("system.neon");
+import("system.result");
+
+//Actions to show in the duplicates view inside the persons main view
+
+let actionState = vars.get("$param.DuplicateActionsControl_param");
+
+if(actionState != null && actionState != "1")//todo replace with keyword
+    result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/onActionProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/onActionProcess.js
new file mode 100644
index 00000000000..7b3385b5bb2
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/onActionProcess.js
@@ -0,0 +1,21 @@
+import("system.logging");
+import("system.neon");
+import("system.vars");
+import("DuplicateScanner_lib");
+import("system.notification");
+
+let contactId = vars.get("$field.CONTACTID");
+let clusterId = DuplicateScannerUtils.GetClusterId(contactId);
+
+let duplicateContactIdsInClusterRay = DuplicateScannerUtils.GetCachedDuplicatesForClusterId(clusterId)
+
+if(duplicateContactIdsInClusterRay.length > 1)
+{
+    let referenceDuplicateId = duplicateContactIdsInClusterRay[0];
+    for (let i = 1; i < duplicateContactIdsInClusterRay.length; i++) 
+    {
+        DuplicateScannerUtils.CreateUnrelatedDuplicateRelation(referenceDuplicateId, duplicateContactIdsInClusterRay[i], clusterId);
+    }
+}
+
+
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/stateProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/stateProcess.js
new file mode 100644
index 00000000000..fdd913ad06b
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/ignorewholecluster/stateProcess.js
@@ -0,0 +1,11 @@
+import("system.logging");
+import("system.vars");
+import("system.neon");
+import("system.result");
+
+//Actions to show in the duplicates view inside the persons main view
+
+let actionState = vars.get("$param.DuplicateActionsControl_param");
+
+if(actionState != null && actionState != "2")//todo replace with keyword
+    result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/onActionProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/onActionProcess.js
new file mode 100644
index 00000000000..65462384c26
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/onActionProcess.js
@@ -0,0 +1,14 @@
+import("system.vars");
+import("system.neon");
+import("DuplicateScanner_lib");
+
+let sourceContactId = vars.get("$param.DuplicateCurrentContactId_param");
+let targetContactId = vars.get("$sys.selection");
+
+//todo the actual merge ought to happen in a separate view where the contact infos can be merged manually by the user.
+let mergeSuccess = DuplicateScannerUtils.MergeOrganisation(sourceContactId, targetContactId);
+
+if(mergeSuccess)
+{
+    neon.openContext("Organisation", "OrganisationMain_view", [targetContactId], neon.OPERATINGSTATE_VIEW, null)
+}
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/stateProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/stateProcess.js
new file mode 100644
index 00000000000..b736eb15f5b
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/integratecurrentintoselectedaction/stateProcess.js
@@ -0,0 +1,11 @@
+import("system.logging");
+import("system.vars");
+import("system.neon");
+import("system.result");
+
+//Actions to show in the duplicates view inside the persons main view
+
+let actionState = vars.get("$param.DuplicateActionsControl_param");
+
+if(actionState != null && actionState != "1")//todo replace with keyword
+    result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/onActionProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/onActionProcess.js
new file mode 100644
index 00000000000..85447cf5568
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/onActionProcess.js
@@ -0,0 +1,16 @@
+import("system.logging");
+import("system.vars");
+import("system.neon");
+import("DuplicateScanner_lib");
+
+let targetContactId = vars.get("$param.DuplicateCurrentContactId_param");
+let sourceContactId = vars.get("$sys.selection");
+logging.log("targetContactId -> " + targetContactId);
+logging.log("sourceContactId -> "+ sourceContactId);
+//todo the actual merge ought to happen in a separate view where the contact infos can be merged manually by the user.
+let mergeSuccess = DuplicateScannerUtils.MergeOrganisation(sourceContactId, targetContactId);
+
+if(mergeSuccess)
+{
+    neon.refreshAll();
+}
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/stateProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/stateProcess.js
new file mode 100644
index 00000000000..b736eb15f5b
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/children/integrateselectedintocurrentaction/stateProcess.js
@@ -0,0 +1,11 @@
+import("system.logging");
+import("system.vars");
+import("system.neon");
+import("system.result");
+
+//Actions to show in the duplicates view inside the persons main view
+
+let actionState = vars.get("$param.DuplicateActionsControl_param");
+
+if(actionState != null && actionState != "1")//todo replace with keyword
+    result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/duplicateactions/stateProcess.js b/entity/Organisation_entity/entityfields/duplicateactions/stateProcess.js
new file mode 100644
index 00000000000..5b8b24021dd
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/duplicateactions/stateProcess.js
@@ -0,0 +1,11 @@
+import("system.logging");
+import("system.vars");
+import("system.neon");
+import("system.result");
+
+//Actions to show in the duplicates view inside the persons main view
+
+let actionState = vars.get("$param.DuplicateActionsControl_param");
+
+if(actionState == null || actionState == "0")//todo replace with keyword
+    result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicateactionscontrol_param/valueProcess.js b/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicateactionscontrol_param/valueProcess.js
new file mode 100644
index 00000000000..81570217c3e
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicateactionscontrol_param/valueProcess.js
@@ -0,0 +1,2 @@
+import("system.result");
+result.string("1");//todo use keyword
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicatecurrentcontactid_param/valueProcess.js b/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicatecurrentcontactid_param/valueProcess.js
new file mode 100644
index 00000000000..821415ae694
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/duplicatecurrentcontactid_param/valueProcess.js
@@ -0,0 +1,3 @@
+import("system.vars");
+import("system.result");
+result.string(vars.get("$field.CONTACTID"));
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/onlyshowcontactids_param/valueProcess.js b/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/onlyshowcontactids_param/valueProcess.js
new file mode 100644
index 00000000000..0338fbaa15f
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/selfduplicatesconsumer/children/onlyshowcontactids_param/valueProcess.js
@@ -0,0 +1,18 @@
+import("system.logging");
+import("system.vars");
+import("DuplicateScanner_lib");
+import("system.result");
+
+let contactIdToCheck = vars.get("$field.CONTACTID");
+
+let duplicateIds = DuplicateScannerUtils.GetCachedDuplicatesForContactId(contactIdToCheck);
+
+/*
+ * To achieve that if there are no duplicates, no contacts should be shown and therefore returned by the 
+ * recordcontainer, an invalid id gets returned. It then is used in the conditionProcess to load the duplicates.
+ * Because of its invalidity, no records are shown.
+*/
+if(duplicateIds.length == 0)
+    result.string(JSON.stringify(["nodata"]));
+else
+    result.string(JSON.stringify(duplicateIds));
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/conditionProcess.js b/entity/Organisation_entity/recordcontainers/db/conditionProcess.js
index ddde730d661..c6b901c9309 100644
--- a/entity/Organisation_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Organisation_entity/recordcontainers/db/conditionProcess.js
@@ -5,7 +5,9 @@ import("Sql_lib");
 import("Context_lib");
 
 var cond = SqlCondition.begin();
-                            
+let alternativeCondition = "1 = 1";
+var onlyShowContactIds = JSON.parse(vars.get("$param.OnlyShowContactIds_param"));
+
 // filter privat company if it is not needed
 if (vars.getString("$param.WithPrivate_param") != "true")
     cond.andPrepare("ORGANISATION.ORGANISATIONID", "0", "# <> ?");
@@ -41,5 +43,17 @@ if (vars.exists("$param.ExcludedContactIds_param") && vars.get("$param.ExcludedC
 
 cond.andPrepareVars("ORGANISATION.KIND", "$param.OrganisationType_param");
 
+if(onlyShowContactIds != null && onlyShowContactIds.length > 0)
+{
+    let additionalCondition = SqlCondition.begin();
+    onlyShowContactIds.forEach(function(pContactId)
+    {
+        additionalCondition.orPrepare("CONTACT.CONTACTID", pContactId);
+    });
+
+    cond.andSqlCondition(additionalCondition, "1=2");
+    alternativeCondition = "1 = 2";
+}
+
 //TODO: use a preparedCondition when available #1030812 #1034026
-result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
+result.string(db.translateCondition(cond.build(alternativeCondition)));
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/onDBDelete.js b/entity/Organisation_entity/recordcontainers/db/onDBDelete.js
new file mode 100644
index 00000000000..8bc517ecf83
--- /dev/null
+++ b/entity/Organisation_entity/recordcontainers/db/onDBDelete.js
@@ -0,0 +1,5 @@
+import("system.vars");
+import("DuplicateScanner_lib");
+
+let contactId = vars.get("$field.CONTACTID");
+DuplicateScannerUtils.DeleteCachedDuplicate(contactId);
\ No newline at end of file
diff --git a/entity/Person_entity/entityfields/selfduplicates/children/duplicateactionscontrol_param/valueProcess.js b/entity/Person_entity/entityfields/selfduplicates/children/duplicateactionscontrol_param/valueProcess.js
index 985b9f8612b..81570217c3e 100644
--- a/entity/Person_entity/entityfields/selfduplicates/children/duplicateactionscontrol_param/valueProcess.js
+++ b/entity/Person_entity/entityfields/selfduplicates/children/duplicateactionscontrol_param/valueProcess.js
@@ -1,2 +1,2 @@
 import("system.result");
-result.string("1");
\ No newline at end of file
+result.string("1");//todo use keyword
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/conditionProcess.js b/entity/Person_entity/recordcontainers/db/conditionProcess.js
index 617f399b002..b982e96d3fc 100644
--- a/entity/Person_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Person_entity/recordcontainers/db/conditionProcess.js
@@ -9,7 +9,7 @@ cond.andPrepareVars("CONTACT.ORGANISATION_ID", "$param.OrgId_param")
     .andPrepareVars("PERSON.CONTACT_ID", "$param.ContactId_param");
 
 var onlyShowContactIds = JSON.parse(vars.get("$param.OnlyShowContactIds_param"));
-var additionalCondition = SqlCondition.begin();
+
 let alternativeCondition = "1 = 1";
 
 if (vars.exists("$param.ExcludedContactIds_param") && vars.get("$param.ExcludedContactIds_param"))
diff --git a/neonView/OrganisationFilter_view/OrganisationFilter_view.aod b/neonView/OrganisationFilter_view/OrganisationFilter_view.aod
index 68f25862f27..7c788a81d69 100644
--- a/neonView/OrganisationFilter_view/OrganisationFilter_view.aod
+++ b/neonView/OrganisationFilter_view/OrganisationFilter_view.aod
@@ -33,6 +33,7 @@
     <tableViewTemplate>
       <name>Organisations</name>
       <favoriteActionGroup1>campaignActionGroup</favoriteActionGroup1>
+      <favoriteActionGroup2>DuplicateActions</favoriteActionGroup2>
       <subtitleField>CUSTOMERCODE_DISPLAY_fieldGroup</subtitleField>
       <entityField>#ENTITY</entityField>
       <columns>
diff --git a/neonView/OrganisationMain_view/OrganisationMain_view.aod b/neonView/OrganisationMain_view/OrganisationMain_view.aod
index 36c146d7b2e..b7faebeb141 100644
--- a/neonView/OrganisationMain_view/OrganisationMain_view.aod
+++ b/neonView/OrganisationMain_view/OrganisationMain_view.aod
@@ -61,9 +61,9 @@
       <view>LogHistoryFilter_view</view>
     </neonViewReference>
     <neonViewReference>
-      <name>100e9c93-0d63-4dd5-94b3-b88fe24f1954</name>
-      <entityField>OrganisationDuplicates</entityField>
-      <view>DuplicatesFilter_view</view>
+      <name>cbac7602-9eba-4e5d-8617-3d0b33e55ca1</name>
+      <entityField>SelfDuplicatesConsumer</entityField>
+      <view>OrganisationFilter_view</view>
     </neonViewReference>
   </children>
 </neonView>
diff --git a/process/DuplicateScanner_lib/process.js b/process/DuplicateScanner_lib/process.js
index 1ef9a6cc053..e2deb7a14a4 100644
--- a/process/DuplicateScanner_lib/process.js
+++ b/process/DuplicateScanner_lib/process.js
@@ -29,11 +29,18 @@ DuplicateScannerUtils.ScanForDuplicates = function(pFilterName, pTargetEntity, p
     return possibleDuplicates;
 }
 
-DuplicateScannerUtils.DeleteCachedDuplicate = function(pContactId)
+/*
+ * Deletes the cached duplicate for the given id. 
+ * If there would only remains one item in the cluster after deletion, the whole cluster including the duplicate gets deleted.
+ * In this case, all records marked as unrelated duplicate will be deleted aswell.
+ * 
+ * @param {String} pDuplicateId Id of the duplicate to delete
+ */
+DuplicateScannerUtils.DeleteCachedDuplicate = function(pDuplicateId)
 {
     let query = "select count(ID), CLUSTERID from DUPLICATECLUSTERS"
-    + " where CLUSTERID = (select CLUSTERID from DUPLICATECLUSTERS where DUPLICATEID = '"+ pContactId +"')"
-    + " and DUPLICATEID != '"+ pContactId +"'"
+    + " where CLUSTERID = (select CLUSTERID from DUPLICATECLUSTERS where DUPLICATEID = '"+ pDuplicateId +"')"
+    + " and DUPLICATEID != '"+ pDuplicateId +"'"
     + " group by CLUSTERID";
 
     let coundAndClusterId = db.array(db.ROW, query);
@@ -45,22 +52,23 @@ DuplicateScannerUtils.DeleteCachedDuplicate = function(pContactId)
     //Otherwise delete just the single duplicate.
     if(countDuplicatesInClusterWithoutParameterId <= 1)
     {
-        let deleteClusterCondition = "DUPLICATECLUSTERS.CLUSTERID = '"+ clusterId +"'";
-        db.deleteData("DUPLICATECLUSTERS", pCondition);
+        let deleteStatements = [];
+        deleteStatements.push(["DUPLICATECLUSTERS", "DUPLICATECLUSTERS.CLUSTERID = '"+ clusterId +"'"]);
+        deleteStatements.push(["UNRELATEDDUPLICATES", "UNRELATEDDUPLICATES.CLUSTERID = '"+ clusterId +"'"]);
         
-        let deleteUnrelatedForClusterCondition = "UNRELATEDDUPLICATES.CLUSTERID = '"+ clusterId +"'";
-        db.deleteData("UNRELATEDDUPLICATES", pCondition);
+        db.deletes(deleteStatements);
     }
     else
     {
-        db.deleteData("DUPLICATECLUSTERS", "DUPLICATECLUSTERS.DUPLICATEID = '"+ pContactId +"'");
+        db.deleteData("DUPLICATECLUSTERS", "DUPLICATECLUSTERS.DUPLICATEID = '"+ pDuplicateId +"'");
+        //Delete all records where this duplicateId is mentioned
+        DuplicateScannerUtils.DeleteAllUnrelatedDuplicateRelations(pDuplicateId);
     }
-    DuplicateScannerUtils.DeleteAllUnrelatedDuplicateRelations(pContactId);
 }
 
 /*
- * Deletes all CLusters for the given Target Entity.
- * No unrelated-duplicate records are being deleted.
+ * Deletes all CLusters for the given target Entity.
+ * No records markes as unrelated duplicate are being deleted.
  * 
  * @return Count of deleted rows
  */
-- 
GitLab