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;       
}
}
  • 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 – Santanu Boral Jun 20 '17 at 15:11
  • @SantanuBoral No failures are given, the code runs. However it does not update the whoid after the context finishes. – Steel Reserve 211 Jun 20 '17 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 '17 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. – Steel Reserve 211 Jun 20 '17 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 '17 at 16:36
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)

| improve this answer | |
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;
}
| improve this answer | |
  • 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. – Steel Reserve 211 Jun 20 '17 at 18:05
  • What do your system debugs say at Before: and After:? – EricSSH Jun 20 '17 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? – Steel Reserve 211 Jun 20 '17 at 18:13
  • What fires after you update a Task? There is something happening to it down stream then – EricSSH Jun 20 '17 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. – Steel Reserve 211 Jun 20 '17 at 18:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.