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
Salesforce AdminSalesforce Admin 

Trigger for Task- Opportunity not firing

Hello There,

I'm kinda new in apex triggers and was trying to write a trigger to copy a field from a task to an account/ opportunity. I tried out the below codes for opportunity but it doesn't seem to copy the task field to opportunity. Any suggestions please? Cheers.

trigger TaskAfterInsertUpdate on Task (after update, after insert)
{
    list<opportunity> liOpportunities = new list<opportunity>();
    list<id> liIDs = new list<id>();

    for(Task sTask : trigger.new)
    {
        if(sTask.Subject.startsWith('Outbound call') || sTask.Subject.startsWith('Inbound call'))
        {
            liIDs.add(sTask.WhatId);
        }
    }

    for(Opportunity sOppty : [select Id, Agent__c from Opportunity]) //where Id in : liIDS])
    {
        sOppty.Agent__c = 'Bla';
        sOppty.Date = sTask.LastModifiedDate;
        liOpportunities.add(sOppty);
    }

    update liOpportunities;
}
Best Answer chosen by Salesforce Admin
pconpcon
I've taken the liberty of updating your trigger to make it better suited for bulk transactions.
 
trigger TaskAfterInsertUpdate on Task (before update, after insert) {
    Set<Id> ownerIds = new Set<Id>();
    Map<Id, Task> taskMap = new Map<Id, Task>();

    for (Task t : Trigger.new) {
        if (
            t.Subject.startsWith('Outbound call') ||
            t.Subject.startsWith('Inbound call')
        ) { 
            taskMap.put(t.WhatId, t);
            ownerIds.add(t.OwnerId);
        } 
    }   

    if (!taskMap.isEmpty()) {
        Map<Id, User> userMap = new Map<Id, User>([
            select Name
            from User
            where Id in :ownerIds
        ]);

        List<Opportunity> oppsToUpdate = new List<Opportunity>();

        for (Opportunity opp : [
            select Agent__c, Date__c
            from Opportunity
            where Id in :taskMap.keySet()
        ]) {
            Task t = taskMap.get(opp.Id);
            opp.Agent__c = userMap.get(t.OwnerId);
            opp.Date__c = t.LastModifiedDate;
            oppsToUpdate.add(opp);
        }  

        if (!oppsToUpdate.isEmpty()) {
            update oppsToUpdate;
        }
    }
}
NOTE: This code has not been tested and may contain typographical or logical errors

All Answers

pconpcon
You are pretty close but you're missing the correct logic to get the right task.  Also, since you are not looking up any information from the Opportunity, it can be done without actually querying the Opportunities.  I've taken the liberty of updating your code to do this.
 
trigger TaskAfterInsertUpdate on Task (after update, after insert) {
    List<Opportunity> opps = new List<Opportunity>();
    Map<Id, Task> oppToTaskMap = new Map<Id, Task>();

    for (Task t : Trigger.new) {
        if (
            t.Subject.startsWith('Outbound call') ||
            t.Subject.startsWith('Inbound call')
        ) {
            oppToTaskMap.put(t.WhatId, t);
        }
    }

    for (Id oppId : oppToTaskMap.keySet()) {
        opps.add(new Opportunity(
            Agent__c = 'Bla',
            opp.Date = oppToTaskMap.get(oppId).LastModifiedDate
        ));
    }

    if (!opps.isEmpty()) {
        update opps;
    }
}

NOTE: This code has not been tested and may contain typographical or logical errors
Salesforce AdminSalesforce Admin
Thanks a lot for your swift response pcon. I sitll get an error

[Error] Error: Compile Error: Invalid field initializer: opps.Date at line 17 column 13

Also, the "bla" is supposed to be the AssignedTo field in Task.
Please any ideas

Thanks
 
trigger TaskAfterInsertUpdate on Task (after update, after insert) {
    List<Opportunity> opps = new List<Opportunity>();
    Map<Id, Task> oppToTaskMap = new Map<Id, Task>();

    for (Task t : Trigger.new) {
        if (
            t.Subject.startsWith('Outbound call') ||
            t.Subject.startsWith('Inbound call')
        ) {
            oppToTaskMap.put(t.WhatId, t);
        }
    }

    for (Id oppId : oppToTaskMap.keySet()) {
        opps.add(new Opportunity(
            Agent__c = 'Bla', //This "bla" is actually suppose to be the AssignedTo in task.
            opps.Date = oppToTaskMap.get(oppId).LastModifiedDate
        ));
    }

    if (!opps.isEmpty()) {
        update opps;
    }
}

 
pconpcon
You need to update line 17 to be a valid field for your date.  I've picked the LastActivityDate but it's up to you to which one you want to assign it to.  I've also update line 16 to use the tasks OwnerId (which is the Assigned To field).
 
