function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
dmchengdmcheng 

Trigger syntax for Lead Convert trigger?

I finally got Validation/Triggers enabled for Lead Conversion, but now I can't figure out how to code a trigger for it.  I've tried

Code:
trigger test on Lead (after convert) {
}

but I get an Invalid Token error.  There are no hints in the documentation.

thanks
David
Best Answer chosen by Admin (Salesforce Developers) 
beenerbeener
Hi,

Thanks for the quick reply.

I'm concerned with creating a class to copy fields that are not (and cannot) be mapped from lead to other object.
Namely, I must copy some fields to a detail object of Contact.

To this end, I need to obtain the id of the new Contact, that is generated as a result of the lead. any idea on how I would do that?

also, based on your comments, here's what I understand the trigger to look like, please say if you think that makes sense.

Thanks

Code:
trigger test on Lead (before update) {
 for(Lead lead:System.Trigger.new) {
  if (Lead.IsConverted)
  //do somethign here with converted leads
 }
}

 

All Answers

Vijay RautVijay Raut
Hi,

There is no convert event. We have to use update event.

Also you can use IsConverted field on Lead to check if Lead is Converted to Account / Contact / Opportunity.

Hope this will help.

Thanks,
V.R.
dmchengdmcheng
Thanks for your reply.  But if we use "after update" anyway, then why is Trigger on Lead Convert a separate feature that has to be enabled?  I've already built a lead trigger on "after update" as a workaround for the lead conversion trigger, and I though enabling the actual trigger would mean something different.

David
Vijay RautVijay Raut

In earlier case, if you are converting Lead and creating New Account / Contact / Opportunity in Lead Conversion, then Triggers which are exist on Account / contact / Opportunity were not firing.

So this new feature gives us option to fire Account / Contact / Opportunity Triggers when we Convert Lead to Account / Contact / Opportunity.

Cheers,

V.R.

dmchengdmcheng
Ah, I just read the last paragraph of the help entry and see that it enables the "before" triggers for account/lead/opportunity when a lead is converted.
beenerbeener
Hi,

I'm also trying to create a convert trigger. from your discussion. I understand that I must use the Before Trigger on account, and somehow check a context variable to determine if this was a Lead.

  1. Can you mention which variable I should check
  2. Do you have a link to help on this issue?
  3. Is it possible for you to include a code sample of your link? obviously, I only need the relevant portion, not the specifics.
Thanks so much, in advance.

Ben
dmchengdmcheng
Actually, you put the Before trigger on the Lead, not on the Account, since you are triggering on a change in the Lead.  Use the Lead.IsConverted field to determine if the Lead was converted.
beenerbeener
Hi,

Thanks for the quick reply.

I'm concerned with creating a class to copy fields that are not (and cannot) be mapped from lead to other object.
Namely, I must copy some fields to a detail object of Contact.

To this end, I need to obtain the id of the new Contact, that is generated as a result of the lead. any idea on how I would do that?

also, based on your comments, here's what I understand the trigger to look like, please say if you think that makes sense.

Thanks

Code:
trigger test on Lead (before update) {
 for(Lead lead:System.Trigger.new) {
  if (Lead.IsConverted)
  //do somethign here with converted leads
 }
}

 

This was selected as the best answer
Greg RohmanGreg Rohman
Hi Beener.

I had the same problem, so I came up with this simple trigger to update the "Type" custom field on a Contact record with the value from the "Status" field on the Lead. I'm new to Apex, and there might be better or more efficient ways to do this, but this works for me.

Code:
trigger trigMapFields on Lead (before update) {
for(Lead lead:System.Trigger.new) {
if (lead.IsConverted) {
// Assign the value from the Lead "Status" field to the Contact "Type" field
Contact con = [SELECT Id FROM Contact WHERE Contact.Id = :lead.ConvertedContactId];
con.Type__c = lead.Status;
update con;
}
}
}

 
-Greg
dmchengdmcheng
Sorry for the late reply.  In the IDE, you can select the Salesforce schema in the tree view on the left side and then view the Lead table fields on the right side.  You'll see fields that contain the converted Account and Contact IDs.

In your code:

You don't need system.trigger.new, just Trigger.New.

You need to put your Select and Update statements outside of the for loop because of the governor limits.  What you need to do is:

* run a for loop to get all the contact IDs from the lead records in the trigger and place the IDs in a Set object.
* Do a single SOQL select statement to pull all the contact records using those IDs, and place the results into a List object.
* Run a for loop through the List object and change the contact types.
* execute the Update statement with the List object (which contains the contact records) as the argument.
Greg RohmanGreg Rohman
Thanks for the response.

