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
Patricia Mozzoni 9Patricia Mozzoni 9 

First trigger & need help correcting error

Thanks for taking the time to read this! This is my first trigger and the purpose is to update the UnitPrice field on Opportunity Line Items with the value of a formula field Net_Amount__c.  I don't even understand the error message I received and will share below.

Greatly appreciate any help!

My Trigger:
 
trigger oliUpdate on OpportunityLineItem (after insert, after update) {

    Set <String> oliID = New Set <String> (); 
    For (OpportunityLineItem oli: Trigger.new) { 
        if (oli.OpportunityId != Null ) { 
        oliID.add (oli.Id); 
        } 
    } 
    If (oliID.size ()> 0) { 
        List <OpportunityLineItem> upOpiList = new List <OpportunityLineItem> (); 
        For (OpportunityLineItem ol: 
[SELECT Id, Net_Amount__c, UnitPrice FROM OpportunityLineItem WHERE id in: oliID AND Net_Amount__c > 0.0]) { 
            ol.UnitPrice = ol.Net_Amount__c; 
            UpOpiList.add (ol); 
        } 
        If (upOpiList.size ()> 0) 
            update upOpiList; 
    } 
}

User-added image
Best Answer chosen by Patricia Mozzoni 9
mukesh guptamukesh gupta
Hi Patricia,

Please use below code:-
trigger oliUpdate on OpportunityLineItem (after insert, after update) {

    Set <String> oliID = New Set <String> (); 
    For (OpportunityLineItem oli: Trigger.new) { 
        if (oli.OpportunityId != Null ) { 
        oliID.add (oli.Id); 
        } 
    } 
    If (oliID.size ()> 0) { 
        List <OpportunityLineItem> upOpiList = new List <OpportunityLineItem> (); 
        For (OpportunityLineItem ol: 
[SELECT Id, Net_Amount__c, UnitPrice FROM OpportunityLineItem WHERE id in: oliID AND Net_Amount__c > 0.0]) { 
			if(ol.UnitPrice != ol.Net_Amount__c){
				ol.UnitPrice = ol.Net_Amount__c; 
				UpOpiList.add (ol); 
			}
           
        } 
        If (upOpiList.size ()> 0) 
            update upOpiList; 
    } 
}


If this solution is usefull for you, Please mark as a Best Answer to help others.



Regards
Mukesh

All Answers

Patricia Mozzoni 9Patricia Mozzoni 9
Looks like that image of the error is impossible to read:

oliUpdate: maximum trigger depth exceeded OpportunityLineItem trigger event AfterInsert OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate OpportunityLineItem trigger event AfterUpdate
 
vishal-negandhivishal-negandhi
Hello Patricia, 


The error you're facing is because of your trigger going into recursion. 
Why is this happening?
Your trigger is updating Opportunity Line Items, which then fires the same trigger again and again, so recursion.

What should you do to fix this?
There are many blogs and articles available on what should you do to fix this, sharing one for example
https://www.sfdcpoint.com/salesforce/maximum-trigger-depth-exceeded-error-salesforce/#:~:text=Maximum%20Trigger%20Depth%20Exceeded%20Error%20Salesforce%20occurs%20mainly%20due%20to,result%20in%20governor%20limit%20sometime.


For your current use case, you don't even need an after insert / update trigger, because you are updating the same record. 
This should be done with an before insert / update trigger. 
Even better if you use Process builder or flow as your use case is straightforward where you're copying value from one field to the other. 

I'm sharing a modified trigger that you can use for your use case. 
trigger oliUpdate on OpportunityLineItem (before insert, before update){

    for (OpportunityLineItem ol: trigger.new]){
			if(ol.Net_Amount__c > 0)
				ol.UnitPrice = ol.Net_Amount__c; 
        } 
    } 
}



Hope this helps.

Best,
Vishal
mukesh guptamukesh gupta
Hi Patricia,