trigger TaskAfterInsertUpdate on Task (after update, after insert) {
    List<Opportunity> opps = new List<Opportunity>();
    Map<Id, Task> oppToTaskMap = new Map<Id, Task>();

    for (Task t : Trigger.new) {
        if (
            t.Subject.startsWith('Outbound call') ||
            t.Subject.startsWith('Inbound call')
        ) {
            oppToTaskMap.put(t.WhatId, t);
        }
    }

    for (Id oppId : oppToTaskMap.keySet()) {
        Task t = oppToTaskMap.get(oppId);

        opps.add(new Opportunity(
            Agent__c = t.OwnerId,
            opp.LastActivityDate = t.LastModifiedDate.date()
        ));
    }

    if (!opps.isEmpty()) {
        update opps;
    }
}
Salesforce AdminSalesforce Admin
Hi Pcon,

Thanks for the updated code. The code seems to work but still gives this error:

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger TaskAfterInsertUpdate caused an unexpected exception, contact your administrator: TaskAfterInsertUpdate: execution of BeforeInsert caused by: System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []: Trigger.TaskAfterInsertUpdate: line 24, column 1

This is my updated code. Please help. Cheers. Plus the date field does not recognize it.(//Date__c = t.LastModifiedDate.date())
 
trigger TaskAfterInsertUpdate on Task (before update, before insert) {
    List<Opportunity> opps = new List<Opportunity>();
    Map<Id, Task> oppToTaskMap = new Map<Id, Task>();

    for (Task t : Trigger.new) {
        if (
            t.Subject.startsWith('Outbound call') ||
            t.Subject.startsWith('Inbound call')
        ) {
            oppToTaskMap.put(t.WhatId, t);
        }
    }

    for (Id oppId : oppToTaskMap.keySet()) {
        Task t = oppToTaskMap.get(oppId);

        opps.add(new Opportunity(
            Agent__c = t.OwnerId
            //Date__c = t.LastModifiedDate.date()
        ));
    }

        if (!opps.isEmpty()) {
        update opps;
    }
}

 
pconpcon
Sorry, line 17-19 should read
 
opps.add(new Opportunity(
    Id = oppId,
    Agent__c = t.OwnerId
    Date__c = t.LastModifiedDate
));

That is assuming that Date__c is actually a type of DateTime
Salesforce AdminSalesforce Admin

Thanks Pcon, I got it working by:
 
trigger TaskAfterInsertUpdate on Task (before update, after insert) {
List<Opportunity> opps = new List<Opportunity>();
Map<Id, Task> oppToTaskMap = new Map<Id, Task>();

for (Task t : Trigger.new) 
{
system.debug('trigger.new' + trigger.new);
if (t.Subject.startsWith('Outbound call') || t.Subject.startsWith('Inbound call')) 
{
oppToTaskMap.put(t.WhatId, t);
}
}
List<Opportunity> opps1 = [SELECT Id, Agent__c,Date__c FROM Opportunity WHERE Id =: oppToTaskMap.keySet()];

for (Opportunity opp2 : opps1) 
{
Task t = oppToTaskMap.get(opp2.Id);
List<User> nam1 = [SELECT name FROM User WHERE Id =: t.OwnerId];
opp2.Agent__c = nam1[0].name;
opp2.Date__c = t.LastModifiedDate;
opps.add(opp2);
}

update opps;
}


Thanks for your help.

:)


 
pconpcon
I've taken the liberty of updating your trigger to make it better suited for bulk transactions.
 
trigger TaskAfterInsertUpdate on Task (before update, after insert) {
    Set<Id> ownerIds = new Set<Id>();
    Map<Id, Task> taskMap = new Map<Id, Task>();

    for (Task t : Trigger.new) {
        if (
            t.Subject.startsWith('Outbound call') ||
            t.Subject.startsWith('Inbound call')
        ) { 
            taskMap.put(t.WhatId, t);
            ownerIds.add(t.OwnerId);
        } 
    }   

    if (!taskMap.isEmpty()) {
        Map<Id, User> userMap = new Map<Id, User>([
            select Name
            from User
            where Id in :ownerIds
        ]);

        List<Opportunity> oppsToUpdate = new List<Opportunity>();

        for (Opportunity opp : [
            select Agent__c, Date__c
            from Opportunity
            where Id in :taskMap.keySet()
        ]) {
            Task t = taskMap.get(opp.Id);
            opp.Agent__c = userMap.get(t.OwnerId);
            opp.Date__c = t.LastModifiedDate;
            oppsToUpdate.add(opp);
        }  

        if (!oppsToUpdate.isEmpty()) {
            update oppsToUpdate;
        }
    }
}
NOTE: This code has not been tested and may contain typographical or logical errors
This was selected as the best answer
Salesforce AdminSalesforce Admin
Thanks Pcon, this was really helpful. :)
pconpcon
Great! If you don't mind, please choose a "Best Answer" so that this question can be removed from the unresolved queue.