Best approach for integrating Converted Leadswith External Ids

Whats the best process for converting leads with external ids?

I have an integration where I need to convert leads. The conversion needs to happen on an external id. I can’t pass in the Salesforce id, that would be too easy. The best thing I’ve thought of is to write a webservice that takes a list of lead external ids, creates Database.LeadConvert objects for all the relevant, non converted leads, and then converts them.

This comes at a price though: If I convert leads in the same list, under the same account, I get a “Duplicate Id list” exception thrown.

Here’s a code snippet of the web service:

List<Database.LeadConvert> leadConversions = new List<Database.LeadConvert>();
    for(Lead l : 
        [Select 
            Id,
            External_Id__c,
            Contact__r.AccountId 
         From 
            Lead 
         Where 
            External_Id__c in :externalIds 
            and External_Id__c != null 
            and IsConverted=false
         Limit 100]){
        Database.LeadConvert lc = new Database.LeadConvert();
        lc.setAccountId(l.Contact__r.AccountId);
        lc.setContactId(l.Contact__r.Id);
        lc.setLeadId(l.Id);
        lc.setDoNotCreateOpportunity(true);
        lc.setConvertedStatus(status);
        leadConversions.add(lc);                
        leadExternalIds.add(l.External_Id__c);
    }

List<LeadConversionResult> lcr = new List<LeadConversionResult>();
Integer i=0;
for(Database.LeadConvertResult r : Database.convertLead(leadConversions,false)){
    lcr.add(
        new LeadConversionResult(
            r.isSuccess(),
            r.getErrors().isEmpty() ? null : r.getErrors().get(0).getMessage(),
            leadExternalIds.get(i++)
        )
    );
}

There is a soap convertLead call I can make, and that DOES handle leads under the same account properly. However, it only takes an Id instead of also external ids. Is there a best practice approach for integrating lead conversions like this, or am I on the right track?

Answer

Seems like you’re pretty close, just need to break up Leads with the same accountId into different batches. You’ll want to do some data analysis to see what your worst case scenario is for the number of leads related to the same account and ensure that you won’t exceed the max number of DML statements.

Example

Map<Id, List<Database.LeadConvert>> leadConvertMap = new Map<Id, List<Database.LeadConvert>();
for(Lead l : [
  ... query ...
]) {
  Database.LeadConvert lc = new Database.LeadConvert();
  ... set lead convert params ...

  // organize by accountId
  Id accountId = l.contact__r.accountId;
  if(!leadConverMap.containsKey(accountId)) {
    leadConvertMap.put(accountId, new List<Database.LeadConvert>());
  }
  leadConvertMap.get(accountId).add(lc);
}

// group into batches guaranteeing no dupe accounts
while(true) {
  List<Database.LeadConvert> toConvert = new List<Database.LeadConvert>();
  for(Id accountId : leadConvertMap.keySet()) {
    List<Database.LeadConvert> convertList = leadConvertMap.get(accountId);
    if(!convertList.isEmpty()) {
      toConvert.add(convertList.remove(0));
    }
  }
  if(toConvert.isEmpty()) break;
  Database.convertLead(toConvert, false);
} 

Attribution
Source : Link , Question Author : James Loghry , Answer Author : Ralph Callaway

Leave a Comment