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
Brandon WolfeBrandon Wolfe 

Apex Trigger Not Sending Tasks Properly

I am a newbie when it comes to Apex development, but I am trying to deploy a trigger that sends a task and an email when an opportunity is marked as won. Half of the trigger is working properly, but the most important half is not. Any help is greatly appreciated!

I have a custom field on the Account level named "Customer_Success_Owner_Name__c". The field is a formula that takes another field and returns the name "Brandon", "Kyle", or "Oz". Based on the name in that field, the trigger should create a task and send an email to the correct user, as well as do the same for our finance officer.

The "Open a Payment Record" task is sending correctly. The "Open a Subscription" is acting sporadic and not sending to the correct user when it does actually send.
 
/*Open a Task on Account on a closed won Opportunity */

trigger OpenAccountTask on Opportunity (after update){
    
    List<Id> AccountId = new List<Id>();
    
    for(Integer i = 0; i < trigger.size; i++){
        if(trigger.new[i].StageName == 'Closed Won' && trigger.new[i].StageName != trigger.old[i].StageName)
            AccountId.add(trigger.new[i].AccountId);
    }
    
    if(!AccountId.isEmpty()){
        Task[] tasksToInsert = new Task[]{};
        Map<Id,Account> GetAccountById = new Map<Id,Account>();
        for(Account a : [SELECT Id, Name, Customer_Success_Owner_Name__c, OwnerId FROM Account WHERE Id IN :AccountId]){
            GetAccountById.put(a.Id,a);
        }
        for(Integer i = 0; i < trigger.size; i++){

            /*US Task for Brandon */
            if(trigger.new[i].StageName == 'Closed Won' && trigger.new[i].StageName != trigger.old[i].StageName && (GetAccountById.get(trigger.new[i].AccountId).Customer_Success_Owner_Name__c == 'Brandon')){
                tasksToInsert.add(new Task(WhatId=trigger.new[i].AccountId, OwnerID='005700000023zFI', Subject='Open a Subscription',ActivityDate=Date.Today()));
                tasksToInsert.add(new Task(WhatId=trigger.new[i].AccountId, OwnerID='005700000026xbg', Subject='Open a Payment record',ActivityDate=Date.Today()));
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();              
                mail.setTargetObjectId('005700000023zFI');
                mail.setSubject('Open a Subscription for ' + GetAccountById.get(trigger.new[i].AccountId).Name);
                mail.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + trigger.new[i].AccountId);
                mail.setSaveAsActivity(false);
                Messaging.SingleEmailMessage mail2 = new Messaging.SingleEmailMessage();
                mail2.setTargetObjectId('005700000026xbg');
                mail2.setSaveAsActivity(false);
                mail2.setSubject('Open a Payment record for ' + GetAccountById.get(trigger.new[i].AccountId).Name);
                mail2.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + trigger.new[i].AccountId);
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail,mail2 });
            }

            /*US & EMEA Task for Kyle*/
            else if(trigger.new[i].StageName == 'Closed Won' && trigger.new[i].StageName != trigger.old[i].StageName && (GetAccountById.get(trigger.new[i].AccountId).Customer_Success_Owner_Name__c == 'Kyle')){
                tasksToInsert.add(new Task(WhatId=trigger.new[i].AccountId, OwnerID='00570000003DXJb', Subject='Open a Subscription',ActivityDate=Date.Today()));
                tasksToInsert.add(new Task(WhatId=trigger.new[i].AccountId, OwnerID='005700000026xbg', Subject='Open a Payment record',ActivityDate=Date.Today()));
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                mail.setTargetObjectId('00570000003DXJb');
                mail.setSaveAsActivity(false);
                mail.setSubject('Open a Subscription for ' + GetAccountById.get(trigger.new[i].AccountId).Name);
                mail.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + trigger.new[i].AccountId);
                Messaging.SingleEmailMessage mail2 = new Messaging.SingleEmailMessage();
                mail2.setTargetObjectId('005700000026xbg');
                mail2.setSaveAsActivity(false);
                mail2.setSubject('Open a Payment record for ' + GetAccountById.get(trigger.new[i].AccountId).Name);
                mail2.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + trigger.new[i].AccountId);
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail,mail2 });
            }       

            /*AP & Enterprise Task for Oz*/
            else if(trigger.new[i].StageName == 'Closed Won' && trigger.new[i].StageName != trigger.old[i].StageName && (GetAccountById.get(trigger.new[i].AccountId).Customer_Success_Owner_Name__c == 'Oz')){
                tasksToInsert.add(new Task(WhatId=trigger.new[i].AccountId, OwnerID='00570000001XWfY', Subject='Open a Subscription',ActivityDate=Date.Today()));
                tasksToInsert.add(new Task(WhatId=trigger.new[i].AccountId, OwnerID='005700000026xbg', Subject='Open a Payment record',ActivityDate=Date.Today()));
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                mail.setTargetObjectId('00570000001XWfY');
                mail.setSaveAsActivity(false);
                mail.setSubject('Open a Subscription for ' + GetAccountById.get(trigger.new[i].AccountId).Name);
                mail.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + trigger.new[i].AccountId);
                Messaging.SingleEmailMessage mail2 = new Messaging.SingleEmailMessage();
                mail2.setTargetObjectId('005700000026xbg');
                mail2.setSaveAsActivity(false);
                mail2.setSubject('Open a Payment record for ' + GetAccountById.get(trigger.new[i].AccountId).Name);
                mail2.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + trigger.new[i].AccountId);
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail,mail2 });
            }
        }
        if(!tasksToInsert.isEmpty())
            Database.insert(tasksToInsert);     
    }
}

 
SlashApex (Luis Luciani)SlashApex (Luis Luciani)
Hi Brandon,

