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
jadenjaden 

Opportunity DML issue

Hi,

I have a trigger against Opp products and when a checkbox I want to copy a field on opportunity to another field on opportunity. 

 

Here is the trigger:

trigger onOppProdUpdateOpp on OpportunityLineItem (after update) {
        
	//Set of ids of opps to use 
	set<Id> opid = new set<Id>(); 
	
	//identify opps needed because winner flag set
    for(OpportunityLineItem op : Trigger.new) 
    {
    	if(op.winner__c = true && op.Winner__c  != trigger.oldMap.get(op.Id).Winner__c)
    		opid.add(op.opportunityid);
    }
    
    if(opid.size() > 0 )
    {
    	//List to hold opps needed and another for those updated 
		list<Opportunity> opplistupd = new list<Opportunity>();
		list<Opportunity> opplistneeded = [select id, Winner_Total__c, amount from Opportunity where id in :opid ];
		 
	  	for(Opportunity opp: opplistneeded)
	  	{
	  		if(opp.Amount != opp.Winner_Total__c)
	  		{
	  			opp.Amount = opp.Winner_Total__c;
				opplistupd.add(opp);
	  		}	
	    } 
	      
	    if(opplistupd.size() > 0 )
	    	update opplistupd;
    } 
}

 

Here is the test class I am doing; which is where the error is coming from:

@isTest (seealldata=true)  
class onOpportunityTest {

	public static testMethod void test_onOpportunityTest () 
	{
        RecordType hnrectypeid = [Select id from RecordType where name = 'XXX Corp'];
				
        Account acct = new Account(name='XXXAcct1');
        insert acct;
        Contact con = new Contact(Firstname='XXXContact1', Lastname='BigLast',AccountID = acct.id, MailingCountry = 'United Kingdom');
        insert con;
          
    	Pricebook2 standardPB = [select id from Pricebook2 where isStandard=true limit 1 ];
    	
		Product2 prod = new Product2(name='prod1', ProductCode = 'PC1');
		insert prod;
		
  		PricebookEntry standardPrice = new PricebookEntry(Pricebook2Id = standardPB.Id, Product2Id = prod.Id, UnitPrice = 10000, UsestandardPrice = false, IsActive = true);
        insert standardPrice;
	 	
		Pricebook2 pb = new Pricebook2(name = 'PB1');
		insert pb;
  
		PricebookEntry pe = new PricebookEntry(PriceBook2id = pb.id, Product2Id = prod.id, unitprice = 10000, UsestandardPrice = true, IsActive = true);
		insert pe;
 	 	 
		Opportunity newOP = new Opportunity(Name = 'Opp', stagename = 'New', AccountId = acct.Id, CloseDate = date.today());
		insert newOp;
		 
		OpportunityLineItem newOL= new OpportunityLineItem(Opportunityid = newOP.Id, Description = 'Oppline Desc', Quantity = 1,
		   	 	ServiceDate = date.today(), UnitPrice = 2.20, PricebookEntryId = pe.Id, Program_Platform__c = 'JBplat', Customer_P_N__c='1234', Tooling_Value__c=10000, Production_Type__c = 'Production');
		insert newOl;
 	  	 
		OpportunityLineItem newOL2 = new OpportunityLineItem(Opportunityid = newOP.Id, Description = 'Oppline Desc', Quantity = 1,
		   	 	ServiceDate = date.today(), UnitPrice = 3.00, PricebookEntryId = pe.Id, Program_Platform__c = 'JBplat', Customer_P_N__c='1234', Tooling_Value__c=10000, Production_Type__c = 'Production');
		insert newOl2;
  
		Quote qte = new Quote(OpportunityId = newOp.id, ContactId=con.id, Name='Quote1', Pricebook2Id=pb.id, SubTotal__c=1.00, RecordTypeId = hnrectypeid.id );
		Insert qte;
		QuoteLineItem qli1 = new QuoteLineItem(QuoteId=qte.id, PricebookEntryId=pe.id, Quantity=2, UnitPrice= 10000);
		Insert qli1;
		
		QuoteLineItem qli2 = new QuoteLineItem(QuoteId=qte.id, PricebookEntryId=pe.id, Quantity=4, UnitPrice= 10000);
      	insert qli2;

		Test.startTest();
 		
	   //must re-query to get updated value        
        newOP = [Select  id, Winner_Total__c, Amount from Opportunity where id = :newOP.id];

        //make sure value us what is expected 
		system.assertEquals(newOP.Amount, 5.20);
 		
		//Update quote  
		qte.SubTotal__c= 2.00;
		update qte;
	 	
		//Update qteline
		qli2.winner__c = true;
		update qli2;
 		
		newOl2.winner__c = true;
		update newol2; 
		   
	   //must re-query to get updated value        
        newOP = [Select  id, Winner_Total__c, Amount from Opportunity where id = :newOP.id];

        //make sure value us what is expected 
        system.debug('** the amount is ' + newop.Amount + ' and the total is ' + newop.Winner_Total__c);
		//system.assertEquals(newOP.Winner_Total__c, newOP.Amount);
	}
}

 The error is happening on the update below and it does not matter which field on the Opp Prod I try to change.

newOl2.winner__c =

true;

 

updatenewol2;   

 

The error is:

Description Resource Path Location Type
System.DmlException: Update failed. First exception on row 0 with id 00ka000000WNGZNAA5; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, onOppProdUpdateOpp: execution of AfterUpdate

caused by: System.FinalException: Record is read-only

Trigger.onOppProdUpdateOpp: line 9, column 1: [] onOpportunityTest.cls /HN Precision/src/classes line 63 Force.com run test failure

 

any help appreciated.

 

 

colemabcolemab

Per this documentation, I don't think you can use trigger.new to update fields in an after update trigger.

 

If you’re updating an object from an ‘after update’, you have to explicitly create a new instance of that object and run an explicit update call.

 

More info here.