0

I want to update the email optout field from converted contact to the existing contacts. For ex lets say i have 3 contacts with same email address([email protected]) and emailoptout not checked and iam converting new lead with emailoptout box checked and has same email([email protected]), i want my trigger to update the email optout box to true on these 3 existing contacts.

trigger updateLeadOnEmailOptOut on Lead (after update) {
    List<Lead> duplicateLeads = new List<Lead>();
    Map<String, Lead> leadEmailMap = new Map<String, Lead>();
    Map<Id, Lead> leadIdMap = new Map<Id, Lead>();
    Map<Id, Contact> contacts = new Map<Id, Contact>();

    for (Integer i = 0; i < Trigger.new.size(); i++) {
        if (Trigger.old[i].HasOptedOutOfEmail != Trigger.new[i].HasOptedOutOfEmail) {
            leadEmailMap.put(Trigger.old[i].email, Trigger.new[i]);
            leadIdMap.put(Trigger.old[i].id, Trigger.new[i]);        
        }
    }    

    if ( leadIdMap.size() > 0 ) {
        for ( Lead dupLead : [SELECT Id, Name, Email, HasOptedOutOfEmail FROM Lead
                                WHERE Email IN : leadEmailMap.KeySet()
                                AND Id NOT IN : leadIdMap.KeySet()
                                AND IsConverted = FALSE]) {
                                 Lead lead = leadEmailMap.get(dupLead.Email);
            if (dupLead.HasOptedOutOfEmail <> lead.HasOptedOutOfEmail) { 
                dupLead.HasOptedOutOfEmail = lead.HasOptedOutOfEmail;   
                duplicateLeads.add(dupLead);
            }
        }

        if ( duplicateLeads.size() > 0 )
            update duplicateLeads;
    }
    for ( Lead record : Trigger.new ) {
        if ( record.ConvertedContactId != null ) {
            contacts.put(record.ConvertedContactId, new Contact(Id=record.ConvertedContactId, HasOptedOutOfEmail=record.HasOptedOutOfEmail));
        }
    }
    update contacts.values(); 
}

2 Answers 2

1

Yes, in your after update lead trigger, you can update the selected contact using something like this:

Map<Id, Contact> contacts = new Map<Id, Contact>();
for(Lead record: Trigger.new) {
    if(record.ConvertedContactId != null) {
        contacts.put(record.ConvertedContactId, new Contact(Id=record.ConvertedContactId, HasOptedOutOfEmail=record.HasOptedOutOfEmail));
    }
}
update contacts.values();

As an aside, "guarding" against an empty list is an obsolete technique.

8
  • Iam getting this error while i check the emailoptout box to true on new lead Apex trigger updateLeadOnEmailOptOut caused an unexpected exception, contact your administrator: updateLeadOnEmailOptOut: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 00Q29000001WNRnEAO; first error: CANNOT_UPDATE_CONVERTED_LEAD, cannot reference converted lead: []: Trigger.updateLeadOnEmailOptOut: line 37, column 1.
    – Admin_BA
    Oct 7, 2015 at 21:00
  • I have updated the trigger above
    – Admin_BA
    Oct 7, 2015 at 21:03
  • @Admin_BA In your lead trigger, simply add a filter for IsConverted = FALSE in your query.
    – sfdcfox
    Oct 7, 2015 at 21:03
  • Sorry where exactly you add in the above modified trigger?
    – Admin_BA
    Oct 7, 2015 at 21:06
  • @Admin_BA No, that part's fine, I'm referring to for(Lead dupLead: [SELECT ..., you need to add AND IsConverted = FALSE to the end of the query.
    – sfdcfox
    Oct 7, 2015 at 21:09
0

The solution may be much simpler than you coded (assumes that you really only care about setting emailOptOut to true on existing contacts if Lead indicates they want to optOut. If the lead opts in, then the converted contact will automatically also optIn on lead conversion

trigger syncEmailOptoutWithContactsOnLeadConversion on Lead (after update) {
   Set<String> emailSearchSet = new Set<String> ();
   for (Lead l : Trigger.new)
     if (l.isConverted && l.hasOptedOutofEmail && l.email != null)
        emailSearchSet.add(l.email);

  List<Contact> cUpdList = [select id, hasOptedOutOfEmail 
                             from Contact 
                             where email IN :emailSearchSet and
                                   hasOptedOutOfEmail = false
                           ];
  for (Contact c : cUpdList)
      c.hasOptedOutOfEmail = true;

  try {  // you could do partial success logic here and correlate
         // any database error back to the offending triggered item
         // but this is an exercise left for you
    update cUpdList;
  }
  catch (Exception e) {//do something useful - prevent conversion? send email? you decide}
}
3
  • N.B. code typed in - may be syntax errors
    – cropredy
    Oct 8, 2015 at 21:52
  • Sorry i forgot to mention i had that code because it should also work even if there is no conversion of lead. i.e if there are 3 contacts in sfdc that has the box not checked then if i check atleast one then it should update rest, now iam trying to implement it for the lead conversion, as per sfdcfox suggested i added that last lines of code but it's not working, any idea on how to modify my trigger
    – Admin_BA
    Oct 8, 2015 at 22:24
  • a) Update your OP (use Edit) to reflect latest code, (b) use system.debug statements at each point along the way to see what is happenning
    – cropredy
    Oct 9, 2015 at 0:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .