0

I am working on a batch class to merge two accounts if they have the same website,EIn and phone number. I did a code and tested with accounts having same EIN same phone number and same website and it is getting merged but when I add the same EIN different phone numbers and website then also it gets merged. (NB:I have given condition only for the EIN).

Code:

global class deDuplicateRecords implements Database.Batchable<sObject> {
    
    public String queryString;
    global Database.QueryLocator start(Database.BatchableContext BC) {
        queryString = 'SELECT EIN__c,phone,website FROM Account WHERE EIN__c != null';
        // system.debug(queryString);
        return Database.getQueryLocator(queryString);
    }
    global void execute(Database.BatchableContext BC, List<Account> acc) {
        
        Map<String,List<Account>> AccountMap = new Map<String,List<Account>>();
        Set<String> Ein = new Set<String>();
        Set<String> Phone=new Set<String>();
        Set<String> Website=new Set<String>();
        for(Account a :acc){
            if(a.Ein__c!= null)
            {
                Ein.add(a.Ein__c);
                
            }
        }
        String sobjectApiName = 'Account';
        Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        Map<String, Schema.SObjectField> fieldMap = schemaMap.get(SobjectApiName).getDescribe().fields.getMap();
        List<String> fieleList = new List<String>();
         List<Account> mergeList;
        for(String fieldName : fieldMap.keySet()){
            Schema.DescribeFieldResult fieldResult = fieldMap.get(fieldName).getDescribe();
            if(!fieldResult.isCalculated() && fieldResult.isCreateable() && !fieldResult.isExternalId() ){
                fieleList.add(fieldName);
            }
        }
        
        String fetchFields = 'SELECT '+String.join(fieleList,',')+' FROM '+sobjectApiName+' WHERE EIN__c IN :Ein ORDER BY CreatedDate DESC ';
        integer i = 1;
        for(Account a : Database.query(fetchFields)){
            String key = a.Ein__c;
            key = key.toLowerCase();
            System.debug('key'+key);
            if(AccountMap.containsKey(key)){
                AccountMap.get(key).add(a);
            }else {
                AccountMap.put(key,new List<Account>{a});
            }
            i++;
        }
       
        
        for(String key : AccountMap.keySet()){

            if(AccountMap.get(key).size()>1 && AccountMap.get(key).size() <4){
                mergeList = new List<Account>();
                Account masterAcc = AccountMap.get(key)[0];
                mergeList.addAll(AccountMap.get(key));
                mergeList.remove(0);
                
                for(Account a : mergeList){
                    Database.MergeResult mergeResult = Database.merge(masterAcc, a, true);
                }
            }
        }
        
        
    }
    
    global void finish(Database.BatchableContext BC) {
        
    }
}

Here I have given only the EIn as key now but earlier I tried concatinating with the website and phone number and tried that way but it isnt merging then also. Also is this the ideal way because I feel there are some limiations this way.

1 Answer 1

0

I did a code and tested with accounts having same EIN same phone number and same website and it is getting merged but when I add the same EIN different phone numbers and website then also it gets merged.

That's exactly what your code specifies to do:

        for(Account a : Database.query(fetchFields)){
            String key = a.Ein__c;
            key = key.toLowerCase();
            System.debug('key'+key);
            if(AccountMap.containsKey(key)){
                AccountMap.get(key).add(a);
            }else {
                AccountMap.put(key,new List<Account>{a});
               
            i++;
        }

You identify merge candidates by Ein__c only. If you wish to locate records by multiple criteria here, you'll need a composite key. Here's an example from the inimitable sfdcfox of how to use sObject instances to do that. (Note that you'll have to, as in the linked example, construct sObject instances, since your queried data contains other fields than the ones you need to use as keys).

1
  • I understood the concept but how do I apply this in my case?
    – user121495
    Sep 12, 2022 at 14:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .