4

I am confused about using a Before or After Update trigger. The scenario is that I want to create a new task and relate it to an opportunity when it's updated with a Stage = 'Closed Won'.

From what I've read so far, you always need to use After Update trigger in such cases. But what if I use a before update trigger? I do have the opp Id in the database and I can use it to associate it to the newly created task. When the opp is saved , the task will be created as well. Am I missing something here in my logic?

trigger ClosedOpportunityTrigger on Opportunity (after insert, before update) {

//Create a list to hold all opportunities for which tasks need to be created
List<Opportunity> oppList = new List<Opportunity>();

for(Opportunity opp: Trigger.new) {

    if(Trigger.isInsert)    {
        if(opp.StageName=='Closed Won') {
            oppList.add(opp);
        }
    }

       //Make sure trigger only works on updated Opportunities 
       where old value != new value
       else {

        Opportunity oldOpp  = Trigger.oldMap.get(opp.Id);
        Boolean oldOppIsWon = oldOpp.StageName.equals('Closed Won');
        Boolean newOppIsWon = opp.StageName.equals('Closed Won');

        if(!oldOppIsWon && newOppIsWon) {

            oppList.add(opp);
        }
    }

  }

List<Task> taskList = new List<Task>();
for(Opportunity opp :oppList) {

    Task t        = new Task();
    t.WhatId      = opp.Id;
    t.Subject     = 'Follow up test task';
    t.Priority    = 'Normal';
    t.Status      = 'Not Started';
    taskList.add(t);
}

insert taskList;

}
2
  • With respect to your trigger code, Just a couple things to be aware of... Do you have any stages beyond closed-won and/or does your workflow allow you to move it back from closed-won to a prior value? I once did a similar trigger and we added a check to make certain it hadn't ever previously been set to closed-won or else added a rule that didn't allow it to be moved back (don't recall which).
    – crmprogdev
    Commented Mar 26, 2015 at 16:16
  • Yes our workflow does allow it to be moved back from closed won to a prior value. Commented Mar 26, 2015 at 19:47

2 Answers 2

3

You can absolutely use an before trigger for that and it will work. That said, I typically leave the before trigger to the simpler functionality. IMO, updates to and validations against the records being acted on should happen in the before trigger, most everything else like cross object logic and callouts/emails/etc. should happen after. But there is nothing that says you can't create records before if you desire.

2

While its true that you can do what you propose, the issue with using a Before trigger would be if the update failed for some reason. There may be something in your workflow that could ultimately cause the update to fail. If that happens, you'll have created a task where the Opp.Stage != Stage = 'Closed Won' which is not the desired outcome. For that reason, I'd recommend sticking with a an After trigger.

2
  • I don't understand how that could happen. If the record fails to update, how will it create a new task? I did what you suggested (made the update fail by inserting a string into the Amount field) and a new task wasn't created. Please see the code in my edited OP. Also, any input on how to improve this or bulkify it will be much appreciated =) Commented Mar 26, 2015 at 16:00
  • Before Update triggers fire before a record is Updated. They don't necessarily require the record to be Updated for them to be successful. They do their work and then the next (if any) trigger fires. As I understand it, "it depends" on how the record update occurs as to whether or not anything else will be rolled back or not. Usually a Before trigger operates on trigger.new. In your case, it creates a record on a different object.
    – crmprogdev
    Commented Mar 26, 2015 at 16:06

You must log in to answer this question.

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