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
Steve Connelly 5Steve Connelly 5 

How do I limit my trigger to specific record types and field values?

I have a new trigger that creates a custom object record when an opportunity is created or updated.

Everything works but I need help with one thing. I only want it to run when a specific opportunity type is created or when that type has its "cloe date" field updated.

Here is my code:
trigger createOq on Opportunity (after insert, after update) {

    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c> (); 
     for(Opportunity opportunityList : trigger.New){
        
       Open_Quarter__c oq = new Open_Quarter__C();

        oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c; 
        oq.Close_Date_oq__c = opportunityList.CloseDate;
        oq.Name = opportunityList.Quarter_Created_op__c;
        oq.Opportunity_Name_oq__c = opportunityList.Id;
        oq.Quarters_Spanned_oq__c = opportunityList.Quarters_Spanned_op__c;
        
         createOpenQuarter.add(oq);

     }
 
    try {
            insert createOpenQuarter;
    } 
    catch (system.Dmlexception e) {
        system.debug (e);
    }
}

How do I limit this so it only runs when a "Sales" opp is created or when an existing Sales Opp has the "Close Date" field updated?

New to coding and apex so any help is greatly appreciated.

Best regards,
Steve​​​​​​​
Best Answer chosen by Steve Connelly 5
Alaric WimerAlaric Wimer

One more correction here, we want that try catch logic within the conditional as well.

 

trigger createOq on Opportunity (after insert, after update) {
    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>();
    for (Opportunity opportunityList : Trigger.new) {
        // On the next line, we add the conditional logic
        if (opportunityList.RecordTypeId == '01241000001USq9AAG' && (Trigger.isInsert || (Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate))) {
            Open_Quarter__c oq         = new Open_Quarter__C();
            oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c;
            oq.Close_Date_oq__c        = opportunityList.CloseDate;
            oq.Name                    = opportunityList.Quarter_Created_op__c;
            oq.Opportunity_Name_oq__c  = opportunityList.Id;
            oq.Quarters_Spanned_oq__c  = opportunityList.Quarters_Spanned_op__c;
            createOpenQuarter.add(oq);
            try {
                insert createOpenQuarter;
            }
            catch (system.Dmlexception e) {
                system.debug (e);
            }
        } // end conditional
    } // end for loop
} // end trigger

All Answers

Alaric WimerAlaric Wimer

Hi Steve,


You can try adding a conditional right after starting the Trigger.new for loop you have. We can us Trigger.isInsert(), Trigger.isUpdate(), and Trigger.oldMap to set the criteria you are looking for.

Here's an example:

 

trigger createOq on Opportunity (after insert, after update) {

    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>(); 
    
    for (Opportunity opportunityList : trigger.New) {
        // On the next line, we add the conditional logic
        if ((Trigger.isInsert() && opportunityList.RecordTypeId == 'SALES RECORD TYPE ID HERE') || (Trigger.isUpdate() && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate)) {
            Open_Quarter__c oq          = new Open_Quarter__C();
            oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c; 
            oq.Close_Date_oq__c         = opportunityList.CloseDate;
            oq.Name                     = opportunityList.Quarter_Created_op__c;
            oq.Opportunity_Name_oq__c   = opportunityList.Id;
            oq.Quarters_Spanned_oq__c   = opportunityList.Quarters_Spanned_op__c;
            createOpenQuarter.add(oq);
        }

        try {
            insert createOpenQuarter;
        } 
        catch (system.Dmlexception e) {
            system.debug (e);
        }
    }
}

 

coddy niccoddy nic
I was able to work on this and get it working. I think one of the issues was that i was trying to call agmt.RecordType.DeveloperName, but it was returning a null value. I had to create a RecordType variable using the Id found in the agmt record and also a separate RecordType variable with the record type I was running the if statement against and compare the two. Here is the code that ended up working for me.


trigger IntakeFormTrigger on Apttus__APTS_Agreement__c (before insert, before update) { Map<String, Id> typeMap = New Map<String, Id>();                    for(RecordType rt: [Select DeveloperName, Id From Record
                        Type Where sObjectType = 'Apttus__APTS_Agreement__c'])
                             { typeMap.put(rt.DeveloperName, rt.Id);
}
for (Apttus__APTS_Agreement__c agmt : trigger.new) {
                         recordtype agmtRT = [select id, developername from recordtype where id=:agmt.
                         recordtypeid]; recordtype IFRT = [select id, developername from recordtype where developername = 'Intake_Form']; \
                         // If the Record Type = Intake Form 
                         if (agmtRT.id == IFRT.id) { // And the Agreement Category on the record = Services if (agmt.Apttus__Agreement_Category__c == 'Services') {
                                 // Then automatically change the Record Type to Services Agreement.
                                  id recid = typeMap.get('Services_Agreement');
                                  recordtype rectype = [select id, developername from recordtype where id=:recid];
                                  agmt.RecordTypeid = rectype.id;
                                 }
                            } 
                    }
            }




