[SalesForce] after update trigger creates duplicate value to related list if related list is empty

I am trying to create a trigger that would add a new value to a related list if a value is adeded to a field.

The field is called Reason of Contact (ROC) and when ever a new reason of contact is added or the field is populated it brings the new value to the related list in the Case. This is working correctly but when ever the first reason of contact is added to the case this value is entered twice. But after that everything works fine. So can someone see what is wrong with the code so that it would not create a duplicate value if the list for Reason Of Contacts (ROCs) is empty.

//


trigger createROCchildonCaseUpdate on Case (after update) {

// Create an empty list of String
List<Reasons_of_Contact__c> ROCs = new List<Reasons_of_Contact__c>();

    //For each case processed by the trigger, add a new  

    //ROC record for the specified case.  

    //Note that Trigger.New is a list of all the new positions  

    //that are being created.  

    for (Case newCase : Trigger.new) {
    Case oldCase = Trigger.oldMap.get(newCase.Id);
    if (oldCase.Request_3__c != newCase.Request_3__c | oldCase.Request_3__c != NULL) {

         //Create the new ROC in the related list with the following values
               ROCs.add(new Reasons_of_Contact__c(
                        ProgramCaseLink__c = newCase.Id,
                        Type__c = newCase.Request_3__c,
                        ProgramCommentLookup__c = newCase.Program__c));
        }
    }
    insert ROCs;
}

Best Answer

While it's not immediately obvious, it's important to know that you're trigger can run multiple times. The primary cause is a workflow field update which causes all triggers for an object to get re-evaluated a second time Based on your description it sounds like the field update is only set to fire when a record is created.

Even less obvious is that after the field update trigger.old contains the same values from the start of the transaction. So if you start with "Foo", change it to "Bar", then a field update causes a second trigger execution, trigger.old still contains "Foo".

To get things to work the way you want, move you're logic into an external class and use a static map to record the last value you saw for the field. That way the second trigger execution won't generate a duplicate record unless the field truly changed.

public class MyProcessor {

  private static Map<Id, Case> oldMapOverride = new Map<Id, Case>();

  public static void execute() {
    List<Reason_of_Contact__c> ROCs = new List<Reason_of_Contact__c>();

    for(Case newCase : trigger.new) {

      // if we've seen this case before, get it from the override map
      Case oldCase = (oldMapOverride.containsKey(newCase.id)) 
        ? oldMapOverride.get(newCase.id) : trigger.oldMap.get(newCase.id);

      // has something changed?
      if (
        oldCase == null ||
        oldCase.Request_3__c != newCase.Request_3__c || 
        oldCase.Request_3__c != NULL
      ) {

        //Create the new ROC in the related list with the following values
        ROCs.add(new Reasons_of_Contact__c(
          ProgramCaseLink__c = newCase.Id,
          Type__c = newCase.Request_3__c,
          ProgramCommentLookup__c = newCase.Program__c));

        // Store this record in case we see it again
        oldMapOverride.put(newCase.id, newCase);
      }
    }

    inserts ROCs;
  }
}
Related Topic