I have some other triggers that I've converted for bulk use, but this one I had figured I didn't need to, as we don't do bulk conversions. Is it considered best practices, though, to always structure triggers that way?

I've modified my trigger to what I believe will work in bulk mode. The code is below. Will this method work? I'm using a Map instead of a Set, because I wanted to pull the Status field from the Lead.

Code:
trigger trigMapFields on Lead (before update) {

    Map<Id,String> leadStatus = new Map<Id,String>(); // Map of the converted Contact ID and the Lead Status

    for(Lead lead : Trigger.new) {
        if (lead.IsConverted) {
            leadStatus.put(lead.ConvertedContactId,lead.Status);
        }
    }
    List<Contact> conContacts = [select Id from Contact WHERE Contact.Id IN :leadStatus.keySet()];
    for ( Contact c : conContacts) {
        c.Type__c = leadStatus.get(c.Id);
    }
    update conContacts;
}

Thanks in advance.

-Greg
 

dmchengdmcheng
Yup that should work.  I think it is best practice to write all code as if you were doing bulk processing.
jahnhyjahnhy

Hello- I have created a very similar trigger to this but looking at another lead field called 'process stage'. My question is, how did you test this code (what did the class look like) in order to get coverage and deploy?

Any help with sample code would be greatly appreciated.

Thanks!

Greg RohmanGreg Rohman
Hello.

My complete trigger does a bunch of other things, so my working unit test method also has additional code. I've removed anything that shouldn't be relevant to the sample trigger above, so this SHOULD work, but it is untested.

Basically, I've created a dummy lead with some values, converted that lead, and then checked to make sure that the Type__c field of the contact equals the value of the Status field for the dummy lead that I created.

Code:
public class testLeadConvertMapFields { 
    static testMethod void trigTest() {

        // Create dummy lead
        Lead testLead = new Lead(Company='Test Lead',FirstName='John',LastName='Doe',Status='Open',Phone='555-123-4567',Potential_Opportunity__c='Pot opp',Priority__c='High',Prospect_Source__c='other title comp',Strategy__c='strategy');
        insert testLead;
    
        // Create dummy conversion
        Database.LeadConvert lc = new database.LeadConvert();
        lc.setLeadId(testlead.id);
        lc.setConvertedStatus('Pipeline Prospect');
        Database.LeadConvertResult lcr = Database.convertLead(lc);

        // Make sure conversion was successful
        System.assert(lcr.isSuccess());

        // Test Contact "Status" field update
        Contact testCon = [SELECT Type__c FROM Contact WHERE Contact.Id = :lcr.getContactId()];
        System.assertEquals(testCon.Type__c,'Pipeline Prospect');
    }
}

Hope this helps.

-Greg
 

dmchengdmcheng
Hi.  I've written some documentation that includes a section on developing unit tests.  See http://claritytechworks.com/salesforce.htm
BobBBobB

I realize this is an old thread but I might as well ask.

 

I'm trying to use this test code to test a convert trigger and everything goes swimmingly until this line:

    Database.LeadConvertResult lcr = Database.convertLead(lc);
I know that the lead ID is: 00QA0000004hNU7MAM

 

This is the result and I'm sure it's telling me exactly what is wrong but I'm new to this and don't understand what it is telling me:

System.DmlException: ConvertLead failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, System.DmlException: Update failed. First exception on row 0 with id 00QA0000004hNU7MAM; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, trigLeadConvert: execution of BeforeUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Contact.AccountId Trigger.trigLeadConvert: line 10, column 37: [] (System Code) External entry point: []

 

I think I have followed the example code exactly so any help is appreciated.

 

Thanks... Bob

 

mohimohi

u can define convert as dml statement like insert , update , delete

craigmhcraigmh

I've come across an odd issue when trying to callout when a Lead is converted.  I used the same trigger posted in this thread, but I still get this error:

 

First error: You have uncommitted work pending. Please commit or rollback before calling out

 

I do have the trigger acting on the Lead, "before update", so which DML operation(s) is it doing before the callout? Since the business rules for what I'm doing only allow for one Lead to be converted at a time, I only reference the first one like so:

 

trigger trigger_LeadConverted on Lead (before update) {
    if(System.trigger.new[0].IsConverted) {
        Callouts.LeadConverted(trigger.new[0].ConvertedOpportunityId);
    }
}

 

But for some reason, this isn't allowed.  What's the issue here? 

 

Edit:

Yes, I do have "Enforce Validation and Triggers from Lead Convert" enabled.

cby016cby016

Greg thanks for your posts, they helped me to write a lead convert trigger and the test method very quickly.

Mohan Raj 33Mohan Raj 33
@dmcheng Hi, I am new in trigger I have the same issue in lead conversion trigger I am used in the following trigger 
public class LeadConversionIndicationHandler {

