Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

Hello and thank you for your time.

I have created a trigger on an opportunity that 'should' only run my methods if the stageName = 'PO IN(100%) and a contract is not already created.. as well if certain fields are not null. I get I should do my error checking on the if(trigger.isbefore) and then run my actual methods on the if(trigger.isafter) I am just confused on how I can :

  1. Disregard any updated opportunity that doesn't meet the criteria of 'PO In 100%'
  2. Make sure the trigger.old isnt already 'PO In 100%'
  3. If there are errors (fields are null or a child contract exists) do an addError() but allow the other triggers to run.

So far, I know how to get the opportunities and add them to a list (and put a child quote id if it exists)

 List<Id> oppIds = new List<Id>();
 List<ServiceContract> SContract = new List<ServiceContract>(); // List that will contain all the new Service Contracts that need to be added
 for(Opportunity opp:Trigger.new){
   if(Trigger.oldMap.get(opp.id).StageName != 'PO In (100%)' && opp.StageName == 'PO In (100%)') //This should take care of my first & second Step      
      oppIds.add(opp.Id);
 }
List<Opportunity> oppsFromDb =  [SELECT
                                Id, StageName, name, Accountid, owner__c, end_user_contact__c, RecordTypeId, OwnerId,
                                                (SELECT Id FROM Service_Contracts__r), (SELECT Id From Quotes)
                                FROM
                                Opportunity 
                                WHERE
                                Id IN:oppIds
                                ];

Now I imagine is the time to use the before Update

if(Trigger.isBefore){
  for(Opportunity verifyOpps: oppsFromDb){
    if(verifyOpps.Service_Contracts__r.size() != 0) { //A contract child exists
      verifyOpps.addError('A contract already exists, cannot create a new contract.');
    }
    //.... other error checking code
   verifyOpps.save() // I have no idea how to save the record.. 
  }
}
else if(Trigger.isAfter){
  for(Opportunity GoodOpps: oppsFromDb){
    // create a contract using the opp variables and other calculations
    SContract.add(the_Contract);
  }
}
insert SContract;

If a contract does exist it should run the opp.addError. Does this mean i need to do an else and put the ones without errors in a new list, so only they go into the isafter trigger?

And by just doing opp.addError, does it automatically give the error or do i have to do something else for it to go back into the db? (Sorry if this is confusing).

Does this code make sense at all? Or am I doing this very wrong :)

Thanks again for your time.

share|improve this question

1 Answer 1

up vote 3 down vote accepted

This should work properly. Take a look at the Salesforce Order of Execution. Every time a record is saved, that record will run through this entire process. You will notice that the before trigger will run before a save (not a commit) happens to the server. When it goes to run that save, it will see that an error has been added and that record failed. It will fail out of the process and not run any of the after triggers.

So, essentially, you have it working fine. That trigger will actually get run multiple times during a single save.

share|improve this answer
    
Thanks Jesse for the quick response! So I dont need to make a new list with only the 'good' opportunities? I can just run a for loop in the if(trigger.isbefore){ for(Opportunity checkerrors: opp){...} and then if(trigger.isafter){ for(Opportinty addgood: opp{...} ? This will make my life very easy –  jnoel10 Feb 20 '13 at 15:53
    
Exactly. There is no filtering required because your Trigger.isAfter is statement will only run the second time the trigger is called (after the record Save). If you addError before your Save, that Save will never occur and it will error out of the entire process. –  Jesse Altman Feb 20 '13 at 15:56
    
I am confused with the record save you are mentioning.. I will add it to code above in a moment. –  jnoel10 Feb 20 '13 at 16:09
    
added.. I did some research on the saving record but I am not finding anything.. –  jnoel10 Feb 20 '13 at 16:24
    
Take a look at the order of execution I linked to earlier - salesforce.com/us/developer/docs/apexcode/Content/…. This trigger is only running when you Save a record (either Insert or Update). Specifically, step 5. Notice how it saves the record (but does not commit). If the record has an error on it (which it would from the addError), that will fail and the rest of the Order of Execution will stop. –  Jesse Altman Feb 20 '13 at 16:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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