I started looking at your trigger and realized that you are hard coding several values in it. You should never hard code ids or names into code since this can change and then the code stops working.

If you need to have different logic depending on which user shows on the formula field, I would recommend creating other formula fields that reflect the correct owner for the tasks. Having the logic on formula fields make the code more flexible, however, you are still hard coding, so its still not an ideal solution. Here is an example:

New Fields on Account
  • OwnerId1_Formula__c - Formula field with the following logic:
    • CASE(Account.Customer_Success_Owner_Name__c,'Brandon','005700000023zFI','Kyle','00570000003DXJb',''Oz,'00570000001XWfY')
  • OwnerId2_Formula__c - Formula field with the following logic:
    • CASE(Account.Customer_Success_Owner_Name__c,'Brandon','005700000026xbg','Kyle','005700000026xbg',''Oz,'005700000026xbg')
/*Open a Task on Account on a closed won Opportunity */
trigger OpenAccountTask on Opportunity (after update)
{
    
    List<Id> accountIds = new List<Id>();
    
    for(Opportunity o : trigger.new)
    {
        if(o.StageName == 'Closed Won' && o.StageName != o.oldMap.get(o.Id).StageName)
            accountIds.add(o.AccountId);
    }
    
    if(!accountIds.isEmpty())
    {
        Task[] tasksToInsert = new Task[]{};
        Map<Id,Account> GetAccountById = new Map<Id,Account>([SELECT Id, Name, OwnerId1_Formula__c, OwnerId2_Formula__c FROM Account WHERE Id IN :accountIds]);

        for(Opportunity o : trigger.new)
        {
            /*US Task for Brandon */
            if(o.StageName == 'Closed Won' && o.StageName != o.oldMap.get(o.Id).StageName)
            {
                //GET the owners from the new formula fields
                string ownerId1 = GetAccountById.get(o.AccountId).OwnerId1_Formula__c;
                string ownerId2 = GetAccountById.get(o.AccountId).OwnerId2_Formula__c;

                tasksToInsert.add(new Task(WhatId=o.AccountId, OwnerID=ownerId1, Subject='Open a Subscription',ActivityDate=Date.Today()));
                tasksToInsert.add(new Task(WhatId=o.AccountId, OwnerID=ownerId2, Subject='Open a Payment record',ActivityDate=Date.Today()));

                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();              
                mail.setTargetObjectId(ownerId1);
                mail.setSubject('Open a Subscription for ' + GetAccountById.get(o.AccountId).Name);
                mail.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + o.AccountId);
                mail.setSaveAsActivity(false);
                Messaging.SingleEmailMessage mail2 = new Messaging.SingleEmailMessage();
                mail2.setTargetObjectId(ownerId2);
                mail2.setSaveAsActivity(false);
                mail2.setSubject('Open a Payment record for ' + GetAccountById.get(o.AccountId).Name);
                mail2.setPlainTextBody('You can view the details here:\n' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + o.AccountId);
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail,mail2 });
            }     
        }
        
        if(!tasksToInsert.isEmpty())
            Database.insert(tasksToInsert);     
    }
}

Hopefully I did not make any mistakes on the code, but this scenario should work for you and it is a little more flexible if any changes need to be made in the future.

Good luck!