Matching rules with apex salesforce

De-Dupe - 
                 Before going to implement dedupe logic using batch apex or regular apex, make sure we need to create matching rules with certain criteria and duplicate rules for same.

Example Here you go -

               Now implemet the actual logic from trigger or apex class based on your requirement. I am going to test the same stuf using developer console on lead object.

Apex Code & Trigger Snippet -

trigger Dedupe_Trg on Lead (after insert) {
   
    public static List<lead> leadIds = new List<lead>();
    public static String query;  
    if(Trigger.isAfter && Trigger.isInsert){
        for(Lead l : trigger.newMap.Values()){
            if(l.status=='Pre-Prospect' && l.dedupe__c=='dedupe'){
                leadIds.add(l);
        }
    }          
    if(!leadIds.isEmpty()){
       String ids = getLeadIdsString(leadIds);
       if(String.isNotBlank(ids)){
           query = 'select id';
           for(Schema.FieldSetMember fld :SObjectType.Lead.FieldSets.DedupeFiedSet.getFields()) {
                query+= ', ' + fld.getFieldPath();
            }
            query+= ' from lead WHERE ID in ('+ ids +')';
       }
    }  
    if(String.isNotBlank(query)){
        Database.executeBatch(new Lead_Deduper(query));
    }
   }
   public static String getLeadIdsString(List<Lead> input){
        String result = '';      
        for (Lead l: input){          
            result = result + '\'' + l.Id + '\',';
            system.debug('result first------'+result);
        }
        result = result.substring(0, result.length()-1);
        system.debug('result Second------'+result);
        return result;
    }    
}
----------------------------------------