Please use below code:-
trigger oliUpdate on OpportunityLineItem (after insert, after update) {

    Set <String> oliID = New Set <String> (); 
    For (OpportunityLineItem oli: Trigger.new) { 
        if (oli.OpportunityId != Null ) { 
        oliID.add (oli.Id); 
        } 
    } 
    If (oliID.size ()> 0) { 
        List <OpportunityLineItem> upOpiList = new List <OpportunityLineItem> (); 
        For (OpportunityLineItem ol: 
[SELECT Id, Net_Amount__c, UnitPrice FROM OpportunityLineItem WHERE id in: oliID AND Net_Amount__c > 0.0]) { 
			if(ol.UnitPrice != ol.Net_Amount__c){
				ol.UnitPrice = ol.Net_Amount__c; 
				UpOpiList.add (ol); 
			}
           
        } 
        If (upOpiList.size ()> 0) 
            update upOpiList; 
    } 
}


If this solution is usefull for you, Please mark as a Best Answer to help others.



Regards
Mukesh
This was selected as the best answer
Patricia Mozzoni 9Patricia Mozzoni 9
Thank you both for your help!  I was able to get the trigger to work using the code Mukesh provided.  Vishal, I do have to do an after trigger because the UnitPrice field for Opportunity Line Items cannot be updated with a before trigger since Net Amount is a formula field and gets calculated after the record is inserted.  Also, my understanding is that I need to use "recalculate.Formulas" in order for Net Amount formula field to be set before it updates UnitPrice. I am struggling because I don't know how to determine the value of the Net_Amount__c field and check that it has updated the UnitPrice field.

Anyway, the trigger works in the sandbox and now I am attempting test code.  Can either of you review and see what I am doing wrong? It seems to be harder then the trigger itself!  This is what I have so far.  As you can likely tell, I have been looking at many examples to determine how to write the test case, but now have become confused.  Please point in the right direction.
 
@isTest 
public class oliUpdateTest 
{
     static testMethod void TestoliUpdate()
    {
        Test.startTest();
        List<Account> testAccounts = new List<Account>();
        Account testAccount0 = new Account(
            Name = 'Arbor'
        );
        testAccounts.add(testAccount0);
        Account testAccount1 = new Account(
            Name = 'Arbor Villa'
        );
        testAccounts.add(testAccount1);
        insert testAccounts;

   
        Opportunity testOpportunity = new Opportunity(
            Name                 = 'Arbor - Cypress Tree Opportunity',
            StageName            = 'Strategy',
            CloseDate            = Date.today(),
            AccountId            = testAccount0.Id
            
        );
          insert testOpportunity;

        Product2 testProduct2 = new Product2(
            Name                  = 'Cypress Tree',
            IsActive              = true,
            CanUseRevenueSchedule = true
        );
        insert testProduct2;

 

        Pricebook2 testPricebook2 = [SELECT Id, Name, IsStandard FROM Pricebook2 where  isStandard=true LIMIT 1];

        PricebookEntry testPricebookEntry = new PricebookEntry(
            IsActive     = true,
            Pricebook2Id = testPricebook2.Id,
            Product2Id   = testProduct2.Id,
            UnitPrice    = 0
        );
        insert testPricebookEntry;

        OpportunityLineItem testOpportunityLineItem = new OpportunityLineItem(
            OpportunityId          = testOpportunity.Id,
            PricebookEntryId       = testPricebookEntry.Id,
            UnitPrice              = 0,
            Quantity               = 1,
            Revenue_Years__c       = 3,
            Annual_Amount__c       = 5000,
            ServiceDate            = Date.newInstance(2020, 1, 1)
        );
        insert testOpportunityLineItem;
    }    
    System.assertEquals(0,testOpportunityLineItem.Net_Amount__c)
             
        Formula.recalculateFormulas(List<OpportunityLineItem> OpportunityLineItem);
      
       
       System.assertEquals(testOpportunityLineItem.UnitPrice)
 

}

These are the errors I am getting:

User-added image