Showing posts with label APEX Trigger. Show all posts
Showing posts with label APEX Trigger. Show all posts

Wednesday, July 13, 2016

Native fields in Lead mapping for conversion

For Leads conversion process Salesforce provides out-of-box functionality for mapping Lead fields to Account/Contact/Opportunity.

Unfortunately there is a limitations - you can't map native Leads fields to target object's native field. For instance you can't map value from LeadSource ("native" Lead field) to AccountSource ("native" Account field).

Here is one of the possible ways to workaround the limitation. Solution could be modified based on particular business requirements. Please do not hesitate to contact us if you want to leverage this solutions in your Saleforce instance.

STEP 1: Create custom Formula(Text) field for Lead object
Name: LeadSourceCustom
Formula:  TEXT(LeadSource)

STEP 2: Create custom Text(100) field for Account object
Name: AccountSourceCustom

STEP 3: Amend Lead fields mapping to write value from LeadSourceCustom to AccountSourceCustom.

STEP 4: Create simple Trigger on Account object
/*
    Version        : 1.0
    Company        : Websolo inc. 
    Date           : 07/2016
    Description    : 
    Update History : 
*/
trigger AccountSourceTrigger on Account (before update,before insert) {
    for(Account a: Trigger.new){
        if(a.AccountSourceCustom__c != null && a.AccountSourceCustom__c != '' && (a.AccountSource == null || a.AccountSource == '')){
            a.AccountSource = a.AccountSourceCustom__c;
        } 
    }
}

As a result this trigger will update native AccountSource field with value from "native" LeadSource field.

EXTRA NOTE:
We can't use WorkFlow as a workaround because AccountSource field is picklist and when we create workflow action to update this field we can write only specific value from the picklist.

Thursday, May 14, 2015

Let your Contacts update their Email preferences using Force.com Site without authentication. Configuring the public Force.com Site.

Force.com Sites is relatively known feature which allows SFDC developers to set up public-facing sites/pages hosted by Salesforce platform. Using Force.com Site you can build micro web sites with one landing page or complicated sites with multiple pages. Such sites could have complicated flows to expose/collect information from/to Salesfroce. Advanced Force.com sites could even (for instance) accept credit card payments.

In this post we will show how to built quite easy but useful Force.com site and page with a purpose to let your Salesforce Contacts update their Email preferences themself, without contacting your support team. I.e. unsubscribe by updating Email Opt Out checkbox in related Salesforce record.

Solution could be modified based on particular business requirements.
Please do not hesitate to contact us if you want to leverage this solutions in your Saleforce instance.

Here's how the solution flow works:
  1. SFDC (or mass mail application) sends marketing emails out to customers (SFDC Contacts).
  2. Email will consist of "manage my subscription" or "unsubscribe" link. The link will be unique for each Contact and consist of "encrypted" Contact's ID. Encrypting is recommended to hide real SFDC Contatc ID (15-character) for security reasons. See the link with “hash id” (in yellow) below as an example.
  3. End user clicks on that URL and opens a Force.com site page, change his Email preferences and click "Update"to commit updates to SFDC.
Unique URL in email for end customer will looks like this:
http://yourdomain.force.com/emailpreferences/profile/fd90b5cd3bda11119f79a0c8131ab2ac7266d3f54add67f276c396e74f906da4

Step 0: Create new trigger to populate HashId field on Contact object

As mentioned above we suggest to encrypt native SFDC ID to improve your Force.com site security.
This technique allows to hide and not publicly expose your SFDC Contact record's ID. Instead of this Force.com site will use Crypto generated (algorithm SHA256) compact representations of the original ID value which will be "decrypted" back by URL rewriter controller class (see below).

First please create new HashId [HashId__c, Text (255)] field on Contact object. To make the field indexed by SFDC (and improve Force.com site response time) set External ID check box to TRUE.
Then create ContactHashId trigger to populate the field with encrypted value. 

NOTE: Trigger fires on "after insert", "before update" events on Contact object. Please make sure you will "update" existing Contacts using APEX scheduled Job or DataLoader.


APEX trigger: ContactHashId
/*
Version      : 1.0
Company      : WebSolo inc.
Date         : 05.2015
Description  : trigger to populate the HashId field on Contact object (used by PublicEmailPreferencesURLRewriter class)
History      :             
*/

