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
Justin.WilliamsJustin.Williams 

Trying to bulkify beforeupdate trigger and now it doesn't do anything.

Running my first 'beforeupdate' trigger. Not even sure which would be better for my process, before or after.  Anyway my original code seemed too simple like it wasn't handling bulkification enough.  So I added an soql at the beginning and then did a for loop off of that.  It worked before I added the soql/for loop combination, now it saves the code fine but nothing happens.

 

Its a nested SOQL statement because I plan on referencing the opportunitycontactrole data in later versions to see if they have contacts of a certain type.

 

trigger CPMeStageChange on Opportunity (before insert, before update) {

    list<Opportunity> o = [select id, StageName, Prior_Stage__c, Date_Stage_Last_Updated__c, Engagement_Letter_Signed__c, X80_Gate_Status__c, X70_Gate_Status__c, X50_Gate_Status__c, X40_Gate_Status__c, X30_Gate_Status__c, X20_Gate_Status__c, X10_Gate_Status__c,
                           (select opportunityID, Contact.FirstName from OpportunityContactRoles where Role = 'Internal Supporter') from opportunity where id in:trigger.new];
    
    for (Opportunity CPMOpp: o) {
        if ( CPMOpp.Engagement_Letter_Signed__c==null){
               if (CPMOpp.StageName !='Engagement' && CPMOpp.X80_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Engagement';
               } else if(CPMOpp.StageName !='Verbal Agreement - Date Agreed' && CPMOpp.X70_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Verbal Agreement - Date Agreed';
               } else if(CPMOpp.StageName !='Verbal Agreement - No Date' && CPMOpp.X50_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Verbal Agreement - No Date';
               } else if(CPMOpp.StageName !='Pilot Project' && CPMOpp.X40_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Pilot Project';
               } else if(CPMOpp.StageName !='Negotiation - No Date' && CPMOpp.X30_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Negotiation - No Date';
               } else if(CPMOpp.StageName !='Owner Mandated' && CPMOpp.X20_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Owner Mandated';
               } else if(CPMOpp.StageName !='Sales Process' && CPMOpp.X10_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Sales Process';
               }
            }
        }

 

Tim BarsottiTim Barsotti

What are you trying to accomplish? 

 

All of the opportunity fields are available in the trigger.new list. Not seeing the need for the SOQL query as you are not using any of the OCRole data.

 

trigger CPMeStageChange on Opportunity (before insert, before update) {

    for (Opportunity CPMOpp: trigger.new) {
        if ( CPMOpp.Engagement_Letter_Signed__c==null){
               if (CPMOpp.StageName !='Engagement' && CPMOpp.X80_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Engagement';
               } else if(CPMOpp.StageName !='Verbal Agreement - Date Agreed' && CPMOpp.X70_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Verbal Agreement - Date Agreed';
               } else if(CPMOpp.StageName !='Verbal Agreement - No Date' && CPMOpp.X50_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Verbal Agreement - No Date';
               } else if(CPMOpp.StageName !='Pilot Project' && CPMOpp.X40_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Pilot Project';
               } else if(CPMOpp.StageName !='Negotiation - No Date' && CPMOpp.X30_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Negotiation - No Date';
               } else if(CPMOpp.StageName !='Owner Mandated' && CPMOpp.X20_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Owner Mandated';
               } else if(CPMOpp.StageName !='Sales Process' && CPMOpp.X10_Gate_Status__c == 'Complete'){
                   CPMOpp.Prior_Stage__c = CPMOpp.StageName;
                   CPMOpp.Date_Stage_Last_Updated__c = System.today();
                   CPMOpp.StageName = 'Sales Process';
               }
            }
        }

 

 

 

Justin.WilliamsJustin.Williams

Is that still considered bulkified?

 

I am putting one of my sales processes into apex because I have hit my limit for Opportunity workflows.  There are a series of 10 gates each with a set of fields that need to be filled in to be considered complete.  Formula fields determine if a gate is complete and the trigger goes off those formula fields.  The gate completions can go forward, backward or jump around but the most advanced complete gate labels the current stage.

 

I was trying to include OppConRole data because one of the gates relies on a specific role to be identified so I was going to query through related oppConRoles to see if o.opportunitycontactroles.size!=0.  Thats why I have the joined SOQL statement.  I didn't want to put the SOQL in the for loop because thats bad programming but I don't know how else to do it.

Tim BarsottiTim Barsotti

OK. Thanks for the explanation. 

 

Yes this trigger is bulkified - it will handle 200 records no problem. It does not perform any dml and just alters the records prior to them being inserted. Granted, there are more elogant ways to handle this type of logic (expression design), but this is simple and works. 

 

The SOQL query you have will not work on a (before insert) trigger. Reason being is the records have no ID prior to insert. They do have an however have IDs for (after Insert) operations. 

 

Recommend you consider leaving the one that requires the contact role to be entered as a workflow rule for sake of ease.

Justin.WilliamsJustin.Williams

Opportunity Contact Roles cannot be accessed by workflow rules otherwise I would.

Tim BarsottiTim Barsotti

Try this... 

 

trigger CPMeStageChange on Opportunity (before insert, before update, after Insert) {
if(trigger.isBefore) { for (Opportunity CPMOpp: trigger.new) { if ( CPMOpp.Engagement_Letter_Signed__c==null){ if (CPMOpp.StageName !='Engagement' && CPMOpp.X80_Gate_Status__c == 'Complete'){ CPMOpp.Prior_Stage__c = CPMOpp.StageName; CPMOpp.Date_Stage_Last_Updated__c = System.today(); CPMOpp.StageName = 'Engagement'; } else if(CPMOpp.StageName !='Verbal Agreement - Date Agreed' && CPMOpp.X70_Gate_Status__c == 'Complete'){ CPMOpp.Prior_Stage__c = CPMOpp.StageName; CPMOpp.Date_Stage_Last_Updated__c = System.today(); CPMOpp.StageName = 'Verbal Agreement - Date Agreed'; } else if(CPMOpp.StageName !='Verbal Agreement - No Date' && CPMOpp.X50_Gate_Status__c == 'Complete'){ CPMOpp.Prior_Stage__c = CPMOpp.StageName; CPMOpp.Date_Stage_Last_Updated__c = System.today(); CPMOpp.StageName = 'Verbal Agreement - No Date'; } else if(CPMOpp.StageName !='Pilot Project' && CPMOpp.X40_Gate_Status__c == 'Complete'){ CPMOpp.Prior_Stage__c = CPMOpp.StageName; CPMOpp.Date_Stage_Last_Updated__c = System.today(); CPMOpp.StageName = 'Pilot Project'; } else if(CPMOpp.StageName !='Negotiation - No Date' && CPMOpp.X30_Gate_Status__c == 'Complete'){ CPMOpp.Prior_Stage__c = CPMOpp.StageName; CPMOpp.Date_Stage_Last_Updated__c = System.today(); CPMOpp.StageName = 'Negotiation - No Date'; } else if(CPMOpp.StageName !='Owner Mandated' && CPMOpp.X20_Gate_Status__c == 'Complete'){ CPMOpp.Prior_Stage__c = CPMOpp.StageName; CPMOpp.Date_Stage_Last_Updated__c = System.today(); CPMOpp.StageName = 'Owner Mandated'; } else if(CPMOpp.StageName !='Sales Process' && CPMOpp.X10_Gate_Status__c == 'Complete'){ CPMOpp.Prior_Stage__c = CPMOpp.StageName; CPMOpp.Date_Stage_Last_Updated__c = System.today(); CPMOpp.StageName = 'Sales Process'; } } }
}
if(trigger.isAfter) {
List<Opportunity> oList = [select id, StageName, Prior_Stage__c, Date_Stage_Last_Updated__c, Engagement_Letter_Signed__c, X80_Gate_Status__c, X70_Gate_Status__c, X50_Gate_Status__c, X40_Gate_Status__c, X30_Gate_Status__c, X20_Gate_Status__c, X10_Gate_Status__c,
(select opportunityID, Contact.FirstName from OpportunityContactRoles where Role = 'Internal Supporter') from opportunity where id in:trigger.newMap.KeySet()];
List<Opportunity> oppsToUpdate = new List<Opportunity>();
for(Opportunity o: oList) {
if(o.OpportunityContactRoles.size()==0) {
//do something
oppsToUpdate.add(o);
}
}
update oppsToUpdate;
}
}