diff --git a/entity/DuplicatesUnrelated_entity/DuplicatesUnrelated_entity.aod b/entity/DuplicatesUnrelated_entity/DuplicatesUnrelated_entity.aod index e588641673ce46d5afaf7d3d0c6ded5e19613800..a5c6ac225f1556a7439b36eadc97c5ff3527b24e 100644 --- a/entity/DuplicatesUnrelated_entity/DuplicatesUnrelated_entity.aod +++ b/entity/DuplicatesUnrelated_entity/DuplicatesUnrelated_entity.aod @@ -48,6 +48,11 @@ <expose v="true" /> <mandatory v="true" /> </entityParameter> + <entityParameter> + <name>ClusterId_param</name> + <expose v="true" /> + <mandatory v="false" /> + </entityParameter> </children> </entityProvider> <entityField> diff --git a/entity/DuplicatesUnrelated_entity/recordcontainers/jditorecordcontainer/contentProcess.js b/entity/DuplicatesUnrelated_entity/recordcontainers/jditorecordcontainer/contentProcess.js index e128ef3d64f5012b19fab4c007ef7950d2af50fc..80ea054419ae03103887f2b2437d5fef52a48dd0 100644 --- a/entity/DuplicatesUnrelated_entity/recordcontainers/jditorecordcontainer/contentProcess.js +++ b/entity/DuplicatesUnrelated_entity/recordcontainers/jditorecordcontainer/contentProcess.js @@ -7,6 +7,9 @@ var INDEX_SOURCE_INFO1 = 1; var INDEX_SOURCE_INFO2 = 2; var INDEX_UNRELATED_INFO1 = 3; var INDEX_UNRELATED_INFO2 = 4; +var INDEX_SOURCE_INFO = 1; +var INDEX_UNRELATED_INFO = 2; + let unrelatedDuplicates = []; let resultUnrelatedDuplicates = []; @@ -28,17 +31,46 @@ if(targetEntity == 'Person_entity') if(clusterId != null && clusterId != "") query += " where ud.CLUSTERID = '" + clusterId + "'"; } +else +{ + query = "select ud.ID," + + " oSource.\"NAME\"," + + " oUnrelated.\"NAME\"" + + " from UNRELATEDDUPLICATES ud" + + " join CONTACT cUnrelated on cUnrelated.CONTACTID = ud.UNRELATEDDUPLICATEID" + + " join Organisation oUnrelated on oUnrelated.ORGANISATIONID = cUnrelated.CONTACTID" + + " join CONTACT cSource on cSource.CONTACTID = ud.SOURCEDUPLICATEID" + + " join Organisation oSource on oSource.ORGANISATIONID = cSource.CONTACTID" + //If the clusterid parameter is present, only load the duplicates for this particular cluster + if(clusterId != null && clusterId != "") + query += " where ud.CLUSTERID = '" + clusterId + "'"; +} unrelatedDuplicates = db.table(query); for (let i = 0; i < unrelatedDuplicates.length; i++) { let id = unrelatedDuplicates[i][INDEX_ID]; - let sourceInfo1 = unrelatedDuplicates[i][INDEX_SOURCE_INFO1]; - let sourceInfo2 = unrelatedDuplicates[i][INDEX_SOURCE_INFO2]; - let unrelatedInfo1 = unrelatedDuplicates[i][INDEX_UNRELATED_INFO1]; - let unrelatedInfo2 = unrelatedDuplicates[i][INDEX_UNRELATED_INFO2]; + let sourceInfo = ""; + let unrelatedInfo = ""; + + if(targetEntity == 'Person_entity') + { + let sourceInfo1 = unrelatedDuplicates[i][INDEX_SOURCE_INFO1]; + let sourceInfo2 = unrelatedDuplicates[i][INDEX_SOURCE_INFO2]; + let unrelatedInfo1 = unrelatedDuplicates[i][INDEX_UNRELATED_INFO1]; + let unrelatedInfo2 = unrelatedDuplicates[i][INDEX_UNRELATED_INFO2]; + + sourceInfo = sourceInfo1 + " " + sourceInfo2; + unrelatedInfo = unrelatedInfo1 + " " + unrelatedInfo2; + } + else + { + sourceInfo = unrelatedDuplicates[i][INDEX_SOURCE_INFO]; + unrelatedInfo = unrelatedDuplicates[i][INDEX_UNRELATED_INFO]; + } + - resultUnrelatedDuplicates.push([id, sourceInfo1 + " " + sourceInfo2, unrelatedInfo1 + " " + unrelatedInfo2]); + resultUnrelatedDuplicates.push([id, sourceInfo, unrelatedInfo]); } result.object(resultUnrelatedDuplicates); \ No newline at end of file diff --git a/entity/Duplicates_entity/Duplicates_entity.aod b/entity/Duplicates_entity/Duplicates_entity.aod index fe6100f69943a8c6f1bbf6d6f6d884f0f40181b2..a9d5e70212dc19cf4f87b700779f78994019a0ae 100644 --- a/entity/Duplicates_entity/Duplicates_entity.aod +++ b/entity/Duplicates_entity/Duplicates_entity.aod @@ -123,6 +123,14 @@ </entityActionField> </children> </entityActionGroup> + <entityConsumer> + <name>DuplicatesUnrelatedOrganisationConsumer</name> + <dependency> + <name>dependency</name> + <entityName>DuplicatesUnrelated_entity</entityName> + <fieldName>UnrelatedOrganisationsProvider</fieldName> + </dependency> + </entityConsumer> </entityFields> <recordContainers> <jDitoRecordContainer> diff --git a/entity/Duplicates_entity/recordcontainers/recordcontainer/contentProcess.js b/entity/Duplicates_entity/recordcontainers/recordcontainer/contentProcess.js index b41c7170c7ff6754a70d4aedeb8ba5e8d7ca5a72..c23d673b2531f3e922167f4633a7272b8206a850 100644 --- a/entity/Duplicates_entity/recordcontainers/recordcontainer/contentProcess.js +++ b/entity/Duplicates_entity/recordcontainers/recordcontainer/contentProcess.js @@ -8,6 +8,7 @@ var INDEX_ID = 0; var INDEX_CLUSTERID = 1; var INDEX_FIRSTNAME = 2; var INDEX_LASTNAME = 3; +var INDEX_ORGNAME = 2; let targetEntity = vars.get("$param.TargetEntity"); let duplicates = []; @@ -29,8 +30,16 @@ if(targetEntity == "Person_entity") } else - duplicateInfosQuery = "orgquery"; - +{ + duplicateInfosQuery = SqlCondition.begin() + .and("DUPLICATEID not in (select UNRELATEDDUPLICATES.UNRELATEDDUPLICATEID from UNRELATEDDUPLICATES)") + .andIn("DUPLICATECLUSTERS.CLUSTERID", vars.get("$local.idvalues")) + .buildSql("select DUPLICATECLUSTERS.ID, CLUSTERID, ORGANISATION.\"NAME\"" + + " from DUPLICATECLUSTERS" + + " join CONTACT on CONTACT.CONTACTID = DUPLICATEID" + + " join ORGANISATION on ORGANISATION.ORGANISATIONID = CONTACT.CONTACTID", "1=2", " ORDER BY CLUSTERID"); +} + let duplicateInfos = db.table(duplicateInfosQuery); let recordClusterId = ""; @@ -47,7 +56,7 @@ for (let i = 0; i < duplicateInfos.length; i++) if(targetEntity == "Person_entity") currentDescription = duplicateInfos[i][INDEX_FIRSTNAME] + " " + duplicateInfos[i][INDEX_LASTNAME]; else - currentDescription = "orgfields"; + currentDescription = duplicateInfos[i][INDEX_ORGNAME]; if(i == 0) { diff --git a/neonContext/Duplicates/Duplicates.aod b/neonContext/Duplicates/Duplicates.aod index 0926349b865ec6ff75de40855a36f4a67e26e180..08035e98574bcfb9eece5b9835add8ef4ea6f2eb 100644 --- a/neonContext/Duplicates/Duplicates.aod +++ b/neonContext/Duplicates/Duplicates.aod @@ -27,5 +27,17 @@ <name>7cdb6ca7-e99d-4eb6-897a-0953157bf62f</name> <view>DuplicatesUnrelatedCluster_view</view> </neonViewReference> + <neonViewReference> + <name>4b9a1a26-e14f-4246-b474-8bfb3e3a95b0</name> + <view>OrganisationDuplicatesTab_view</view> + </neonViewReference> + <neonViewReference> + <name>f9b46eab-7417-4f61-b7cd-dc772c04ddc0</name> + <view>OrganisationDuplicatesFilter_view</view> + </neonViewReference> + <neonViewReference> + <name>d68a425a-037a-4725-8dc1-b0afac277bdd</name> + <view>OrganisationUnrelatedDuplicates_view</view> + </neonViewReference> </references> </neonContext> diff --git a/neonView/DuplicatesOverview_view/DuplicatesOverview_view.aod b/neonView/DuplicatesOverview_view/DuplicatesOverview_view.aod index cdbcf32c67c97517285f40ad0c57faf8c7b02ab5..e733c2ef89cb4125c9a886a4c3a4b25de8b4bfda 100644 --- a/neonView/DuplicatesOverview_view/DuplicatesOverview_view.aod +++ b/neonView/DuplicatesOverview_view/DuplicatesOverview_view.aod @@ -13,5 +13,10 @@ <entityField>#ENTITY</entityField> <view>PersonDublicatesTab_view</view> </neonViewReference> + <neonViewReference> + <name>8e19d057-58da-4db8-8119-ecf070af86ab</name> + <entityField>#ENTITY</entityField> + <view>OrganisationDuplicatesTab_view</view> + </neonViewReference> </children> </neonView> diff --git a/neonView/DuplicatesUnrelatedOrganisationFilter_view/DuplicatesUnrelatedOrganisationFilter_view.aod b/neonView/DuplicatesUnrelatedOrganisationFilter_view/DuplicatesUnrelatedOrganisationFilter_view.aod index 0962b89c7f08f00c9074d544465bc49470e06e84..0c2a6665e4886fb5e5ebb40ac783962b92d9304e 100644 --- a/neonView/DuplicatesUnrelatedOrganisationFilter_view/DuplicatesUnrelatedOrganisationFilter_view.aod +++ b/neonView/DuplicatesUnrelatedOrganisationFilter_view/DuplicatesUnrelatedOrganisationFilter_view.aod @@ -2,4 +2,29 @@ <neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> <name>DuplicatesUnrelatedOrganisationFilter_view</name> <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <boxLayout> + <name>layout</name> + </boxLayout> + </layout> + <children> + <tableViewTemplate> + <name>UnrelatedOrganisations</name> + <hideContentSearch v="true" /> + <entityField>#ENTITY</entityField> + <isCreatable v="false" /> + <isEditable v="false" /> + <title>Unrelated organisation duplicates</title> + <columns> + <neonTableColumn> + <name>04681f8d-b941-4a66-be50-6ac08d6f52a4</name> + <entityField>SourceDuplicateDescription</entityField> + </neonTableColumn> + <neonTableColumn> + <name>b293ed18-ebf5-474e-8ec2-851a3562b4d5</name> + <entityField>UnrelatedDuplicateDescription</entityField> + </neonTableColumn> + </columns> + </tableViewTemplate> + </children> </neonView> diff --git a/neonView/OrganisationDuplicatesFilter_view/OrganisationDuplicatesFilter_view.aod b/neonView/OrganisationDuplicatesFilter_view/OrganisationDuplicatesFilter_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..6579ac0f55fe9cb61bc555ab09d46d2b136ae0ec --- /dev/null +++ b/neonView/OrganisationDuplicatesFilter_view/OrganisationDuplicatesFilter_view.aod @@ -0,0 +1,31 @@ +<?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.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> + <name>OrganisationDuplicatesFilter_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <boxLayout> + <name>layout</name> + </boxLayout> + </layout> + <children> + <tableViewTemplate> + <name>OrganisationDuplicatesTable</name> + <favoriteActionGroup2>DuplicateClusterActionGroup</favoriteActionGroup2> + <hideContentSearch v="true" /> + <entityField>#ENTITY</entityField> + <isCreatable v="false" /> + <isEditable v="false" /> + <isDeletable v="false" /> + <columns> + <neonTableColumn> + <name>ebe8d904-449c-49bd-915c-5b4fee894bc2</name> + <entityField>CLUSTER_DESCRIPTION</entityField> + </neonTableColumn> + <neonTableColumn> + <name>48db4335-6bdb-4a6a-809e-f9c371733f85</name> + <entityField>COUNT_DUPLICATES_IN_CLUSTER</entityField> + </neonTableColumn> + </columns> + </tableViewTemplate> + </children> +</neonView> diff --git a/neonView/OrganisationDuplicatesTab_view/OrganisationDuplicatesTab_view.aod b/neonView/OrganisationDuplicatesTab_view/OrganisationDuplicatesTab_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..601b065b7aa13aa9f35194381a3cfbe4cf07a3d5 --- /dev/null +++ b/neonView/OrganisationDuplicatesTab_view/OrganisationDuplicatesTab_view.aod @@ -0,0 +1,24 @@ +<?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.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> + <name>OrganisationDuplicatesTab_view</name> + <title>Organisation duplicates</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <boxLayout> + <name>layout</name> + <direction>HORIZONTAL</direction> + </boxLayout> + </layout> + <children> + <neonViewReference> + <name>8b4ab951-afb3-4fac-915b-89226ab2f849</name> + <entityField>SelfOrganisationDuplicatesConsumer</entityField> + <view>OrganisationDuplicatesFilter_view</view> + </neonViewReference> + <neonViewReference> + <name>d1e2ba4a-a5d6-4bba-a646-5918490e43a4</name> + <entityField>#ENTITY</entityField> + <view>OrganisationUnrelatedDuplicates_view</view> + </neonViewReference> + </children> +</neonView> diff --git a/neonView/OrganisationUnrelatedDuplicates_view/OrganisationUnrelatedDuplicates_view.aod b/neonView/OrganisationUnrelatedDuplicates_view/OrganisationUnrelatedDuplicates_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..80177f02af3fc1d0b3ac71125ec445feed22d66b --- /dev/null +++ b/neonView/OrganisationUnrelatedDuplicates_view/OrganisationUnrelatedDuplicates_view.aod @@ -0,0 +1,17 @@ +<?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.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> + <name>OrganisationUnrelatedDuplicates_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <boxLayout> + <name>layout</name> + </boxLayout> + </layout> + <children> + <neonViewReference> + <name>edc0822d-4388-4e3d-93d7-2e46e32f5742</name> + <entityField>DuplicatesUnrelatedOrganisationConsumer</entityField> + <view>DuplicatesUnrelatedOrganisationFilter_view</view> + </neonViewReference> + </children> +</neonView> diff --git a/process/RebuildDuplicatesCache_serverProcess/process.js b/process/RebuildDuplicatesCache_serverProcess/process.js index d7ee47f9636e9db46a82c9afe9590e13c32d9931..c8efbfd89c72c4dd2705d45e6a79bacbc78d41bd 100644 --- a/process/RebuildDuplicatesCache_serverProcess/process.js +++ b/process/RebuildDuplicatesCache_serverProcess/process.js @@ -1,7 +1,25 @@ import("DuplicateScanner_lib"); - -// Build Organisation duplicate cache +/* + * Serverprocess to reload duplicates + * It is dividede by the filter and their respective target entities. + * + * Step #1: + * All Clusters for the specified targetEntity are deleted. + * Relations between records marked as unrelated are not deleted at this moment + * Step #2 + * The duplicates cache gets rebuilt + * + * Step #3: + * All unrelated relations between duplicate ids hold their respective cluster id + * If the same combination of duplicate ids exists in the duplicate cache after the rebuild, + * it is assumed that those records remain duplicates. + * Therefore the saved clusterId gets refreshed with the newly created clusters id. + * + * Relations between unrelated duplicates are deleted, if no cluster contains the same combination of duplicate ids + */ + +// Build Person duplicate cache var filterName = "PersonDuplicates"; var targetEntity = "Person_entity";