_________________________________________________________________________________________
https://www.prepaidcardstatus.net/
Steve Connelly 5Steve Connelly 5
@Alaric Wimer,

I inserted your changes and I get a couple of errorsd I have not sorted out.

Here is the code:
trigger createOq on Opportunity (after insert, after update) {
 
    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>();
     
    for (Opportunity opportunityList : trigger.New) {
        
        // On the next line, we add the conditional logic
        if ((Trigger.isInsert() && opportunityList.RecordTypeId == '01241000001USq9AAG') || 
(Trigger.isUpdate() && opportunityList.CloseDate != 
 Trigger.oldMap.get(opportunityList.Id).CloseDate)) {
            Open_Quarter__c oq         = new Open_Quarter__C();
            oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c;
            oq.Close_Date_oq__c        = opportunityList.CloseDate;
            oq.Name                    = opportunityList.Quarter_Created_op__c;
            oq.Opportunity_Name_oq__c  = opportunityList.Id;
            oq.Quarters_Spanned_oq__c  = opportunityList.Quarters_Spanned_op__c;
            createOpenQuarter.add(oq);
        }
 
        try {
            insert createOpenQuarter;
        }
        catch (system.Dmlexception e) {
            system.debug (e);
        }
    }
}

I get these errors:
User-added image

Do I need to call this trigger elsewhere? It is interesting that it does not also error out on line 10.
Sc
​​​​​​​
Steve Connelly 5Steve Connelly 5
Dissregard what I said about line 10. My mistake.
Sc
Alaric WimerAlaric Wimer

Hi Steve, I believe isUpdate and isInsert are actually variables and not methods on Trigger, so the () are likely causing the error. So how about we try removing those parentheses. So it will look like the following:

 

trigger createOq on Opportunity (after insert, after update) {
    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>();
    for (Opportunity opportunityList : Trigger.new) {
        // On the next line, we add the conditional logic
        if ((Trigger.isInsert && opportunityList.RecordTypeId == '01241000001USq9AAG') || (Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate)) {
            Open_Quarter__c oq         = new Open_Quarter__C();
            oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c;
            oq.Close_Date_oq__c        = opportunityList.CloseDate;
            oq.Name                    = opportunityList.Quarter_Created_op__c;
            oq.Opportunity_Name_oq__c  = opportunityList.Id;
            oq.Quarters_Spanned_oq__c  = opportunityList.Quarters_Spanned_op__c;
            createOpenQuarter.add(oq);
        } // end conditional
        try {
            insert createOpenQuarter;
        }
        catch (system.Dmlexception e) {
            system.debug (e);
        }
    } // end for loop
} // end trigger
Steve Connelly 5Steve Connelly 5
That resolved the errors, thanks!

So, the problem is that while this does limit the trigger to Sales Opps for new opps.

It does not limit the trigger to Close Date updates only for Sales Opps.

That was probably my fault for not clarifying.

I need this to
  • Only execute for new "Sales" Opps (accomplished)
  • Only execute for existing Sales Opps when the close date field is updated
Right now it runs when any opp has the Close Date field updated.

Is there a way to limit that too?

Sc
Alaric WimerAlaric Wimer

Hi Steve, yea absolutely. In that case, we just need to update the conditional slightly as such:

 

trigger createOq on Opportunity (after insert, after update) {
    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>();
    for (Opportunity opportunityList : Trigger.new) {
        // On the next line, we add the conditional logic
        if (opportunityList.RecordTypeId == '01241000001USq9AAG' && (Trigger.isInsert || (Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate))) {
            Open_Quarter__c oq         = new Open_Quarter__C();
            oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c;
            oq.Close_Date_oq__c        = opportunityList.CloseDate;
            oq.Name                    = opportunityList.Quarter_Created_op__c;
            oq.Opportunity_Name_oq__c  = opportunityList.Id;
            oq.Quarters_Spanned_oq__c  = opportunityList.Quarters_Spanned_op__c;
            createOpenQuarter.add(oq);
        } // end conditional
        try {
            insert createOpenQuarter;
        }
        catch (system.Dmlexception e) {
            system.debug (e);
        }
    } // end for loop
} // end trigger
Alaric WimerAlaric Wimer

One more correction here, we want that try catch logic within the conditional as well.

 

