0

The following class is called during an after insert trigger and handed trigger.NewMap.

Per my debugs the task whoid is updated, however when I look at the task record the whoid has not been updated. No error is given, what gives? This also happens when I wrote this as a before insert with trigger.new. What gives!

NOTE: This code is generic enough to work in any org, no custom fields etc. Just copy and paste and call it from your task trigger (after insert).

public class exampleTaskParenting {

public static void qualifySource(Map<Id, Task> newMap) {

    List<Task> newMapTasks = [SELECT Id, WhoId, Subject FROM Task WHERE Id IN: newMap.keySet() LIMIT 50000];
    List<Task> exampleSource = new List<Task>();

       //Qualify based on subject line string

    for(Task t : newMapTasks) {

        String taskSubject = t.subject;

        if(tasksubject.contains('[example]')) {
            exampleSource.add(t);

        }
    }
    if(exampleSource.size() > 0) {
        reparentTasks(exampleSource);
    }
}

public static void reparentTasks(List<Task> exampleSource) {

    List<Id> parentLeadIds = new List<Id>();
    List<Lead> parentLeads = new List<Lead>();
    List<String> parentLeadEmails = new List<String>();
    Map<Id, Id> parentIdIdMap = new Map<Id, Id>();
    List<Contact> parentContacts = new List<Contact>();

    for(Task t : exampleSource) {
        parentLeadIds.add(t.WhoId);

    }

    // Get parent Lead records for email processing
    parentLeads = [SELECT Id, Email 
                   FROM Lead 
                   WHERE Id IN: parentLeadIds 
                   LIMIT 50000];

    for(Lead l : parentLeads) {
        parentLeadEmails.add(l.email);

    }

    parentContacts = [SELECT Id, Email 
                     FROM Contact 
                     WHERE Email IN: parentLeadEmails 
                     LIMIT 50000];
    // Bad logic
    for(Lead l : parentLeads) {
        for(Contact c : parentContacts) {
            if(l.email == c.email) {
                parentIdIdMap.put(l.Id, c.Id);

            }
        }    
    }
    // Parent based on Id Id Map
    for(Task t : exampleSource) {
        System.debug('Before: ' + t.whoid);
        t.whoId = parentIdIdMap.get(t.whoId);
        System.debug('After: '+ t.whoid);

    }

    update exampleSource;       
}
}
8
  • can you refactor your code and add error handling logic to check why it is getting failed. There are lots to unwanted looping which you need to work on Jun 20, 2017 at 15:11
  • @SantanuBoral No failures are given, the code runs. However it does not update the whoid after the context finishes. Jun 20, 2017 at 15:51
  • Santanu is saying to put a try/catch block around the update to see if there is an error updating.. 30 seconds of work
    – EricSSH
    Jun 20, 2017 at 16:28
  • @EricSSH The update gives no error when running. A try catch would not have anything to catch? If this is failing, it fails silently. Jun 20, 2017 at 16:31
  • Well considering your DML operation should have one anyway, i dunno what to tell you.. Also the majority of those Lists aren't needed with proper Map usage
    – EricSSH
    Jun 20, 2017 at 16:36

2 Answers 2

1


I got the solution for this issue
I was facing the same issue and you can solve the issue by using the @future annotation but this solution will only work for Non-batch Apex Class.
Using Future Method you can update the WhoId of the task.

Note : This issue was caused because of Shared Activities feature was enabled in your org.
(Setup --> Activity Setting --> Allow Users to Relate Multiple Contacts to Tasks and Events)

2

If you truly want to make it generic you could do something like this, but this really isn't generic considering you need a Contact and Lead that have the same email addresses. I don't like string of task subject contains stuff, but that may be the best way.. This methods only job is to change the WhoID and you should update the task outside this method..

I don't know why yours wasn't working, I'm guessing your tasks for update wasn't building correctly. This works in my org, but if you may have required fields somewhere that I don't

public static Map<ID, Task> reparentTasksWithLeadsAndAssociatedContactEmails(Map<ID, Task> taskMap, String taskSubjectToReparent) 
{

    Map<ID, Task> result = new Map<ID, Task> ();

    for(ID t : taskMap.keySet()) 
    {
        if(taskMap.get(t).Subject.contains(taskSubjectToReparent)) 
        {
            result.put(taskMap.get(t).WhoID, taskMap.get(t));
        }
    }

    System.debug('result ' + result);

    if(!result.isEmpty())
    {
        Map<ID, Lead> leadMap = new Map<ID, Lead>([SELECT Id, Email FROM Lead WHERE ID IN: result.keySet()]);

        Set<String> emails = new Set<String>();

        for(ID leadID : leadMap.keySet())
        {
            emails.add(leadMap.get(leadID).Email);
        }

        Map<String, Contact> emailToContact = new Map<String, Contact>();

        for(Contact contact : [SELECT ID, Email FROM Contact WHERE Email =: emails])
        {
            emailToContact.put(contact.Email, contact);
        }


        for(ID taskID : result.keySet())
        {
            if(leadMap.containsKey(result.get(taskID).WhoID))
            {
                result.get(taskID).WhoID = emailToContact.get(leadMap.get(result.get(taskID).WhoID).Email).ID;
            }
        }
    }

    return result;
}
9
  • Thank you for posting that, however I am truly interested in why what I wrote does not update. The logic appears to be basic and clearcut. Jun 20, 2017 at 18:05
  • What do your system debugs say at Before: and After:?
    – EricSSH
    Jun 20, 2017 at 18:12
  • USER_DEBUG [69]|DEBUG|Before: 00QXXXXXX(Lead) , USER_DEBUG [71]|DEBUG|After: 003XXXXXX(Contact), Makes no sense, why the hoot does the update list not update the whoid, I even tried doing the update within the for loop yet still got the same result. Is WhoId not updatable? Why am I not getting a read only error then? Jun 20, 2017 at 18:13
  • What fires after you update a Task? There is something happening to it down stream then
    – EricSSH
    Jun 20, 2017 at 18:19
  • Nothing else, I have tried this in a vanilla dev org, I am gunna end up opening a ticket. I read on the forums WhoId cannot be modified during a before Insert, perhaps that extends to after insert. Jun 20, 2017 at 18:21

You must log in to answer this question.

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