You need to sign in to do that
Don't have an account?
Trigger Problem
Hi all i have this trigger where i want to update some values on an opp based on values in the opps line items but im getting the "maximum trigger depth exceeded" error but i dont really know how to resolve it, can anyone see what i can do here?
trigger opportunitySubTotalSummaryTrigger2 on Opportunity (after insert, after update)
{
list<id> OppIds = new list<id>();
list<Opportunity> oppsWithLineItems = new list<Opportunity>();
list<Opportunity> oppsToUpdate = new list<Opportunity>();
for(Opportunity o : trigger.new)
{
if(o.HasOpportunityLineItem == true)
OppIds.add(o.id);
}
oppsWithLineItems = [Select o.System_Revenue_2__c, System_Margin_2__c, CS_Revenue_2__c, CS_Margin_2__c, PS_Revenue_2__c, PS_Margin_2__c, o.Name, o.Id, (Select Id, OpportunityId, SortOrder, PricebookEntryId, CurrencyIsoCode, Quantity, TotalPrice, UnitPrice, ListPrice, ServiceDate, Description, Unit_Cost_Price__c, Unit_List_Price__c, Vendor_Quote_Reference__c, Vendor_Registration__c, Total_Cost_Price__c, Total_List_Price__c, Total_Sell_Price__c, Total_Product_Margin__c, Margin_percent__c, Test_Type__c, Type__c, CS_Revenue__c, CS_Margin__c, System_Revenue__c, PS_Margin__c, PS_Revenue__c, System_Margin__c, Other_Revenue__c, Other_Margin__c From OpportunityLineItems) From Opportunity o where o.HasOpportunityLineItem = true and id in :oppIds];
for(Opportunity o : oppsWithLineItems)
{
for(OpportunityLineItem oli : o.OpportunityLineItems)
{
o.System_Revenue_2__c += oli.System_Revenue__c;
}
}
update(oppsWithLineItems);
}
Thanks All
Just interchange your last two lines of your logic.
You should be setting the flag to false before firing the DML. This way when the trigger is fired again, the condition will evaluate to false.
Thanks,
Anoop
All Answers
you're in an infinite loop, you'll keep updating your oportunity object and keep increasing the system_reveue.
Think of a condition to use, and only update the oportunities for which the condition is met. As a side note, are you taking into account a decrease of system_revenue_2 when a line item is deleted ?
Hi yeah the problem is i dont know how to not be an infintite loop, basically the trigger is just creating a roll up value on the opp, but i dont know how to say that this trigger has already fired dont execute again.
You can verify if the system_revenye_2__c field on opportunity already equals the roll up of the values of all system_revenue__c fields on the lineitems. If this is already the case, an update is not required.
Hey Micky,
All you need is to create and initialize (to either true or false) a static flag in one of your classes.
Your trigger logic should be wrapped inside the condition, which will evaluate to true only if your flag holds the same value which you initialized.
And before you fire the DML on opportunity, switch your flag.
I believe this should do the trick.
Thanks,
Anoop
Thanks for the help guys, ive just tried this:
here's my clase with a flag
public with sharing class staticFlagsForRecursionTriggers
{
public static boolean firstRun = true;
}
//Trigger Code
if(staticFlagsForRecursionTriggers.firstRun)
{
list<id> OppIds = new list<id>();
list<Opportunity> oppsWithLineItems = new list<Opportunity>();
list<Opportunity> oppsToUpdate = new list<Opportunity>();
for(Opportunity o : trigger.new)
{
if(o.HasOpportunityLineItem == true)
OppIds.add(o.id);
}
oppsWithLineItems = [Select o.System_Revenue_2__c, System_Margin_2__c, CS_Revenue_2__c, CS_Margin_2__c, PS_Revenue_2__c, PS_Margin_2__c, o.Name, o.Id, (Select Id, OpportunityId, SortOrder, PricebookEntryId, CurrencyIsoCode, Quantity, TotalPrice, UnitPrice, ListPrice, ServiceDate, Description, Unit_Cost_Price__c, Unit_List_Price__c, Vendor_Quote_Reference__c, Vendor_Registration__c, Total_Cost_Price__c, Total_List_Price__c, Total_Sell_Price__c, Total_Product_Margin__c, Margin_percent__c, Test_Type__c, Type__c, CS_Revenue__c, CS_Margin__c, System_Revenue__c, PS_Margin__c, PS_Revenue__c, System_Margin__c, Other_Revenue__c, Other_Margin__c From OpportunityLineItems) From Opportunity o where o.HasOpportunityLineItem = true and id in :oppIds];
for(Opportunity o : oppsWithLineItems)
{
for(OpportunityLineItem oli : o.OpportunityLineItems)
{
o.System_Revenue_2__c += oli.System_Revenue__c;
}
oppsToUpdate.add(o);
}
system.debug('oppsToUpdate' + oppsToUpdate);
update(oppsToUpdate);
staticFlagsForRecursionTriggers.firstRun = false;
}
and here's the error (which is a bit long but it will probably give you a clue, i cant really see what im doing wrong.
Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger opportunitySubTotalSummaryTrigger2 caused an unexpected exception, contact your administrator: opportunitySubTotalSummaryTrigger2: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 006M0000004SrlDIAS; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, opportunitySubTotalSummaryTrigger2: maximum trigger depth exceeded Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD] Opportunity trigger event AfterUpdate for [006M0000004SrlD]: []: Trigger.opportunitySubTotalSummaryTrigger2: line 26, column 1
Just interchange your last two lines of your logic.
You should be setting the flag to false before firing the DML. This way when the trigger is fired again, the condition will evaluate to false.
Thanks,
Anoop
oh yeah thats got it!! cheers for that! just another quick question, when does the static variable get set back to true? you know when i hit save again? what is it that resets the variable?
Yes.
Hitting the save button is one of the cases which will re-initialize the flag.
Basically any fresh insert or update which invokes a new instance will reset the flag to the initial value.
Thanks,
Anoop
Excellent! thanks for all your help guys!! thats ace.
Hi ashok cant we declare a flag = true with in the trigger and switch it when a condition is met ,Instead of using a class jst for the initating the flag variable do we need to use the class.
Hey Suree,
Lets assume we followed the below steps in order within the trigger.
1. Declare flag = true
2. Condition -> if flag = true, execute steps 3,4 and 5.
3. All the trigger logic.
4. set flag = false
5. update records.
Now the step 5 will again invoke the same trigger, and when it reaches line 1, the flag will be set to true. So your step 2 will evaluate to true, and this will repeat infinitely.
In case you're creating a new class, then in future when need arises you can use this class itself for similiar helper functionalities. Or, if you've any light weight classes which is already in place, you can even use that for keeping this flag. Either way, it doesn't make much of a difference I believe.
I believe I answered your question. :-)
Thanks,
Anoop
Can any one please help me to write a trigger:
I Have to write a trigger which can pick up the latest date from record type and update a filed. Please reply soon