I'm updating OpportunityLineItems when a date changes on the record. Somehow this code works in that I capture when the field is edited, add to a map and then updates the field to the expected value. The problem is it's not committing the change to the database. I can see in the debug log the Start_Date_Renewal__c gets update to the date but the record doesn't show it.

I think I need to put an update at the end but when i try update oli; it says variable does not exist. I know that I don't want the update inside the loop so what do I need to do to update the record?


  private void hasDateRangeChanged(Map<Id, OpportunityLineItem> newMap, Map<Id, OpportunityLineItem> oldMap)
    List<OpportunityLineItem> dateRangeChanged = new List<OpportunityLineItem>();
    List<OpportunityLineItem> renewals = new List<OpportunityLineItem>();
    Set<Id> parentIds = new Set<Id>();
    for (OpportunityLineItem item : newMap.values())
        if ((item.Start_Date__c != oldMap.get(item.id).Start_Date__c) || (item.End_Date__c != oldMap.get(item.id).End_Date__c))
    System.debug('dateRangeChanged is:: ' + dateRangeChanged);

    renewals = [SELECT Id, Start_Date__c, Start_Date_Renewal__c, End_Date__c, End_Date_Renewal__c, Opportunity.ContractTerm__c 
                FROM OpportunityLineItem 
                WHERE Id in:dateRangeChanged];

    System.debug('Renewal list is:: ' + renewals);

    for (OpportunityLineItem item : renewals) 
        Map<Id, Opportunity> parents = new Map<Id, Opportunity>([SELECT Id, ContractTerm__c FROM Opportunity WHERE Id IN :parentIds]);

    for(OpportunityLineItem oli: renewals)
    oli.Start_Date_Renewal__c = oli.Start_Date__c.addMonths(Integer.valueOf(12)); //need to add in ContractTerm__c from parent record map
    oli.End_Date_Renewal__c = oli.End_Date__c.addMonths(Integer.valueOf(12));
  • Is this part of a trigger? Make sure you apply your logic in the before event if so. – Adrian Larson Aug 17 '16 at 20:14
  • it's in a trigger handler on after update. – Dan Wooding Aug 17 '16 at 20:15
  • Just move it to before update. – Adrian Larson Aug 17 '16 at 20:16

Take a look at this section of the Triggers article in the Apex Developer Guide:

There are two types of triggers:

  • Before triggers are used to update or validate record values before they’re saved to the database.
  • After triggers are used to access field values that are set by the system (such as a record's Id or LastModifiedDate field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue. The records that fire the after trigger are read-only.

Make sure you update the values in the before update event.

You also need to update the trigger reference records.

Instead of:

for (OpportunityLineItem oli : renewals)


for (OpportunityLineItem oli : newMap.values())
    Integer term = (Integer)parents.get(oli.OpportunityId).ContractTerm__c;
    // addMonths
  • I can still see in the debug the new value, but the field doesn't show the value. 16:22:16.0 (217386455)|SYSTEM_METHOD_EXIT|[149]|com.salesforce.api.interop.apex.bcl.DateMethods.addMonths(Integer) 16:22:16.0 (217434951)|VARIABLE_ASSIGNMENT|[149]|this.End_Date_Renewal__c|"2018-10-01T00:00:00.000Z"|0x59eeb8c2 In the record the date shows 2018-08-01 which it was at the start of the transaction. – Dan Wooding Aug 17 '16 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.