You need to sign in to do that
Don't have an account?
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.
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.