global class Lead_Deduper implements Database.Batchable < sObject > {
    //@Class level variable declaration here
    global String query;
    global List<sObject> tempMatchRecordId;
   
    //@Method: Constructor for getting query string from trigger
    global Lead_Deduper(String query){
        this.query = query;
    }
    //@Method: Start method for fetching records from query
    global Database.QueryLocator start(Database.BatchableContext info) {
        return Database.getQueryLocator(query);
    }
    //@Method: Execute will do actual operations
    global void execute(Database.BatchableContext info, List <Lead> scope) {
        for(Lead l : scope){
            If(l.status=='Pre-Prospect'){
                l.status='New Prospect';
                l.Dedupe__c= Null;
                l.Dedupe_Processing__c = True;
            }
        }
       
        scopeIdentifier(scope);
    }
    //@Method: This is responsible for gettting both existing and latest lead ids
    global static Lead getLatestExistingLead(Datacloud.MatchRecord[] matchRecords){
        Lead existingLeadId;
        for (Datacloud.MatchRecord matchRecord : matchRecords) {
            existingLeadId = (Lead)matchRecord.getRecord();
        }
        system.debug('exsting lead id ----->>>'+existingLeadId);
        return existingLeadId;
    }
    //@Method: Finish logic for sending emails
    global void finish(Database.BatchableContext info){
        system.debug('Finally i am success...');
    }
    //@Method: This method will identify the duplicate records based on new record using datacloud namespace classes and matching rules defined in the system
    global static void scopeIdentifier(List<Lead> scope){
        // Optionally, set DML options here, use “DML” instead of “false”
        //   in the insert()
        // Database.DMLOptions dml = new Database.DMLOptions();
        // dml.DuplicateRuleHeader.allowSave = true;
        // dml.DuplicateRuleHeader.runAsCurrentUser = true;
        Database.SaveResult[] saveResult  = Database.Update(scope,false);
        Map <Id,Id> duplicateLeadIds = new Map <ID,ID> ();
        Integer i=0;
        for (Database.SaveResult sr: saveResult){
        if (sr.isSuccess()){
            scope.remove(i);
        }else{
            for (Database.Error error: sr.getErrors()){
                // If there are duplicates, an error occurs
                // Process only duplicates and not other errors
                // (e.g., validation errors)
                if (error instanceof Database.DuplicateError){
                    // Handle the duplicate error by first casting it as a
                    // DuplicateError class
                    // This lets you use methods of that class
                    // (e.g., getDuplicateResult())
                    Database.DuplicateError duplicateError = (Database.DuplicateError) error;
                    Datacloud.DuplicateResult duplicateResult = duplicateError.getDuplicateResult();
                    // Return only match results of matching rules that
                    // find duplicate records
                    Datacloud.MatchResult[] matchResults = duplicateResult.getMatchResults();
                    // Just grab first match result (which contains the
                    // duplicate record found and other match info)
                    Datacloud.MatchResult matchResult = matchResults[0];
                    Datacloud.MatchRecord[] matchRecords = matchResult.getMatchRecords();
                    Lead existingLead = getLatestExistingLead(matchRecords);
                    duplicateLeadIds.put(scope.get(i).Id,existingLead.Id);
                }else {
                }
            }
            i++;
            }
        }
        List<Suppressed_Lead__c > suppressList = new List<Suppressed_Lead__c>();
        // Add matched record to the duplicate records variable
        for(Lead led : scope){
            led.status = 'Inactive';
            led.Dedupe_Processing__c = false;
            led.Active_Lead_Id_Reason__c = 'https://mysalesproductforce-dev-ed.my.salesforce.com/'+duplicateLeadIds.get(led.id);
            led.Supperession_Reason__c = 'Duplicate lead has been found with same email or customer name';
            Suppressed_Lead__c sup = new Suppressed_Lead__c(Active_Lead__c=led.id,Suppressed_Lead__c=duplicateLeadIds.get(led.id),Description__c=led.description);          
            suppressList.add(sup);
        }
        Database.update(scope,false);
        Map<string,string> queueDetailsUpdate = getQueueDetails(scope);
        for(lead l : scope){
            l.ownerId = queueDetailsUpdate.get(l.country__c);
        }
        Database.update(scope,false);
        if(!suppressList.isEmpty()){
            Database.insert(suppressList,false);
        }
        //List<Lead> leads = [select id,firstname,leadsource,Active_Lead_Id_Reason__c,annualrevenue ,Supperession_Reason__c,lastname,email,description,company,Dedupe__c,Dedupe_Processing__c,status from lead WHERE ID IN : scope];
        String queryString = 'select id';
        //Getting fields from fieldset from lead object
        for(Schema.FieldSetMember fld :SObjectType.Lead.FieldSets.DedupeFiedSet.getFields()) {
            queryString+= ', ' + fld.getFieldPath();
        }
        queryString+= ' from lead WHERE  ID IN : scope ';
       
        //@Response : Creating new response record based on lead information        
        List<Response__c> resp = createResponse(Database.query(queryString));
        system.debug(resp);
        if(resp!=Null && !resp.isEmpty()){
            insert resp;
            system.debug(resp[0].id);
        }      
    }
    //@Method: Create one dummy response using lead details and tagged under the same lead id
    global static List<Response__c> createResponse(List<Lead> scope){
        List<Response__c> response = new List<Response__c>();
        for(Lead l : scope){
            Response__c r = new Response__c();
                r.name = system.now()+'-'+l.firstname+' '+l.lastname;
                r.Is_Suppressed__c = true;
                r.Lead__c = l.id;
                r.Revenue__c = l.annualrevenue;
                r.Description__c = l.Description;
                r.Source__c = l.leadsource;
            response.add(r);
            system.debug(response);
        }
        return response;
    }
    //@Method: This method is reposible for getting Queue name based on country name from lead record
    global static Map<String,string> getQueueDetails(List<Lead> scope){
        Set<String> queueName = new Set<String>();
        Map<String,string> queueMap = new Map<String,string>();
        for(Lead sc : scope){
            if(sc.country__c != Null){
                queueName.add(sc.Country__c);
            }          
        }
        for(QueueSobject q : [Select Id, QueueId, Queue.Name, SobjectType from QueueSobject where queue.name=:queueName]){
            queueMap.put(q.queue.name,q.queueid);
        }
        return queueMap;
    }  
}

No comments:

Featured

What is Cryptography in salesforce and what are all the algorithms provided by them ?

A). It is a security protocal between two systems. Lets say we are integration two systems without any encrytion mechanism then hackers wil...

Popular