From 9f90edfa29081e968c3ceae37d1fe77c353153cc Mon Sep 17 00:00:00 2001 From: "d.buechler" <d.buechler@adito.de> Date: Tue, 30 Jul 2019 17:30:28 +0200 Subject: [PATCH] =?UTF-8?q?Zwei=20Aktionen=20verf=C3=BCgbar,=20Integrieren?= =?UTF-8?q?:=20Selektion=20->=20Current,=20Current=20->=20Selektion=20Logi?= =?UTF-8?q?k=20zum=20erstellen=20der=20Update=20und=20Delete=20Statements?= =?UTF-8?q?=20wurde=20implementiert=20Es=20muss=20zur=20Ermittlung=20der?= =?UTF-8?q?=20Dubletten=20nun=20nicht=20mehr=20bei=20der=20Person=20die=20?= =?UTF-8?q?Personid=20dem=20Provider=20per=20Consumer=20als=20Parameter=20?= =?UTF-8?q?=C3=BCbergeben=20werden,=20sondern=20die=20Contactid=20Es=20wer?= =?UTF-8?q?den=20nun=20die=20korrekten=20Filterkonfigurationen=20zum=20Dub?= =?UTF-8?q?letten-Filter=20angezeigt=20Erste=20Integration=20der=20Dublett?= =?UTF-8?q?enermittlung=20in=20die=20Organisation.!!=20Noch=20nicht=20upge?= =?UTF-8?q?dated=20auf=20die=20neuen=20Parameter=20und=20Aktionen!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jditorecordcontainer/onDelete.js | 3 + .../recordcontainers/db/conditionProcess.js | 2 +- .../DuplicateScanConditionConfig_entity.aod | 6 +- .../dbrecordcontainer/conditionProcess.js | 7 + .../Duplicates_entity/Duplicates_entity.aod | 42 +++++- .../onActionProcess.js | 14 ++ .../onActionProcess.js | 14 ++ .../jditorecordcontainer/contentProcess.js | 7 +- .../Organisation_entity.aod | 38 +++++ .../children/filtername_param/valueProcess.js | 2 + .../recordidtoignore_param/valueProcess.js | 3 + .../resultfields_param/valueProcess.js | 3 + .../valueProcess.js | 2 + .../targetcontext_param/valueProcess.js | 2 + .../targetentity_param/valueProcess.js | 2 + .../valuestoscan_param/valueProcess.js | 12 ++ .../recordidtoignore_param/valueProcess.js | 2 +- .../resultfields_param/valueProcess.js | 2 +- .../valueProcess.js | 2 +- .../sourcecontactid_param/valueProcess.js | 3 + .../targetcontext_param/valueProcess.js | 2 + .../valuestoscan_param/valueProcess.js | 21 ++- .../_____LANGUAGE_EXTRA.aod | 3 + .../_____LANGUAGE_de/_____LANGUAGE_de.aod | 3 + .../_____LANGUAGE_en/_____LANGUAGE_en.aod | 3 + .../DuplicatesFilter_view.aod | 4 + .../OrganisationMain_view.aod | 5 + process/DuplicateScanner_lib/process.js | 141 +++++++++++++++++- 28 files changed, 324 insertions(+), 26 deletions(-) create mode 100644 entity/DuplicateScanConditionConfig_entity/recordcontainers/dbrecordcontainer/conditionProcess.js create mode 100644 entity/Duplicates_entity/entityfields/actiongroup/children/integratecurrentintoselectedaction/onActionProcess.js create mode 100644 entity/Duplicates_entity/entityfields/actiongroup/children/integrateselectedintocurrentaction/onActionProcess.js create mode 100644 entity/Organisation_entity/entityfields/organisationduplicates/children/filtername_param/valueProcess.js create mode 100644 entity/Organisation_entity/entityfields/organisationduplicates/children/recordidtoignore_param/valueProcess.js create mode 100644 entity/Organisation_entity/entityfields/organisationduplicates/children/resultfields_param/valueProcess.js create mode 100644 entity/Organisation_entity/entityfields/organisationduplicates/children/resultfieldsidfieldname_param/valueProcess.js create mode 100644 entity/Organisation_entity/entityfields/organisationduplicates/children/targetcontext_param/valueProcess.js create mode 100644 entity/Organisation_entity/entityfields/organisationduplicates/children/targetentity_param/valueProcess.js create mode 100644 entity/Organisation_entity/entityfields/organisationduplicates/children/valuestoscan_param/valueProcess.js create mode 100644 entity/Person_entity/entityfields/personduplicates/children/sourcecontactid_param/valueProcess.js create mode 100644 entity/Person_entity/entityfields/personduplicates/children/targetcontext_param/valueProcess.js diff --git a/entity/CampaignPlanning_entity/recordcontainers/jditorecordcontainer/onDelete.js b/entity/CampaignPlanning_entity/recordcontainers/jditorecordcontainer/onDelete.js index 0bfb4a162b..8daa120a4c 100644 --- a/entity/CampaignPlanning_entity/recordcontainers/jditorecordcontainer/onDelete.js +++ b/entity/CampaignPlanning_entity/recordcontainers/jditorecordcontainer/onDelete.js @@ -1,3 +1,4 @@ +import("system.neon"); import("system.vars"); import("Campaign_lib"); @@ -9,4 +10,6 @@ if(selectedElement.length > 0) CampaignUtils.deleteCampaignStepData(selectedElement[0].UID); else CampaignUtils.deleteCampaignData(selectedElement[0].UID); + //todo temporary fix for #1041096. As soon as entities.delete is available and integrated into the deletion process, this can be removed + neon.refreshAll(); } \ No newline at end of file diff --git a/entity/CampaignStep_entity/recordcontainers/db/conditionProcess.js b/entity/CampaignStep_entity/recordcontainers/db/conditionProcess.js index c693832d8e..295493d78e 100644 --- a/entity/CampaignStep_entity/recordcontainers/db/conditionProcess.js +++ b/entity/CampaignStep_entity/recordcontainers/db/conditionProcess.js @@ -1,7 +1,7 @@ import("system.vars"); import("system.result"); -if(vars.exists("$param.campaignId_param") && vars.get("$param.campaignId_param")) +if(vars.get("$param.campaignId_param")) { result.string("CAMPAIGN_ID = '" + vars.getString("$param.campaignId_param") + "'"); } diff --git a/entity/DuplicateScanConditionConfig_entity/DuplicateScanConditionConfig_entity.aod b/entity/DuplicateScanConditionConfig_entity/DuplicateScanConditionConfig_entity.aod index 456a0f924d..07fc1f2dff 100644 --- a/entity/DuplicateScanConditionConfig_entity/DuplicateScanConditionConfig_entity.aod +++ b/entity/DuplicateScanConditionConfig_entity/DuplicateScanConditionConfig_entity.aod @@ -82,19 +82,21 @@ </entityField> <entityField> <name>MAX_RESULTS_THRESHOLD</name> + <title>Max results threshold</title> </entityField> </entityFields> <recordContainers> <dbRecordContainer> <name>DBRecordContainer</name> <alias>Data_alias</alias> + <conditionProcess>%aditoprj%/entity/DuplicateScanConditionConfig_entity/recordcontainers/dbrecordcontainer/conditionProcess.js</conditionProcess> <onDBUpdate>%aditoprj%/entity/DuplicateScanConditionConfig_entity/recordcontainers/dbrecordcontainer/onDBUpdate.js</onDBUpdate> <linkInformation> <linkInformation> - <name>22217bb2-6fbf-4a7f-94f3-b200ef54c49f</name> + <name>072783b0-8914-4886-bfa3-74565db81474</name> <tableName>DUPLICATESCANCONDITIONCONFIG</tableName> <primaryKey>ID</primaryKey> - <isUIDTable v="false" /> + <isUIDTable v="true" /> <readonly v="false" /> </linkInformation> </linkInformation> diff --git a/entity/DuplicateScanConditionConfig_entity/recordcontainers/dbrecordcontainer/conditionProcess.js b/entity/DuplicateScanConditionConfig_entity/recordcontainers/dbrecordcontainer/conditionProcess.js new file mode 100644 index 0000000000..32b8c7a573 --- /dev/null +++ b/entity/DuplicateScanConditionConfig_entity/recordcontainers/dbrecordcontainer/conditionProcess.js @@ -0,0 +1,7 @@ +import("system.vars"); +import("system.result"); + +if(vars.get("$param.DuplicateScanId_param")) +{ + result.string("DUPLICATESCAN_ID = '" + vars.getString("$param.DuplicateScanId_param") + "'"); +} \ No newline at end of file diff --git a/entity/Duplicates_entity/Duplicates_entity.aod b/entity/Duplicates_entity/Duplicates_entity.aod index c0a6d7fe20..896c64c1cb 100644 --- a/entity/Duplicates_entity/Duplicates_entity.aod +++ b/entity/Duplicates_entity/Duplicates_entity.aod @@ -6,8 +6,6 @@ <entityFields> <entityProvider> <name>#PROVIDER</name> - <targetContextField>targetEntity</targetContextField> - <targetIdField>UID</targetIdField> </entityProvider> <entityParameter> <name>filterName_param</name> @@ -40,6 +38,9 @@ </entityField> <entityProvider> <name>DuplicatesProvider</name> + <targetContextField>targetContext</targetContextField> + <targetIdField>UID</targetIdField> + <titlePlural>Duplicates</titlePlural> <dependencies> <entityDependency> <name>ea8abf2a-d8b8-4f83-a68e-664b3b23d822</name> @@ -47,10 +48,16 @@ <fieldName>PersonDuplicates</fieldName> <isConsumer v="false" /> </entityDependency> + <entityDependency> + <name>4d787122-cc91-4afa-a85a-dd0265cb289e</name> + <entityName>Organisation_entity</entityName> + <fieldName>OrganisationDuplicates</fieldName> + <isConsumer v="false" /> + </entityDependency> </dependencies> </entityProvider> <entityField> - <name>targetEntity</name> + <name>targetContext</name> </entityField> <entityField> <name>UID</name> @@ -69,6 +76,33 @@ <expose v="true" /> <mandatory v="true" /> </entityParameter> + <entityParameter> + <name>targetContext_param</name> + <expose v="true" /> + <mandatory v="true" /> + </entityParameter> + <entityActionGroup> + <name>ActionGroup</name> + <children> + <entityActionField> + <name>IntegrateSelectedIntoCurrentAction</name> + <title>Integrate selected into current contact</title> + <onActionProcess>%aditoprj%/entity/Duplicates_entity/entityfields/actiongroup/children/integrateselectedintocurrentaction/onActionProcess.js</onActionProcess> + <isSelectionAction v="true" /> + </entityActionField> + <entityActionField> + <name>IntegrateCurrentIntoSelectedAction</name> + <title>Integrate current into selected contact</title> + <onActionProcess>%aditoprj%/entity/Duplicates_entity/entityfields/actiongroup/children/integratecurrentintoselectedaction/onActionProcess.js</onActionProcess> + <isSelectionAction v="true" /> + </entityActionField> + </children> + </entityActionGroup> + <entityParameter> + <name>sourceContactId_param</name> + <expose v="true" /> + <mandatory v="true" /> + </entityParameter> </entityFields> <recordContainers> <jDitoRecordContainer> @@ -80,7 +114,7 @@ <name>UID.value</name> </jDitoRecordFieldMapping> <jDitoRecordFieldMapping> - <name>targetEntity.value</name> + <name>targetContext.value</name> </jDitoRecordFieldMapping> <jDitoRecordFieldMapping> <name>VALUE1.value</name> diff --git a/entity/Duplicates_entity/entityfields/actiongroup/children/integratecurrentintoselectedaction/onActionProcess.js b/entity/Duplicates_entity/entityfields/actiongroup/children/integratecurrentintoselectedaction/onActionProcess.js new file mode 100644 index 0000000000..63fddf359f --- /dev/null +++ b/entity/Duplicates_entity/entityfields/actiongroup/children/integratecurrentintoselectedaction/onActionProcess.js @@ -0,0 +1,14 @@ +import("system.vars"); +import("system.neon"); +import("DuplicateScanner_lib"); + +let sourceContactId = vars.get("$param.sourceContactId_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.MergePerson(sourceContactId, targetContactId); + +if(mergeSuccess) +{ + neon.openContext("Person", "PersonMain_view", [targetContactId], neon.OPERATINGSTATE_VIEW, null) +} \ No newline at end of file diff --git a/entity/Duplicates_entity/entityfields/actiongroup/children/integrateselectedintocurrentaction/onActionProcess.js b/entity/Duplicates_entity/entityfields/actiongroup/children/integrateselectedintocurrentaction/onActionProcess.js new file mode 100644 index 0000000000..6351f476b8 --- /dev/null +++ b/entity/Duplicates_entity/entityfields/actiongroup/children/integrateselectedintocurrentaction/onActionProcess.js @@ -0,0 +1,14 @@ +import("system.vars"); +import("system.neon"); +import("DuplicateScanner_lib"); + +let targetContactId = vars.get("$param.sourceContactId_param"); +let sourceContactId = 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.MergePerson(sourceContactId, targetContactId); + +if(mergeSuccess) +{ + neon.refreshAll(); +} \ No newline at end of file diff --git a/entity/Duplicates_entity/recordcontainers/jditorecordcontainer/contentProcess.js b/entity/Duplicates_entity/recordcontainers/jditorecordcontainer/contentProcess.js index f11e641ac1..8baa7234be 100644 --- a/entity/Duplicates_entity/recordcontainers/jditorecordcontainer/contentProcess.js +++ b/entity/Duplicates_entity/recordcontainers/jditorecordcontainer/contentProcess.js @@ -5,6 +5,7 @@ import("system.logging"); var filterName = vars.get("$param.filterName_param"); var targetEntity = vars.get("$param.targetEntity_param"); +var targetContext = vars.get("$param.targetContext_param"); var values = JSON.parse(vars.get("$param.valuesToScan_param")); var resultFields = JSON.parse(vars.get("$param.resultFields_param")); var resultFieldsIdFieldName = vars.get("$param.resultFieldsIdFieldName_param"); @@ -25,7 +26,7 @@ var returnRay = []; logging.log("duplicates.length -> " + duplicates.length); for (i = 0; i < duplicates.length; i++) { - let newRecord = _compileSingleRecord(duplicates[i], resultFieldsIdFieldName, maxRecorValues, targetEntity); + let newRecord = _compileSingleRecord(duplicates[i], resultFieldsIdFieldName, maxRecorValues, targetContext); logging.log("newRecord -> " + newRecord); returnRay.push(newRecord); @@ -33,13 +34,13 @@ for (i = 0; i < duplicates.length; i++) result.object(returnRay); -function _compileSingleRecord(pDuplicate, pIdFieldName, maxRecordValues, pTargetEntity) +function _compileSingleRecord(pDuplicate, pIdFieldName, maxRecordValues, pTargetContext) { let newRecord = []; let recordId = pDuplicate[pIdFieldName]; newRecord.push(recordId); - newRecord.push(pTargetEntity); + newRecord.push(pTargetContext); let recordCount = 0; diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod index a2a3e3a443..b502eae91e 100644 --- a/entity/Organisation_entity/Organisation_entity.aod +++ b/entity/Organisation_entity/Organisation_entity.aod @@ -852,6 +852,44 @@ <onActionProcess>%aditoprj%/entity/Organisation_entity/entityfields/newletter/onActionProcess.js</onActionProcess> <iconId>VAADIN:ENVELOPE</iconId> </entityActionField> + <entityConsumer> + <name>OrganisationDuplicates</name> + <dependency> + <name>dependency</name> + <entityName>Duplicates_entity</entityName> + <fieldName>DuplicatesProvider</fieldName> + </dependency> + <children> + <entityParameter> + <name>filterName_param</name> + <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/organisationduplicates/children/filtername_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>recordIdToIgnore_param</name> + <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/organisationduplicates/children/recordidtoignore_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>resultFields_param</name> + <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfields_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>resultFieldsIdFieldName_param</name> + <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfieldsidfieldname_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>targetEntity_param</name> + <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/organisationduplicates/children/targetentity_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>valuesToScan_param</name> + <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/organisationduplicates/children/valuestoscan_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>targetContext_param</name> + <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/organisationduplicates/children/targetcontext_param/valueProcess.js</valueProcess> + </entityParameter> + </children> + </entityConsumer> </entityFields> <recordContainers> <dbRecordContainer> diff --git a/entity/Organisation_entity/entityfields/organisationduplicates/children/filtername_param/valueProcess.js b/entity/Organisation_entity/entityfields/organisationduplicates/children/filtername_param/valueProcess.js new file mode 100644 index 0000000000..517d55822d --- /dev/null +++ b/entity/Organisation_entity/entityfields/organisationduplicates/children/filtername_param/valueProcess.js @@ -0,0 +1,2 @@ +import("system.result"); +result.string("OrganisationDuplicates"); \ No newline at end of file diff --git a/entity/Organisation_entity/entityfields/organisationduplicates/children/recordidtoignore_param/valueProcess.js b/entity/Organisation_entity/entityfields/organisationduplicates/children/recordidtoignore_param/valueProcess.js new file mode 100644 index 0000000000..68a0694645 --- /dev/null +++ b/entity/Organisation_entity/entityfields/organisationduplicates/children/recordidtoignore_param/valueProcess.js @@ -0,0 +1,3 @@ +import("system.vars"); +import("system.result"); +result.string(vars.get("$field.ORGANISATIONID")); diff --git a/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfields_param/valueProcess.js b/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfields_param/valueProcess.js new file mode 100644 index 0000000000..daed36607e --- /dev/null +++ b/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfields_param/valueProcess.js @@ -0,0 +1,3 @@ +import("system.result"); + +result.string(JSON.stringify(["NAME", "STANDARD_PHONE_COMMUNICATION", "STANDARD_EMAIL_COMMUNICATION", "ORGANISATIONID"])); \ No newline at end of file diff --git a/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfieldsidfieldname_param/valueProcess.js b/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfieldsidfieldname_param/valueProcess.js new file mode 100644 index 0000000000..d3bd35e201 --- /dev/null +++ b/entity/Organisation_entity/entityfields/organisationduplicates/children/resultfieldsidfieldname_param/valueProcess.js @@ -0,0 +1,2 @@ +import("system.result"); +result.string("ORGANISATIONID"); \ No newline at end of file diff --git a/entity/Organisation_entity/entityfields/organisationduplicates/children/targetcontext_param/valueProcess.js b/entity/Organisation_entity/entityfields/organisationduplicates/children/targetcontext_param/valueProcess.js new file mode 100644 index 0000000000..6be9b7dc0b --- /dev/null +++ b/entity/Organisation_entity/entityfields/organisationduplicates/children/targetcontext_param/valueProcess.js @@ -0,0 +1,2 @@ +import("system.result"); +result.string("Organisation"); \ No newline at end of file diff --git a/entity/Organisation_entity/entityfields/organisationduplicates/children/targetentity_param/valueProcess.js b/entity/Organisation_entity/entityfields/organisationduplicates/children/targetentity_param/valueProcess.js new file mode 100644 index 0000000000..e781fb72fd --- /dev/null +++ b/entity/Organisation_entity/entityfields/organisationduplicates/children/targetentity_param/valueProcess.js @@ -0,0 +1,2 @@ +import("system.result"); +result.string("Organisation_entity"); \ No newline at end of file diff --git a/entity/Organisation_entity/entityfields/organisationduplicates/children/valuestoscan_param/valueProcess.js b/entity/Organisation_entity/entityfields/organisationduplicates/children/valuestoscan_param/valueProcess.js new file mode 100644 index 0000000000..afaaa47d8a --- /dev/null +++ b/entity/Organisation_entity/entityfields/organisationduplicates/children/valuestoscan_param/valueProcess.js @@ -0,0 +1,12 @@ +import("system.logging"); +import("system.result"); +import("system.vars"); + +var picture = vars.get("$field.PICTURE"); +var name = vars.get("$field.NAME"); +let status = vars.get("$field.STATUS"); +let recordId = vars.get("$field.ORGANISATIONID"); + +logging.log("picture -> " + picture); + +result.object({PICTURE: picture, NAME: name, STATUS: status, ORGANISATIONID: recordId}); \ No newline at end of file diff --git a/entity/Person_entity/entityfields/personduplicates/children/recordidtoignore_param/valueProcess.js b/entity/Person_entity/entityfields/personduplicates/children/recordidtoignore_param/valueProcess.js index 0e4d59044e..821415ae69 100644 --- a/entity/Person_entity/entityfields/personduplicates/children/recordidtoignore_param/valueProcess.js +++ b/entity/Person_entity/entityfields/personduplicates/children/recordidtoignore_param/valueProcess.js @@ -1,3 +1,3 @@ import("system.vars"); import("system.result"); -result.string(vars.get("$field.PERSONID")); \ No newline at end of file +result.string(vars.get("$field.CONTACTID")); \ No newline at end of file diff --git a/entity/Person_entity/entityfields/personduplicates/children/resultfields_param/valueProcess.js b/entity/Person_entity/entityfields/personduplicates/children/resultfields_param/valueProcess.js index 18a872ec6c..4b05025f1c 100644 --- a/entity/Person_entity/entityfields/personduplicates/children/resultfields_param/valueProcess.js +++ b/entity/Person_entity/entityfields/personduplicates/children/resultfields_param/valueProcess.js @@ -1,2 +1,2 @@ import("system.result"); -result.string(JSON.stringify(["FIRSTNAME", "LASTNAME", "PERSONID"])); \ No newline at end of file +result.string(JSON.stringify(["FIRSTNAME", "LASTNAME", "CONTACTID"])); \ No newline at end of file diff --git a/entity/Person_entity/entityfields/personduplicates/children/resultfieldsidfieldname_param/valueProcess.js b/entity/Person_entity/entityfields/personduplicates/children/resultfieldsidfieldname_param/valueProcess.js index 3e1b8e0b2a..364d243874 100644 --- a/entity/Person_entity/entityfields/personduplicates/children/resultfieldsidfieldname_param/valueProcess.js +++ b/entity/Person_entity/entityfields/personduplicates/children/resultfieldsidfieldname_param/valueProcess.js @@ -1,2 +1,2 @@ import("system.result"); -result.string("PERSONID"); \ No newline at end of file +result.string("CONTACTID"); \ No newline at end of file diff --git a/entity/Person_entity/entityfields/personduplicates/children/sourcecontactid_param/valueProcess.js b/entity/Person_entity/entityfields/personduplicates/children/sourcecontactid_param/valueProcess.js new file mode 100644 index 0000000000..821415ae69 --- /dev/null +++ b/entity/Person_entity/entityfields/personduplicates/children/sourcecontactid_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/Person_entity/entityfields/personduplicates/children/targetcontext_param/valueProcess.js b/entity/Person_entity/entityfields/personduplicates/children/targetcontext_param/valueProcess.js new file mode 100644 index 0000000000..8fccd9a7e2 --- /dev/null +++ b/entity/Person_entity/entityfields/personduplicates/children/targetcontext_param/valueProcess.js @@ -0,0 +1,2 @@ +import("system.result"); +result.string("Person"); \ No newline at end of file diff --git a/entity/Person_entity/entityfields/personduplicates/children/valuestoscan_param/valueProcess.js b/entity/Person_entity/entityfields/personduplicates/children/valuestoscan_param/valueProcess.js index 1e01a572a9..8e2ffcbd39 100644 --- a/entity/Person_entity/entityfields/personduplicates/children/valuestoscan_param/valueProcess.js +++ b/entity/Person_entity/entityfields/personduplicates/children/valuestoscan_param/valueProcess.js @@ -2,18 +2,15 @@ import("system.logging"); import("system.result"); import("system.vars"); -// var adresses = vars.get("$field.PersAddresses"); -// var organisation = vars.get("$field.ORGANISATION_NAME"); -// var organisationAdress = vars.get("$field.OrgAddresses"); -// -// logging.log("adresses -> " + adresses); -// logging.log("firstname -> " + firstname); -// logging.log("organisation -> " + organisation); -// logging.log("organisationAdress -> " + organisationAdress); - +/* + * All values to the configured filters have to be defined here. + * The same field as defined in resultFieldsIdFieldName and the respective id have to be included in the values list. + * It has to be the correct id of the target entity, which is also used to open the preview. + */ var firstname = vars.get("$field.FIRSTNAME"); var lastname = vars.get("$field.LASTNAME"); let gender = vars.get("$field.GENDER"); -let recordId = vars.get("$field.PERSONID"); - -result.object({FIRSTNAME: firstname, LASTNAME: lastname, GENDER: gender, PERSONID: recordId}); \ No newline at end of file +let recordId = vars.get("$field.CONTACTID"); + + +result.object({FIRSTNAME: firstname, LASTNAME: lastname, GENDER: gender, CONTACTID: recordId}); \ No newline at end of file diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod index 076e0574da..c7a61be27f 100644 --- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod +++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod @@ -4971,6 +4971,9 @@ <entry> <key>The combination of filter name and target entity is already in use</key> </entry> + <entry> + <key>Duplicates</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 6e773b6b1b..bb07b870b8 100644 --- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod +++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod @@ -6261,6 +6261,9 @@ <key>The combination of filter name and target entity is already in use</key> <value>Die Kombination von Filtername und Zielentity existiert bereits</value> </entry> + <entry> + <key>Duplicates</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod index dc8935925a..b880baca43 100644 --- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod +++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod @@ -5020,6 +5020,9 @@ <entry> <key>The combination of filter name and target entity is already in use</key> </entry> + <entry> + <key>Duplicates</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/neonView/DuplicatesFilter_view/DuplicatesFilter_view.aod b/neonView/DuplicatesFilter_view/DuplicatesFilter_view.aod index 995dc98ce1..c0bb9039a1 100644 --- a/neonView/DuplicatesFilter_view/DuplicatesFilter_view.aod +++ b/neonView/DuplicatesFilter_view/DuplicatesFilter_view.aod @@ -11,9 +11,13 @@ <children> <tableViewTemplate> <name>DuplicatesTable</name> + <favoriteActionGroup2>ActionGroup</favoriteActionGroup2> <entityField>#ENTITY</entityField> <isCreatable v="false" /> <isEditable v="false" /> + <isDeletable v="false" /> + <showHeader v="true" /> + <linkedFrame></linkedFrame> <columns> <neonTableColumn> <name>6d6aef18-53c9-4a43-8929-c421ea2d1889</name> diff --git a/neonView/OrganisationMain_view/OrganisationMain_view.aod b/neonView/OrganisationMain_view/OrganisationMain_view.aod index 02cd976b49..fad806a344 100644 --- a/neonView/OrganisationMain_view/OrganisationMain_view.aod +++ b/neonView/OrganisationMain_view/OrganisationMain_view.aod @@ -60,5 +60,10 @@ <entityField>LogHistoryConsumer</entityField> <view>LogHistoryFilter_view</view> </neonViewReference> + <neonViewReference> + <name>100e9c93-0d63-4dd5-94b3-b88fe24f1954</name> + <entityField>OrganisationDuplicates</entityField> + <view>DuplicatesFilter_view</view> + </neonViewReference> </children> </neonView> diff --git a/process/DuplicateScanner_lib/process.js b/process/DuplicateScanner_lib/process.js index 0a2af60fd9..b0f7f6736c 100644 --- a/process/DuplicateScanner_lib/process.js +++ b/process/DuplicateScanner_lib/process.js @@ -34,6 +34,30 @@ DuplicateScannerUtils.ScanForDuplicates = function(pFilterName, pTargetEntity, return possibleDuplicates; } +DuplicateScannerUtils.MergePerson = function(pSourceContactId, pTargetContactId) +{ + let updateStatements = []; + let deleteStatements = []; + + var sourcePersonId = db.cell("select PERSON_ID from CONTACT where CONTACTID = '" + pSourceContactId + "'"); + var tableInfos = _DuplicateScannerUtils._getMergeUpdateTableInfos(); + + updateStatements.push(_DuplicateScannerUtils._buildUpdateContactIdStatements(tableInfos, pSourceContactId, pTargetContactId)); + updateStatements.push(_DuplicateScannerUtils._buildUpdateAttachParticipantsToNewContactQuery("CAMPAIGNPARTICIPANT", "CONTACT_ID", "CAMPAIGN_ID", pSourceContactId, pTargetContactId)); + + deleteStatements.push(_DuplicateScannerUtils._buildDeleteRemoveObsoleteParticipantsRecordsQuery("CAMPAIGNPARTICIPANT", "CONTACT_ID", "CAMPAIGN_ID", pSourceContactId, pTargetContactId)); + deleteStatements = deleteStatements.concat(_DuplicateScannerUtils._buildDeletePersonAndContactQuery(sourcePersonId, pSourceContactId)); + + logging.log("updateStatements -> " + JSON.stringify(updateStatements)); + logging.log("deleteStatements -> " + JSON.stringify(deleteStatements)); + //let affectedRows = db.updates(updateStatements); + //let deletedRows = db.deletes(deleteStatements) + + return true;//(affectedRows > 0 && deletedRows >= 2); +} + + + function _DuplicateScannerUtils() {} @@ -41,6 +65,57 @@ var INDEX_FILTER_CONDITION = 0; var INDEX_COUNT_CHARS_TO_USE = 1; var INDEX_MAX_RESULTS_THRESHOLD = 2; +var INDEX_TABLE_NAME = 0; +var INDEX_COLUMN_NAME = 1; +var INDEX_CONDITION = 2; + + +/* + * All records with contactId = sourceContactId get updated, which are not assigned to the same "group" as the targetContactId. + * This is because otherwise there would now be in total two "participants" in the same "group" as opposed to one before. + * Also if they already are in the same "group" those records shouldn't be updated because it would lead to the same outcome. + * + * Mandatory: All records ignored for the time being have to be deleted aswell! See #_DuplicateScannerUtils._buildRemoveObsoleteParticipantsRecordsDeleteQuery + * + */ +_DuplicateScannerUtils._buildUpdateAttachParticipantsToNewContactQuery = function (pTableName, pContactIdColumn, pAssignableIdColumn, pSourceContactId, pTargetContactId, updateStatements) +{ + var selectAssignableIdsOfTargetContactQuery = "select " + pAssignableIdColumn + + " from " + pTableName + + " where " + pContactIdColumn + " = '" + pTargetContactId + "'"; + +//+ " ( select tab." + pAssignableIdColumn + " from (" + selectAssignableIdsOfTargetContactQuery + ")tab ) " +//+ " (select tab." + pAssignableIdColumn + " from (" + selectAssignableIdsOfTargetContactQuery + ")tab ) " + + + let updateCondition = pAssignableIdColumn + + " not in" + + " (" + selectAssignableIdsOfTargetContactQuery + ")" + + " and " + pContactIdColumn + " = '" + pSourceContactId + "'"; + + return [pTableName, [pContactIdColumn], null, [pTargetContactId], updateCondition]; +} + +_DuplicateScannerUtils._buildDeleteRemoveObsoleteParticipantsRecordsQuery = function (pTableName, pContactIdColumn, pAssignableIdColumn, pSourceContactId, pTargetContactId, updateStatements) +{ + var selectAssignableIdsOfTargetContactQuery = "select " + pAssignableIdColumn + + " from " + pTableName + + " where " + pContactIdColumn + " = '" + pTargetContactId + "'"; + + let deleteCondition = pAssignableIdColumn + " in" + + " (" + selectAssignableIdsOfTargetContactQuery + ")" + + " and " + pAssignableIdColumn + " = '" + pSourceContactId + "'"; + return [pTableName, deleteCondition]; +} + +_DuplicateScannerUtils._buildDeletePersonAndContactQuery = function(pSourcePersonId, pSourceContactId) +{ + let recordsToDelete = [] + recordsToDelete.push(["PERSON", "PERSONID = '" + pSourcePersonId + "'"]); + recordsToDelete.push(["CONTACT", "CONTACTID = '" + pSourceContactId + "'"]); + return recordsToDelete; +} + _DuplicateScannerUtils._getIgnoreRecordFilter = function(pRecordIdFieldToIgnore, pRecordIdValueToIgnore, pTargetEntity) { let ignoreFilterJson = JSON.stringify({"entity":pTargetEntity,"filter":{"type":"group","operator":"AND","childs":[{"type":"row","name":pRecordIdFieldToIgnore,"operator":"NOT_EQUAL","value":pRecordIdValueToIgnore,"key":"","contenttype":"TEXT"}]}}); @@ -48,6 +123,70 @@ _DuplicateScannerUtils._getIgnoreRecordFilter = function(pRecordIdFieldToIgnore, return [ignoreFilterJson, null, null]; } +_DuplicateScannerUtils._buildUpdateContactIdStatements = function(pTableInfos, pSourceContactId, pTargetContactId) +{ + let statements = []; + + for (let i = 0; i < pTableInfos.length; i++) + { + let tableInfo = pTableInfos[i]; + let updateStatement = _DuplicateScannerUtils._buildStatement(tableInfo, pSourceContactId, pTargetContactId); + statements.push(updateStatement); + } + return statements; +} + +_DuplicateScannerUtils._buildStatement = function(pTableinfos, pSourceContactId, pTargetContactId) +{ + let tableName = pTableinfos[INDEX_TABLE_NAME]; + let columnName = pTableinfos[INDEX_COLUMN_NAME]; + let additionalCondition = pTableinfos[INDEX_CONDITION]; + + let condition = columnName + " = '" + pSourceContactId + "'"; + + if(additionalCondition != "") + condition += " and ( " + additionalCondition + ") "; + + return [tableName, [columnName], null, [pTargetContactId], condition]; +} + +_DuplicateScannerUtils._getMergeUpdateTableInfos = function(pSourceContactId, pTargetContactId) +{ + let campaignParticipantCondition = "CAMPAIGN_ID" + + var tableInfos = new Array(); + tableInfos.push(["AB_APPOINTMENTLINK", "OBJECT_ROWID", ""]); + tableInfos.push(["AB_CTILOG", "CONTACT_ID", ""]); + //tableInfos.push(["AB_OBJECTRELATION", "??", "" + nochmal? + tableInfos.push(["HISTORY", "RESPONSIBLE", ""]); + tableInfos.push(["ADDRESS", "CONTACT_ID", ""]); + tableInfos.push(["BULKMAILRECIPIENT", "CONTACT_ID", ""]); + tableInfos.push(["CAMPAIGN", "EMPLOYEE_CONTACT_ID", ""]); + tableInfos.push(["CAMPAIGNSTEP", "EMPLOYEE_CONTACT_ID", ""]); + tableInfos.push(["COMMRESTRICTION", "CONTACT_ID", ""]); + tableInfos.push(["COMMUNICATION", "CONTACT_ID", ""]); + tableInfos.push(["COMPETITION", "CONTACT_ID", ""]); + tableInfos.push(["CONTRACT", "CONTACT_ID", ""]); + tableInfos.push(["LETTERRECIPIENT", "CONTACT_ID", ""]); + tableInfos.push(["MEMBER", "CONTACT_ID", ""]); + tableInfos.push(["OFFER", "CONTACT_ID", ""]); + tableInfos.push(["PRODUCT", "CONTACT_ID", ""]); + tableInfos.push(["PRODUCTPRICE", "CONTACT_ID", ""]); + tableInfos.push(["SALESORDER", "CONTACT_ID", ""]); + tableInfos.push(["SALESPROJECT", "CONTACT_ID", ""]); + tableInfos.push(["TASK", "REQUESTOR_CONTACT_ID", ""]); + tableInfos.push(["TASK", "EDITOR_CONTACT_ID", ""]); + tableInfos.push(["TASKLINK", "OBJECT-ROWID", ""]); + tableInfos.push(["ACTIVITY", "RESPONSIBLE", ""]); + tableInfos.push(["AB_ATTRIBUTERELATION", "OBJECT_ROWID", ""]); + + //tableInfos.push(["CAMPAIGNPARTICIPANT", "CONTACT_ID", ""]); + + return tableInfos; +} + + + /* * The pre filter is used to narrow the records to be searched by the duplicate scan service * It loads the target entity and uses filters achieve this. @@ -176,7 +315,7 @@ _DuplicateScannerUtils._insertValuesInFilterTemplate = function(pJsonRootNode, p if(fieldValue == null) { - logging.log("Duplicate Scan: Requested value for field " + fieldName + " not present in the provided valueslist"); + logging.show("Duplicate Scan: Requested value for field " + fieldName + " not present in the provided valueslist"); continue; } -- GitLab