trigger createOq on Opportunity (after insert, after update) {
    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>();
    for (Opportunity opportunityList : Trigger.new) {
        // On the next line, we add the conditional logic
        if (opportunityList.RecordTypeId == '01241000001USq9AAG' && (Trigger.isInsert || (Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate))) {
            Open_Quarter__c oq         = new Open_Quarter__C();
            oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c;
            oq.Close_Date_oq__c        = opportunityList.CloseDate;
            oq.Name                    = opportunityList.Quarter_Created_op__c;
            oq.Opportunity_Name_oq__c  = opportunityList.Id;
            oq.Quarters_Spanned_oq__c  = opportunityList.Quarters_Spanned_op__c;
            createOpenQuarter.add(oq);
            try {
                insert createOpenQuarter;
            }
            catch (system.Dmlexception e) {
                system.debug (e);
            }
        } // end conditional
    } // end for loop
} // end trigger
This was selected as the best answer
Steve Connelly 5Steve Connelly 5
Unfortunately, the problem persists.
Sc
Steve Connelly 5Steve Connelly 5
So, when I change this:
if (opportunityList.RecordTypeId == '01241000001USq9AAG' && (Trigger.isInsert || (Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate)))

to this: (removing this: (Trigger.isInsert ||)
if (opportunityList.RecordTypeId == '01241000001USq9AAG' && (Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate

It does limit the change to Close Field on the correct record type only.

I just don't know where that leaves me with only firing on the correct record type when new.​​​​​​​ It appears that the issue is with the "OR" maybe.
​​​​​​​Sc
Steve Connelly 5Steve Connelly 5
So, I redid this line to include the record type + new, and record type + update as two separate statements with an "OR" like so
 
trigger createOq on Opportunity (after insert, after update) {
    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>();
    for (Opportunity opportunityList : Trigger.new) {
        
        // On the next line, we add the conditional logic
        if ((opportunityList.RecordTypeId == '01241000001USq9AAG' && Trigger.isInsert) || 
            (opportunityList.RecordTypeId == '01241000001USq9AAG' && Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate)) {
            Open_Quarter__c oq         = new Open_Quarter__C();
            oq.Amount_Per_Quarter_oq__c = opportunityList.Amount_per_Quarter_op__c;
            oq.Close_Date_oq__c        = opportunityList.CloseDate;
            oq.Name                    = opportunityList.Quarter_Created_op__c;
            oq.Opportunity_Name_oq__c  = opportunityList.Id;
            oq.Quarters_Spanned_oq__c  = opportunityList.Quarters_Spanned_op__c;
            
            createOpenQuarter.add(oq);
            try {
                insert createOpenQuarter;
            }
            catch (system.Dmlexception e) {
                system.debug (e);
            }
        } // end conditional
    } // end for loop
} // end trigger

It seems to work now so I think we got there together.

Marking yuou as Best Answer.

Thanks so much for all the help!
Steve
Alaric WimerAlaric Wimer

Hi Steve, that's great! You can also clean it up just a little by adding an "outer" conditional to first check for the Record type, and then proceeding to an "inner" conditional. This would avoid the repeating " RecordTypeId = '01241000001USq9AAG' "

 

Obviously, if you have it working then I wouldn't want to mess anything thing up. But you could always give it a shot:

 

trigger createOq on Opportunity (after insert, after update) {
    List <Open_Quarter__c> createOpenQuarter = new List <Open_Quarter__c>();
    for (Opportunity opportunityList : Trigger.new) {
        // record type conditional check
        if (opportunityList.RecordTypeId == '01241000001USq9AAG') {
            // rest of the conditional checks
            if (Trigger.isInsert || (Trigger.isUpdate && opportunityList.CloseDate != Trigger.oldMap.get(opportunityList.Id).CloseDate)) {
                Open_Quarter__c oq           = new Open_Quarter__C();
                oq.Amount_Per_Quarter_oq__c  = opportunityList.Amount_per_Quarter_op__c;
                oq.Close_Date_oq__c          = opportunityList.CloseDate;
                oq.Name                      = opportunityList.Quarter_Created_op__c;
                oq.Opportunity_Name_oq__c    = opportunityList.Id;
                oq.Quarters_Spanned_oq__c    = opportunityList.Quarters_Spanned_op__c;
                createOpenQuarter.add(oq);
                try {
                    insert createOpenQuarter;
                }
                catch (system.Dmlexception e) {
                    system.debug (e);
                }
            } // end rest of the conditional checks
        } // end record type conditional check
    } // end for loop
} // end trigger
 

Anyway, glad we could work it out. All the best

 

Steve Connelly 5Steve Connelly 5
Thanks again!

I feel like I learned something today.

Not bad for a Monday.

Sc