Thursday, August 7, 2014

Salesforce Lead Conversion - How To Specify resulted Account/Contact/Opportunity Record Types

As known when user converts a Lead, Salesforce creates new Account, Contact and Opportunity using the information from the Lead.

There is uncomfortable feature that Salesforce users struggle for a long time: "the default record type of the user converting the Lead is assigned to records created during lead conversion".

I.e. User (who's Profile has access to multiple Record Types) can not control with which Record Type Account, Contact and Optionally will be created. It always will be "Default Record Type" selected by Administrator for the User's profile. As a result Users will have to manually change Record Types for newly created records. Which is uncomfortable and takes valuable time.

There are two workarounds to enhance user experience and overcome the issue. Please find below workarounds description with analysis about their PROS and CONS.

Note: Updated 2015/02/05 with corrections related to solution #1

#1 Use Workflow Rules to update Record Type of created Account, Contact and Opportunity 

Easy to implement solution which not requires advanced Salesfroce Development skills.

Step 1: Create three picklist fields on Lead object (Expected Account Type, Expected Contact Type, Expected Opportunity Type) and populate them with Record Types names you have for Accounts, Contacts and Opportunities objects. These field will be visible to Users to let them to select Record Type they want for created after Lead Conversion records.

Step 2: Create three text fields with the same names on Accounts (Expected Account Type), Contacts (Expected Contact Type) and Opportunity (Expected Opportunity Type). These fields could be invisible for Users an will be used by workflow rules.

Step 3: Map new Leads fields to related fields on Accounts, Contacts and Opportunities objects.

Step 4:  You will have to create as many Workflow Rules and Actions for Accounts, Contacts and Opportunities as many Record Types you have in these objects. For instance if you have two Record Types for Account you will have to create two Workflows dedicated for each of them.

Set every Workflow Rule with Evaluation Criteria "Evaluate the rule when a record is created" and Rule Criteria  (for example) "Account: Expected Account Type EQUALS [YOUR RECORD TYPE NAME]. Add Action as field update to update the Record Type field to value you want to change in this particular Workflow. Repeat the same for every Account Record Type. Then do the same for Contacts and Opportunities Record Types.

Step 5: Activate Workflows and test the solution.

PROS: Pretty easy to implement. Does not require APEX coding and triggers development.
CONS: Six custom fields in four objects. Multiple (depend on your SFDC solution -  could be quite many) Workflow Rules/Actions to monitor and update if any changes required.

#2 Use APEX trigger Rules to update Record Type of created Account, Contact and Opportunity 

A little more complicated from development point of view but more efficient and easy to support solution.

Instead of the workflows this solution use a single APEX trigger with Helper class to handle all needed functionality.

Step 1: The same as above. Create three picklist fields on Lead object (Expected Account Type, Expected Contact Type, Expected Opportunity Type) and populate them with Record Types names you have for Accounts, Contacts and Opportunities objects. These field will be visible to Users to let them to select Record Type they want for created after Lead Conversion records.

Step 2: Create trigger and helper class. See code samples below.

Step 3: Test and deploy the solution to Production environment.

PROS: Easy to implement and support.
CONS: None

APEX Trigger: LeadConversionExpectedRecordTypes
/*
Version        : 1.0
Company        : Websolo inc. 
Date           : 08/2014
Description    : 
Update History :
*/
trigger LeadConversionExpectedRecordTypes on Opportunity (after insert) 
{
    Boolean uiCR = false;
     if(Test.isRunningTest())
     {
       uiCR  = true;
     }
     else
     {
      if(Trigger.new.size() == 1)
      {
       uiCR  = true;
      }
     }
     if(uiCR  == true)
     {
          for(Opportunity opp: Trigger.new)
          {
             LeadConversionExpectedRecordTypesHelper.UpdOpp(opp.id);
          }
     }
}

APEX helper class: LeadConversionExpectedRecordTypesHelper
/*
    Version        : 1.0
    Company        : Websolo inc. 
    Date           : 08/2014
    Description    : help class for LeadConversionExpectedRecordTypes trigger 
    Update History :
*/
public class LeadConversionExpectedRecordTypesHelper
{
 @future(callout = true)
 public static void UpdOpp(id oppObjID)
 {
   map mapRC = new map();
   for(RecordType a: [select Name, id from RecordType where SobjectType = 'Opportunity'])
   {
     mapRC.put(a.Name, a.id);
   }
   
   map mapRCacc = new map();
   for(RecordType a: [select Name, id from RecordType where SobjectType = 'Account'])
   {
     mapRCacc.put(a.Name, a.id);
   }   
   
   Opportunity opp = [select id, OwnerId, RecordTypeId from Opportunity where id =: oppObjID];   
   List listLead = new List();
   if(!test.isRunningTest())
   {
       listLead = [select id, Expected_Opportunity_Type__c, Expected_Account_Type__c, ConvertedAccountId  from Lead where ConvertedOpportunityId =: opp.id AND isConverted = true];
   }
   else
   {
       listLead = [select id, Expected_Opportunity_Type__c, Expected_Account_Type__c, ConvertedAccountId from Lead];        
   }   
   if(listLead.size() > 0)
   {
    if(listLead[0].Expected_Opportunity_Type__c != null)
    {
      opp.RecordTypeId = mapRC.get(listLead[0].Expected_Opportunity_Type__c);
      update opp;
    }
    if(listLead[0].ConvertedAccountId != null)
    {
      Account acc = [select id, RecordTypeId from Account where id=:listLead[0].ConvertedAccountId];
      if(listLead[0].Expected_Account_Type__c != null)
      {
        acc.RecordTypeId = mapRCacc.get(listLead[0].Expected_Account_Type__c);
        update acc;
      }
    }
   }
 }
}