    Public static void insertTrigger(List<Lead> LeadConvert){
        Map<Id,Integer> NumberofconvertedLeads=new Map<Id,Integer>();
        for(Lead j:LeadConvert){
            if(NumberofconvertedLeads.isConverted == True){
                if(NumberofconvertedLeads.get(j.AccountId)==Null){
                    NumberofconvertedLeads.put(j.AccountId,1);
                }
                else{
                    NumberofconvertedLeads.put(j.AccountId,NumberofconvertedLeads.get(j.AccountId)+1);
                }
             }
            Set<id> setofid=NumberofconvertedLeads.keySet();
            List<Account> acctoupdate=[SELECT Id,Number_of_converted_Leads__c FROM Account WHERE Id IN :setofid];
            List<Account> listone=new List<Account>();
            for(Account a:acctoupdate){
                if(a.Number_of_converted_Leads__c==Null)
                    a.Number_of_converted_Leads__c=0;
                a.Number_of_converted_Leads__c=a.Number_of_converted_Leads__c+NumberofconvertedLeads.get(a.Id);
                listone.add(a);
                
            }
            Update listone;
        
        }        

    }
}

Here It's provided ERROR :the AccountId field is invalid for sobject lead how to I solve it here I am trying to the if lead is converted to the particular account it's to be the field is Number_of_converted_Leads__c field in account is incresed by one(actually it calculated converted lead for particular account ). Thanks
Danielle Pulley 10Danielle Pulley 10
How do I add two more options to my Lead Source when converting automatically. I need to add User Registration and Organization Registration as well. Please see trigger below. All help is appreciated. 

trigger LeadConvert on Lead (after insert,after update) {
//Bulkified
List<String> LeadNames = new List<String>{};
for(Lead myLead: Trigger.new){
 if((myLead.isconverted==false) && (myLead.LeadSource = 'Academy Registration')) {
Database.LeadConvert lc = new database.LeadConvert();
        lc.setLeadId(myLead.Id);
        lc.convertedStatus = 'Qualified';
        //Database.ConvertLead(lc,true);
        lc.setDoNotCreateOpportunity(true);
        Database.LeadConvertResult lcr = Database.convertLead(lc);
        System.assert(lcr.isSuccess());
        }
        }
}
Sravan Kumar 359Sravan Kumar 359
Hi , I am trying to convert a Lead through Trigger Bulk lead conversion process. As per my requirement, when i updated the Lead Status as Closed -Converted then lead should be converted  as well as Related records like an Account,Contact and Opportunity should be created automatically. But, it is not working. Please find the following code and provide a solution for this ... Thanks in Advance 

trigger LeadAutomaticConvert on Lead (After Update) 
{
if(Trigger.isAfter && Trigger.Isupdate)

    LeadStatus Ldstatus = [Select id,Masterlabel, isconverted from LeadStatus where isconverted = True];
    list<database.LeadConvert> lstlConvert = New list<database.LeadConvert>();
    for(Lead ldrec : Trigger.New)
    {
        if(ldrec.Status == 'Closed-Converted' && ldrec.isConverted == False)
        {
        Database.LeadConvert Lconvert = New Database.LeadConvert();
        Lconvert.setLeadId(ldrec.Id);
        Lconvert.setDoNotCreateOpportunity(False);    
        Lconvert.setSendNotificationEmail(True);
        Lconvert.setConvertedStatus(ldstatus.MasterLabel);    
        lstlConvert.add(Lconvert);
    }
        if(!lstlconvert.isempty())
        {
            database.LeadConvertResult[] LResults = Database.convertLead(lstlconvert); 
        }
}
}
}
RAHUL PARJAPATI 7RAHUL PARJAPATI 7

trigger conversion on Lead (after insert) {
set<id>idset=new set<id>();
list<lead>lelist=new list<lead>();
account ac=new account();
contact con=new contact();
account acs=new account();
opportunity opp=new opportunity();
list<account>acclist=new list<account>();
list<contact>conlist=new list<contact>();
list<opportunity>opplist=new list<opportunity>();
if(Trigger.isDelete || Trigger.isInsert){
if(Trigger.isDelete){
for(Lead l:trigger.old){
idset.add(l.id); ac.name=l.company; ac.id=l.id;
}
}
else {
for(lead ls:trigger.new)
{
idset.add(ls.id);
ac.name=ls.company;
ac.id=ls.PartnerAccountid;
}
}
}
for(lead le:trigger.new)
{
idset.add(le.id);
ac.name=le.company;
ac.id=le.PartnerAccountid;
}
acclist.add(ac);
insert acclist;