trigger ContactHashId on Contact (after insert, before update) {

    // Generate hash ids for all contacts that don't have them.
    List<Contact> contactsToUpdate = new List<Contact>();
    for (Contact c : Trigger.new) {
        if (c.HashId__c == null) {
            String hashId = EncodingUtil.convertToHex(Crypto.generateDigest('SHA-256', Blob.valueOf((String)c.Id)));
            if (Trigger.isInsert) {
                contactsToUpdate.add(new Contact(Id = c.Id, HashId__c = hashId));
            } else {
                c.HashId__c = hashId;
            }
        }
    }
    if (!contactsToUpdate.isEmpty()) {
        update contactsToUpdate;
    }
}

Step 1: Set up Unique Domain Name for your SFDC instance

You can set up your Force.com Site by going to Setup | Develop | Sites

If your company does not have Force.com Site yet, you will be able to register a Force.com domain name that you like (upon availability).

NOTE: Be careful when registering the domain name on your Production instance. After registration you will not be able to change it! As per Salesforce "You cannot modify your Force.com domain name after the registration process."

Step 2: Create Force.com site components (VF page, APEX controllers, template) 

Create and save following Force.com site components.

VF page (Active Site Home Page): PublicEmailPreferences
<!-- 
Version      : 1.0
Company      : WebSolo Inc.
Date         : 05.2015
Description  : VF page "PublicEmailPreferences" to serve as a page in Force.com site
History      :             
-->

<apex:page controller="PublicEmailPreferencesController" cache="false" expires="0" showHeader="false" sidebar="false">

