You need to sign in to do that
Don't have an account?

CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, LineItemCreation: maximum trigger depth exceeded
I have created two triggers to affect the opportunity line item and opprtunity. Keep getting thrown that error and unsure where my bulkification has gone wrong.
LineItemCreation Trigger
OpportunityUpdate Trigger
LineItemCreation Trigger
trigger LineItemCreation on OpportunityLineItem (after insert, after update) { Product2 productsRef = new Product2(); Opportunity oppRef = new Opportunity(); String oliIdd; Decimal OliDayPrice; Integer daysDiff; List<OpportunityLineItemSchedule> OLISlist = new List<OpportunityLineItemSchedule>(); for(OpportunityLineItem OLI :Trigger.new){ OLIidd = OLI.Id; try{ productsRef = [SELECT Id, Basis__c, Family FROM Product2 WHERE Id =:OLI.Product2Id]; } catch(Exception e){ System.debug('The following exception has occurred: ' + e.getMessage()); } oppRef = [SELECT Id, Contract_Start_Date__c, Go_Live_Date__c, Contract_End_Date__c FROM Opportunity WHERE Id=:OLI.OpportunityId]; daysDiff = oppRef.Contract_Start_Date__c.daysBetween(oppRef.Contract_End_Date__c); System.Debug('DaysDifference = ' + daysDiff); OliDayPrice = (OLI.TotalPrice / daysDiff); System.Debug('Dailys Schedule Record Price = ' + oliDayPrice); Decimal totalPaid = 0; } for(Integer i=0; i < daysDiff; i++){ if((productsRef.Basis__c =='Per Site Per Month' || productsRef.Basis__c =='Per Device Per Month') && productsRef.Family=='Licensing'){ OpportunityLineItemSchedule OLISl = new OpportunityLineItemSchedule( OpportunityLineItemId=OLIidd, Revenue=OliDayPrice, ScheduleDate=(oppRef.Contract_Start_Date__c + i), //issue with it adding on revenue to saleprice Type='Revenue'); OLISlist.add(OLISl); } } if(trigger.isInsert || trigger.isUpdate){ if(!OLISlist.isEmpty()){ insert OLISlist; System.debug('List Inserted:' + OLISlist); } } }
OpportunityUpdate Trigger
trigger OpportunityUpdateTrigger on Opportunity (after update) { List<Product2> getProducts = new List<Product2>(); List<Opportunity> oldOpp = new List<Opportunity>(); List<Opportunity> newOpp = new List<Opportunity>(); List<OpportunityLineItemSchedule> getSchedules = new List<OpportunityLineItemSchedule>(); List<OpportunityLineItem> OLIlist = new List<OpportunityLineItem>(); Date conStartNew; Date conStartOld; Date conEndNew; Date conEndOld; Date goLiveNew; Date goLiveOld; set<Id> getOLI = new set<Id>(); set<Id> OLIid = new set<Id>(); for(Opportunity old : trigger.old){ //get oli and add to list conStartOld = old.Contract_Start_Date__c; conEndOld = old.Contract_End_Date__c; goLiveOld = old.Go_Live_Date__c; for(OpportunityLineItem OLI : [SELECT Id, Product2Id, Quantity FROM OpportunityLineItem WHERE OpportunityId=:old.Id]){ getOLI.add(OLI.Product2Id); OLIid.add(OLI.Id); OLIlist.add(OLI); } //GET PRODUCTS ADD TO LIST for(Product2 p : [SELECT Id, Basis__c, Family FROM Product2 WHERE Id=:getOLI AND Family='Licensing' AND (Basis__c='Per Device Per Month' OR Basis__c='Per Site Per Month')]){ getProducts.add(p); System.debug('products : ' + getProducts); } //GET ALL REVENUE SCHEDULES RELATED TO OLI for(OpportunityLineItemSchedule s : [SELECT Id, ScheduleDate FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId = :OLIid]){ System.debug('OLI ID =' + OLIid); getSchedules.add(s); System.debug('Schedules =' + getSchedules); } } System.debug('s = ' + getSchedules); for(Opportunity o : trigger.new){ conStartNew = o.Contract_Start_Date__c; conEndNew = o.Contract_End_Date__c; goLiveNew = o.Go_Live_Date__c; } if(Trigger.isUpdate){ if(conStartNew != conStartOld || goLiveNew != goLiveOld || conEndNew != conEndOld){ System.debug('Date changed!'); Delete getSchedules; System.debug('Schedules Removed'); for(OpportunityLineItem x : [SELECT Id FROM OpportunityLineItem WHERE Id=:OLIid]){ update x; } } } }
Please check with below solution which was posted on stack exchange community for similar issue.
After staring at your triggers for a fair amount of time, I think I've come up with a plausible explanation.
Background:
The relationship between OpportunityLineItem (OLI for short) and Opportunity isn't quite a Master-Detail relationship (Salesforce does some funky stuff with standard objects), but it allows you to create roll-up summary fields on Opportunity that summarize a field on OpportunityLineItem.
From the documentation on trigger order of execution (emphasis mine):
If the record contains a roll-up summary field or is part of a cross-object workflow, performs calculations and updates the roll-up summary field in the parent record. Parent record goes through save procedure.
The Problem:
It breaks down to the fact that you have an implicit loop in your two triggers. An update to one updates the other.
So, say we're starting with an update to an OLI. Things run as expected, until we get to step 16 in the order of execution. Now, the parent Opportunity goes through a save, kicking off its trigger.
Where things go wrong is your Opportunity trigger then causes an update on OLIs. Thus, we have a loop, and it continues until you've hit the max trigger depth (16 levels of nested triggers, if memory serves).
The Solution:
The easiest way out of this problem is to remove the DML update of OLIs in your Opportunitytrigger. This would cut the feedback loop, ensuring that your triggers only flow one way (i.e. from OLIto Opportunity). This probably isn't possible in your situation, as it appears that you're using dates on the Opportunity to drive logic on OLI.
The next easiest solution is to track which OLIs have already been updated using a separate apex class with a static Set<Id>.
The extra class only needs to be 3 lines long.
The reason why this will work is that a static variable inside of a class will retain its data throughout the entire transaction (so if we set the data in the OLI trigger, it'll still be available in the Opportunity trigger). We must use a separate class for this, as static variables in triggers behave differently (and are nearly useless, imo).
Once you have that, you'll need to make the following changes to your triggers:
OLI trigger: Opportunity Trigger: Please mark this as solved so that it gets removed from the unanswered queue and others can get benefitted out of that who are looking with similar issue.
Thanks,
Nagendra.