diff --git a/entity/CampaignPlanning_entity/recordcontainers/jditorecordcontainer/onDelete.js b/entity/CampaignPlanning_entity/recordcontainers/jditorecordcontainer/onDelete.js index 0bfb4a162b77ca300d0c33fb8a73e83c4095135b..8daa120a4c1da42852657cb6a7865e0a51bfbfb0 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 c693832d8e3fad0d122698e5320c4248edf4735f..295493d78e809e8e6e55e99285ad4716cc28a105 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 456a0f924d264e5a23ccc34d0716ea581b270b41..07fc1f2dff683afef6d01cd6067930a8c8a47cd1 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 0000000000000000000000000000000000000000..32b8c7a5734ea01291f8beec4262d7bc3488869e --- /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 c0a6d7fe20f6dd0caced42a0d3e84175246b5272..896c64c1cb924c5334af96b9bf671869ba77a255 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 0000000000000000000000000000000000000000..63fddf359f2eb4b0a04887c8a9d30b55fe88d179 --- /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 0000000000000000000000000000000000000000..6351f476b874b054df0d237856615bdb8ecc2f1b --- /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 f11e641ac15873f08289b4ea3cac23dc397ee48c..8baa7234be79b6c98716ac049fa1355747a24d95 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 a2a3e3a443b5da3cb138567b08ca4c5f940c79c9..b502eae91e03951bbdba32ce115cfbbd799f40e0 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 0000000000000000000000000000000000000000..517d55822d0c5276183daef2f41fc8dcfd0b3e58 --- /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 0000000000000000000000000000000000000000..68a0694645c086c652eb10ed12720998b4146cad --- /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 0000000000000000000000000000000000000000..daed36607e029adb9fd456d551c6e81c506d9480 --- /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 0000000000000000000000000000000000000000..d3bd35e20196092d94e713892060a728a2a618fa --- /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 0000000000000000000000000000000000000000..6be9b7dc0bec4faae14d54827ce1dc99499fbaa0 --- /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 0000000000000000000000000000000000000000..e781fb72fd248164b8b63a98008094744aee7460 --- /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 0000000000000000000000000000000000000000..afaaa47d8ac7882a6771d63393f8adf0cd04a854 --- /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 0e4d59044e0e7deeb430491c96d6ef3b3c0e9c04..821415ae694dd9c3d98a7703f4c59b81a37f524b 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 18a872ec6ccf09bd82d7f9aa02522a88729516c4..4b05025f1c3027e68cca59e6ca7d1c971d1f9ee2 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 3e1b8e0b2afa639de608f618d662ea3ab658e53b..364d24387465fffab727ed9de8a8be10524e2db5 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 0000000000000000000000000000000000000000..821415ae694dd9c3d98a7703f4c59b81a37f524b --- /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 0000000000000000000000000000000000000000..8fccd9a7e20bf5ab2fb1982a956d9e3c475ec5ff --- /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 1e01a572a98104737bba1f2dae71fb293de8230c..8e2ffcbd3918fe9aa384c329025074d480dca3ce 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 076e0574da76ac6f7d6e6507290b3ab6d2eeac07..c7a61be27f95986b142015c0036bbeb9c7c64a21 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 6e773b6b1b876b37e8075be92394dd08d47aec89..bb07b870b84227ef3b232c1ba15d3af1293dbe21 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 dc8935925a5953e1bcba7a4bc7905a09ef5fc9cc..b880baca435a35ce787ebff949c3d007427a8c4e 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 995dc98ce19936dcb11559c190654eef5549ca6e..c0bb9039a11fc7901825602bbdade21c33cddda7 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 02cd976b495963ecbced53bf9bca6b0da3e04b07..fad806a3449fa26c917b8907cb59484996199556 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 0a2af60fd9cf8c4b0c0c40d6fc14538cfd315343..b0f7f6736cd69e3d99fc5e486d4287c6eefde2cb 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; }