<style>
body { font-size: 100%; }
.contactInfo { margin: 20px 0px; }
.contentPanel { float: left; margin: 5px 0px 20px 20px; }
.contactLabel { float: left; font-weight: bold; width: 10em; }
h1 { color: #cc6611; font-size: 200%; padding-top: 25px;}
input[type="checkbox"] { height: 20px; width: 20px; }
.detailPanel { float: left; margin-left: 10px; width: 16em;margin-top:10px }
.logo { margin: 0px 100px 0px 20px; width: 250px; }
.selectionLabelPanel { float: left; margin-bottom: 10px; }
.selectionLabel { font-weight: bold; }
.selectionCheckboxPanel { float: right; }
</style>

<apex:composition template="{!$Site.Template}">
<apex:define name="logo">
<!-- 
You can add the logo here as a link to static resource 
<apex:image styleClass="logo" value="{!$Resource.LOGO_RESOURCE_NAME}" />
-->
</apex:define>

<apex:define name="headline">
  <h1>Email Opt Out Preferences</h1>
</apex:define>

<apex:define name="body">

  <apex:form >
  <apex:outputPanel id="leftPanel" layout="block" rendered="{!showPrefs}" styleClass="contentPanel" >    
    <apex:outputPanel layout="block" >
      <apex:outputText value="Keep your email preferences up to date." />
    </apex:outputPanel>    
    <apex:outputPanel layout="block" styleClass="contactInfo" >
      <apex:outputPanel layout="block" styleClass="contactLabel" >
        <apex:outputText value="Email" />
      </apex:outputPanel>
      <apex:outputPanel layout="block" >
        <apex:outputText value="{!contact.Email}" />
      </apex:outputPanel>
      <apex:outputPanel layout="block" styleClass="clearBoth" />
    </apex:outputPanel>    
    <apex:outputPanel layout="block" styleClass="contactInfo" >
      <apex:outputPanel layout="block" styleClass="contactLabel" >
        <apex:outputText value="First Name" />
      </apex:outputPanel>
      <apex:outputPanel layout="block" >
        <apex:outputText value="{!contact.FirstName}" />
      </apex:outputPanel>
      <apex:outputPanel layout="block" styleClass="clearBoth" />
    </apex:outputPanel>    
    <apex:outputPanel layout="block" styleClass="contactInfo" >
      <apex:outputPanel layout="block" styleClass="contactLabel" >
        <apex:outputText value="Last Name" />
      </apex:outputPanel>
      <apex:outputPanel layout="block" >
        <apex:outputText value="{!contact.LastName}" />
      </apex:outputPanel>
      <apex:outputPanel layout="block" styleClass="clearBoth" />
    </apex:outputPanel>    
    <apex:outputPanel layout="block" styleClass="contactInfo" >
      <apex:outputPanel layout="block" styleClass="clearBoth" />
    </apex:outputPanel>    
    <apex:outputPanel layout="block" >
      <apex:outputText value="To request an update to your profile information, please kindly contact our " />
      <apex:outputLink target="_top" style="color:#cc6611" value="mailto:SUPPORT%40YOURCOMAPNYDOMAIN.com?subject=Please%20update%20my%20information">support team</apex:outputLink>
      <apex:outputText value="." />
    </apex:outputPanel>    
  </apex:outputPanel>
  
  <apex:outputPanel layout="block" styleClass="clearBoth" />
  
  <apex:outputPanel id="rightPanel" layout="block" rendered="{!showPrefs}" styleClass="contentPanel" >    
    <apex:outputPanel layout="block" >
      <apex:outputText value="Select the checkbox if you do not want to receive emaild form us." />     
    </apex:outputPanel>
    <apex:outputPanel layout="block" styleClass="detailPanel" >    
      <apex:outputPanel layout="block" styleClass="selectionPanel" >
        <apex:outputPanel layout="block" styleClass="selectionLabelPanel" >
          <apex:outputText styleClass="selectionLabel" value="Opt Out Of Emails" />
        </apex:outputPanel>
        <apex:outputPanel layout="block" styleClass="selectionCheckboxPanel" >
          <apex:inputCheckbox styleClass="selectionCheckbox" value="{!subEmailOptOut}" />
        </apex:outputPanel>
      </apex:outputPanel>        
    </apex:outputPanel>
    <apex:outputPanel layout="block" styleClass="clearBoth" />
    <apex:outputPanel id="buttonPanel" layout="block" >
      <apex:actionStatus id="saveStatus">
        <apex:facet name="start">
            <apex:outputPanel >
            Updating...&nbsp;<img src="{!$Resource.AnimatedBusy}" />
          </apex:outputPanel>
        </apex:facet>
        <apex:facet name="stop">
          <apex:commandButton action="{!updatePreferences}" rerender="messagesPanel" status="saveStatus" style="background: #cc6611; color: white; font-size: 200%; margin-top: 20px;" styleClass="updateBtn" value="Update" />
        </apex:facet>
      </apex:actionStatus>
    </apex:outputPanel>    
  </apex:outputPanel>

  <apex:outputPanel layout="block" styleClass="clearBoth" />

  <apex:outputPanel id="messagesPanel" layout="block" style="max-width: 400px;" >
    <apex:outputPanel layout="block" rendered="{!hasMessages}" style="{!messagePanelStyle}" >
      <apex:repeat value="{!messages}" var="message">
        <apex:outputText value="{!message}" />
      </apex:repeat>
    </apex:outputPanel>
  </apex:outputPanel>

  </apex:form>

</apex:define>

</apex:composition>

</apex:page>

NOTE: For $Resource.AnimatedBusy please use any animated GIF illustrate "progress"

VF page controller (for Active Site Home Page): PublicEmailPreferencesController
/*
Version        : 1.0
Company        : WebSolo Inc.
Date           : 05.2015
Description    : controller for PublicEmailPreferences VF page 
Update History :

*/ 

public without sharing class PublicEmailPreferencesController {

    public Contact contact { public get; private set; }
    public Boolean subEmailOptOut { public get; public set; }
    public String rsaEmail { public get; private set; }
    public String rsrEmail { public get; private set; }
    public List<String> messages { public get; private set; }
    public Boolean hasMessages { public get {return messages != null && !messages.isEmpty();} private set; }
    public String messagePanelStyle { public get {return hasErrorMessage ? ERROR_STYLE : INFO_STYLE;} private set; }
    public Boolean showPrefs { public get; private set; }
    
    private Boolean hasErrorMessage = false;
    
    public final static String URL_PARM_ID = 'id';
    public final static String INFO_STYLE = 'color: green; background-color: #efe; padding: 10px; margin: 10px; border: 1px solid green;';
    public final static String ERROR_STYLE = 'color: red; background-color: #fee; padding: 10px; margin: 10px; border: 1px solid red;';
    public final static String ERR_CONTACT_NOT_FOUND = 'We are unable to retrieve your information at this time.';
    public final static String ERR_PREFS_UPDATE_FAILED = 'We are unable to update your preferences at this time.';
    public final static String ERR_PREFS_UPDATE_SUCCEEDED = 'Your preferences have been updated.';
    
    public PublicEmailPreferencesController() {
        
        clearMessages();
        
        String contactId = ApexPages.currentPage().getParameters().get(URL_PARM_ID);
        System.debug('id=' + contactId);
        if (contactId != null) {
            try {
                contact = getContactForId(contactId);
                if (contact != null) {
                    subEmailOptOut = contact.HasOptedOutOfEmail;
                    showPrefs = true;
                }
            } catch (Exception e) {
                addErrorMessage(ERR_CONTACT_NOT_FOUND);
            }
        } else {
            addErrorMessage(ERR_CONTACT_NOT_FOUND);
        }
    }
    
    private void addErrorMessage(String message) {
        if (messages == null) messages = new List<String>();
        messages.add(message);
        hasErrorMessage = true;
    }
    
    private void addInfoMessage(String message) {
        if (messages == null) messages = new List<String>();
        messages.add(message);
    }
    
    private void clearMessages() {
        if (messages == null) messages = new List<String>();
        messages.clear();
        hasErrorMessage = false;
    }
    
    private Contact getContactForId(String contactId) {
        Contact contact = null;
        List<Contact> contacts = [SELECT HasOptedOutOfEmail, Email, FirstName, Id, LastName FROM Contact WHERE Id = :contactId];
        if (contacts.size() == 1) {
            contact = contacts[0];
            
        } else {
            addErrorMessage(ERR_CONTACT_NOT_FOUND);
        }
        return contact;
    }
    
    public PageReference updatePreferences() {
        try {
            clearMessages();
            contact.HasOptedOutOfEmail = subEmailOptOut;
            update contact;
            addInfoMessage(ERR_PREFS_UPDATE_SUCCEEDED);
        } catch (Exception e) {
            addErrorMessage(ERR_PREFS_UPDATE_FAILED);
        }
        return null;
    }
}


VF page (template for site VF pages): PublicSiteTemplate
<!-- 
Version      : 1.0
Company      : WebSolo Inc.
Date         : 05.2015
Description  : VF page "PublicSiteTemplate" to serve as a Force.com Site Template
History      :             
-->
<apex:page showHeader="false" sidebar="false" id="PublicSiteTemplate" cache="false" expires="0" >
    <head>
        <title>FPC</title>
        
        <style>
            #fullContainer { }
            #headerContainer { padding: 0px 10px; }
            #logoContainer { float: left; }
            #contentContainer { padding-left: 10px; }
            #headlineContainer { float: left; margin-top:10px}
            #footerContainer { padding-left: 10px; }
            #footerbar { background-color: #cc6611; line-height: 0.5em; max-width: 650px; }
            .clearBoth { clear: both; }
        </style>
    </head>
    <body>
        <div id="fullContainer">
            <div id="headerContainer">
                <div id="logoContainer">
                    <apex:insert name="logo"/>
                </div>
                <div id="headlineContainer">
                    <apex:insert name="headline"/>
                </div>
                <div class="clearBoth"></div>
            </div>
            <div id="contentContainer">
                <div id="mainContent">
                    <apex:insert name="body"/>
                </div>
                <div class="clearBoth"></div>
            </div>
            <div id="footerContainer">
                <div id="footerLinks"></div>
                <div class="clearBoth"></div>
                <div id="footerbar">&nbsp;</div>
                <div class="clearBoth"></div>
            </div>
        </div>
    </body>
</apex:page>


APEX class (URL rewriter): PublicEmailPreferencesURLRewriter
/*
Version      : 1.0
Company      : WebSolo inc.
Date         : 05.2015
Description  : controller to support URL Rewrite for Force.com VF page "PublicEmailPreferences"
History      :             
*/

global class PublicEmailPreferencesURLRewriter implements Site.UrlRewriter {
    public static final String EMAIL_PROFILE_FRIENDLY = '/profile/';
    public static final String EMAIL_PROFILE_VF_PAGE_BASE = '/PublicEmailPreferences';
    public static final String EMAIL_PROFILE_VF_PAGE = EMAIL_PROFILE_VF_PAGE_BASE + '?' + PublicEmailPreferencesController.URL_PARM_ID + '=';

    global PageReference[] generateUrlFor(PageReference[] urls) {
        
        System.debug('generateUrlFor has been invoked for ' + urls);
        PageReference[] pageRefs = new List<PageReference>();
        
        Set<Id> cIds = new Set<Id>();
        for (PageReference pRef : urls) {
            String urlStr = pRef.getUrl();
            if (urlStr.startsWith(EMAIL_PROFILE_VF_PAGE_BASE)) {
                cIds.add(urlStr.substring(EMAIL_PROFILE_VF_PAGE.length()));
            }
        }
        
        Map<Id, Contact> contactsById = new Map<Id, Contact>([SELECT Id, HashId__c FROM Contact WHERE Id IN :cIds]);
        for (PageReference pRef : urls) {
            String urlStr = pRef.getUrl();
            pageRefs.add(
                urlStr.startsWith(EMAIL_PROFILE_VF_PAGE_BASE) ?
                new PageReference(EMAIL_PROFILE_FRIENDLY + contactsById.get(urlStr.substring(EMAIL_PROFILE_VF_PAGE.length())).HashId__c) :
                pRef
            );
        }
         return pageRefs;
    }
    
    global PageReference mapRequestUrl(PageReference url) {
        
        PageReference pageRef = null;
        
        String urlStr = url.getUrl();
        System.debug('mapping url=' + urlStr);
        
        if (urlStr.startsWith(EMAIL_PROFILE_FRIENDLY)) {
            String hashId = urlStr.substring(EMAIL_PROFILE_FRIENDLY.length());
            if (hashId != '') {
                List<Contact> contacts = [SELECT Id FROM Contact WHERE HashId__c = :hashId];
                if (!contacts.isEmpty()) {
                    pageRef = new PageReference(EMAIL_PROFILE_VF_PAGE + contacts[0].Id);
                } else {
                    pageRef = new PageReference(EMAIL_PROFILE_VF_PAGE);
                }
            }
        }
        return pageRef; 
    }
}


Step 3: Configuring new Force.com Public Site

Press the "New" button to create a new Force.com Site and enter the following values – you can leave all the other fields as-is. Click Save when done.
    • Site Label – name (may contain spaces) used to identify the site in the Salesforce user interface. In this example we use EmailPreferences. See screenshot below.
    • Site Name – name (cannot contain spaces) used to identify the site in code
    • Site Contact – Salesforce user who will receive email notifications about any problems with the site.
    • Default Web Address – the part of the site URL that will appear immediately after the domain name, e.g. “domainname.force.com/defaultwebaddress”.
    • Active – makes the site available for use. Can be set manually, or the Activate and Deactivate buttons on the Site page can be used to change tise setting.
    • Active Site Home Page – name of the Visualforce page that serves as the home page of the site when it is active: PublicEmailPreferences.
    • Inactive Site Home Page – name of the Visualforce page that serves as the home page of the site when it is not active: InMaintenance (automatically generated by Salesforce).
    • Site Template – name of the template that specifies the structure of all site pages: PublicSiteTemplate.
    • URL Rewriter Class – name of the class that translates public-facing URLs to internal ones: PublicEmailPreferencesURLRewriter. This class converts the public-facing contact ids into Salesforce record ids, so it provides one level of data security.
    • Clickjack Protection Level – the recommended value is compatible with the operation of the site.
Configuring new Force.com Public Site


Step 4: Adjusting Site Profile Permissions

Please proceed up with following steps:
    • On the Site Details page, click Public Access Settings.
    • Click Object Settings select Contact object and click Edit.
    • For Email Opt Out field tick Read and Edit 
    • Click Save.
    • Return to Profile Overview page select Visualforce Page Access and click Edit.
    • On the Enabled Visualforce Page list, select following pages and click Save:
      • PublicEmailPreferences
      • PublicEmailTemplate
    • Return to Profile Overview page select Apex Class Access and click Edit.
    • On the Enabled Apex Classes list, select following classes and click Save:
      • PublicEmailPreferencesController 
      • PublicEmailPreferencesURLRewriter
    • Note that the Enabled Visualforce Pages list may (and should) automatically include default pages associated with the site.
Step 5:  Test your new Force.com Site

When all done you can open the Force.com site URL an test it in action.
See how it suppose to looks like on our screenshot.


Force.com Site

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;
      }
    }
   }
 }
}