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
BrandiTBrandiT 

NEED HELP!! Update all items in custom object related list upon lead conversion

I have a custom object called headings__c that is related to Leads.  When I convert the lead, I need all of those heading records to be updated so that they show up under Accounts/Opportunties.

 

I've already created the lookup fields for those objects, but I don't know how to ensure those lookup fields are populated during lead conversion. 

 

I did find a trigger on the appexchange that I tried to use, but it will only move over one record and I need multiple heading records to move to the account/opportunity.

 

Does anyone know of any way to do this?  Is there something on the appexchange or does anyone have code that they've used?  Any ideas on how to make the code below work?

 

Here is the code I tried (but only copies first record from headings related list over):

 

trigger UpdateCustomeObject_Trigger on Lead (before update) {

for (Integer i = 0; i < Trigger.new.size(); i++){
    if (Trigger.new[i].IsConverted == true && Trigger.old[i].isConverted == false){
    Set<Id> leadIds = new Set<Id>();
    for (Lead lead : Trigger.new) {
        leadIds.add(lead.Id);
    }
   
    Map<Id, CustomObject__c> entries = new Map<Id, CustomObject__c>([select Contact__c, Opportunity__c, Account__c, Lead__c from CustomObject__c where lead__c in :leadIds]);       
    if(!Trigger.new.isEmpty()) {
    for (Lead lead : Trigger.new)  {
    for (CustomObject__c CustomObject : entries.values()) {
    if (CustomObject.Lead__c == lead.Id) {
        CustomObject.contact__c = lead.ConvertedContactId;
        CustomObject.opportunity__c = lead.ConvertedOpportunityId;
        CustomObject.account__c = lead.ConvertedAccountId;
        update CustomObject;
        break;
    }
    }
    }
    }
    }
    }
}

Best Answer chosen by Admin (Salesforce Developers) 
BrandiTBrandiT

I found a wonderful resource who was able to get this working for me.  Thought I would post the code in case anyone else is having the same problem.

 

trigger UpdateOHObject_Trigger on Lead (after update) {

  Map<Id, Lead> leadMap = new Map<Id,Lead>();
  Lead parent;
 
  for (Integer i = 0; i < Trigger.new.size(); i++){
    if (Trigger.new[i].IsConverted == true && Trigger.old[i].isConverted == false) {
      leadMap.put( Trigger.new[i].Id, Trigger.new[i]);
    }
  }
   
  if( leadMap.size() > 0 ) {
      Set<Id> leadIds = leadMap.keySet();
      List<Opportunity_Headings__c> allChildren =
        [select Id, Opportunity__c, Account__c, Lead__c from Opportunity_Headings__c where lead__c in :leadIds];      
 
 System.debug(allChildren);
   
      for ( Opportunity_Headings__c child : allChildren ) {
        if ( leadMap.containsKey( child.Lead__c ) ) {
           // lookup the parent lead
           parent = leadMap.get( child.Lead__c );
           // update the fields on the child object
           child.opportunity__c = parent.ConvertedOpportunityId;
           child.account__c = parent.ConvertedAccountId;
        }
      }

System.debug(allChildren);

    //try {
      update allChildren;
   // } catch( Exception e ) {
         // could put something here to notify on error
         // otherwise it fails silently
   // }
     
  }
}

 

Thanks for all your help Robert!

All Answers

bob_buzzardbob_buzzard

The reason for this is that the inner loop that locates the CustomObject__c instances that match a Lead breaks out when it finds a match, as highlighted below:

 

 

for (CustomObject__c CustomObject : entries.values()) {
    if (CustomObject.Lead__c == lead.Id) {
        CustomObject.contact__c = lead.ConvertedContactId;
        CustomObject.opportunity__c = lead.ConvertedOpportunityId;
        CustomObject.account__c = lead.ConvertedAccountId;
        update CustomObject;
        break;
    }
}

 

 

It would be better to store all the objects to update in a list and bulk update once you've processed everything.  Revised code shown below:

 

 

 List<CustomObject__c> toUpdate=new List<CustomObject__c>();
 Map<Id, CustomObject__c> entries = new Map<Id, CustomObject__c>([select Contact__c, Opportunity__c, Account__c, Lead__c from CustomObject__c where lead__c in :leadIds]);        
 if(!Trigger.new.isEmpty()) {
  for (Lead lead : Trigger.new)  {
   for (CustomObject__c CustomObject : entries.values()) {
    if (CustomObject.Lead__c == lead.Id) {
        CustomObject.contact__c = lead.ConvertedContactId;
        CustomObject.opportunity__c = lead.ConvertedOpportunityId;
        CustomObject.account__c = lead.ConvertedAccountId;
        toUpdate.add(CustomObject);
    }
   }
  }
 }
 if (!toUpdate.isEmpty())
 {
    update(toUpdate);
 }

 

 

 

BrandiTBrandiT

I found a wonderful resource who was able to get this working for me.  Thought I would post the code in case anyone else is having the same problem.

 

trigger UpdateOHObject_Trigger on Lead (after update) {

  Map<Id, Lead> leadMap = new Map<Id,Lead>();
  Lead parent;
 
  for (Integer i = 0; i < Trigger.new.size(); i++){
    if (Trigger.new[i].IsConverted == true && Trigger.old[i].isConverted == false) {
      leadMap.put( Trigger.new[i].Id, Trigger.new[i]);
    }
  }
   
  if( leadMap.size() > 0 ) {
      Set<Id> leadIds = leadMap.keySet();
      List<Opportunity_Headings__c> allChildren =
        [select Id, Opportunity__c, Account__c, Lead__c from Opportunity_Headings__c where lead__c in :leadIds];      
 
 System.debug(allChildren);
   
      for ( Opportunity_Headings__c child : allChildren ) {
        if ( leadMap.containsKey( child.Lead__c ) ) {
           // lookup the parent lead
           parent = leadMap.get( child.Lead__c );
           // update the fields on the child object
           child.opportunity__c = parent.ConvertedOpportunityId;
           child.account__c = parent.ConvertedAccountId;
        }
      }

System.debug(allChildren);

    //try {
      update allChildren;
   // } catch( Exception e ) {
         // could put something here to notify on error
         // otherwise it fails silently
   // }
     
  }
}

 

Thanks for all your help Robert!

This was selected as the best answer
richginparichginpa

Could a similar approach be used to copy all items in a related list on a custom object to a text field on the object?

 

Basically, I need to send an email from the related list parent (not really parent) that include all related items.

 

Seems this is not easily accomplished...

BrandiTBrandiT

I'm not 100% clear on the question in regards to copying related records to a text field, but to send emails that list those records...

 

I have a few workflows rules set up that send emails out that include a list of related items though.  You have to set up a Visualforce template.  Then put something like this in the code:

 

<apex:repeat var="cx" value="{!relatedTo.ChildObject__r}">
       <tr>
           <td>{!cx.Field1__c}</td>
           <td>{!cx.Field2__c}</td>
       </tr>
    </apex:repeat>

Not sure if that's what you are looking for though.

richginparichginpa

Im assuming that needs to be a master detail relationship and cannot be a lookuo relationship?  Sorry for the very basic questions - somewhat new to this aspect of the system.

BrandiTBrandiT

Actually, I believe you could do it with a master-detail or a lookup relationship. I didn't see anything in the documentation specifying that it would only work for master-details.