[SalesForce] Help! After Trigger Not Updating a field

I have this after trigger and I can't figure out why it isn't updating the field. I have the field write to a list then once done with the Trigger.New I then update the list. But when I test I can't get the field to populate with anything.

More detail on the problem I am trying to create a lookup to an Object that I will let a department own. The object has the fields they use to split and define regions. They can enter this information into the record in this custom object and then this trigger will take in this case a lead, and look to find the region that it matches to. This way for small changes to the region it can all be managed by the end user with no need to update any Apex.

The reason I thought it needed to be an After trigger is it relies on a different Before trigger to populate one of the fields that is used to select the region. After getting enough written to test a single region I created a region record then updated a Lead record to match. No error pops up, and no update is made.

Looking for some help on what might be wrong and where I should make my next stab. Trying to learn to fish.

trigger SDRRegionLead on Lead(after insert, after update) {

// Has to be an After trigger as it relys on LookupRegionsLead trigger to fire first
// Build a map of the SDR Region Object

//after trigger means I need to update via a List as the record is already locked
List<Lead> leadUpdate = new List<Lead>();

Map < Id, SDR_Region__c > regionmap =  new Map < Id, SDR_Region__c > ();

for (Lead newLead : Trigger.New){
    If(Trigger.isUpdate) {
        Lead oldLead = Trigger.oldmap.get(NewLead.id);

        // Do new vs old check so it doesnt always fire
        //Broken into each category so it will only run based on set rules of what MIGHT change for each lookup
        //Geography__c = Field Sales Region

        If(oldLead.NumberOfEmployees !=  newLead.NumberOfEmployees || oldLead.Geography__c !=  newLead.Geography__c) {
            for (ID idKey : regionmap.keyset()) {
                SDR_Region__c SDRR = regionmap.get(idKey);
                if (newLead.Geography__c != NULL) {
                    if (newLead.Geography__c == SDRR.Field_Sales_Region__c && (newLead.NumberOfEmployees >= SDRR.Number_of_Employees_Lower_Fence__c ||  newLead.NumberOfEmployees == SDRR.Number_of_Employees_Lower_Fence__c) &&  newLead.NumberOfEmployees <= SDRR.Number_of_Employees_Upper_Fence__c) {
                        newLead.SDR_Region__c = SDRR.SDR_Region_Name__c;
                        leadUpdate.add(newLead);
                    }
                }
            }
        }
        Else If(oldLead.NumberOfEmployees !=  newLead.NumberOfEmployees || oldLead.Corporate_Sales_Region__c !=  newLead.Corporate_Sales_Region__c) {
            for(ID idKey : regionmap.keyset()){
                SDR_Region__c SDRR = regionmap.get(idKey);
                if (newLead.Corporate_Sales_Region__c != NULL){
                    if (newLead.Corporate_Sales_Region__c == SDRR.Corporate_Sales_Region__c && (newLead.NumberOfEmployees >= SDRR.Number_of_Employees_Lower_Fence__c ||  newLead.NumberOfEmployees == SDRR.Number_of_Employees_Lower_Fence__c) &&  newLead.NumberOfEmployees <= SDRR.Number_of_Employees_Upper_Fence__c) {
                        newLead.SDR_Region__c  = SDRR.SDR_Region_Name__c;
                        leadUpdate.add(newLead);
                    }
                }
            }
        }
        Else If(oldLead.NumberOfEmployees != newLead.NumberOfEmployees || oldLead.Corporate_HQ_State__c != newLead.Corporate_HQ_State__c || (newLead.Corporate_HQ_State__c == NULL && oldLead.State != newLead.State)) {
            for(ID idKey : regionmap.keyset()){
                SDR_Region__c SDRR = regionmap.get(idKey);
                if (newLead.Corporate_HQ_State__c != NULL){
                    if(SDRR.States__c.containsIgnoreCase(newLead.Corporate_HQ_State__c) && (newLead.NumberOfEmployees >= SDRR.Number_of_Employees_Lower_Fence__c ||  newLead.NumberOfEmployees == SDRR.Number_of_Employees_Lower_Fence__c) &&  newLead.NumberOfEmployees <= SDRR.Number_of_Employees_Upper_Fence__c){
                        newLead.SDR_Region__c  = SDRR.SDR_Region_Name__c;
                        leadUpdate.add(newLead);
                    }
                }
            }
        }

    }
 }

update leadUpdate;
}

Best Answer

@Dan, here is a very comprehensive answer as well, including functional code for your consideration. Yes, there are several things wrong with your initial code...

Issue 1) You cannot modify Trigger.new in after trigger: you are attempting to do that several different places. Here is one example where you are attempting to modify Trigger.new:

newLead.SDR_Region__c = SDRR.SDR_Region_Name__c;

If you had properly wrapped your DML in try/catch (you didn't), and cleared up the other issues (I'll point them out later) you would have seen an error like this if you made a "triggering" Lead update via the GUI:

Error:Apex trigger SDRRegionLead caused an unexpected exception, contact your administrator: SDRRegionLead: execution of AfterUpdate caused by: System.FinalException: Record is read-only: Trigger.SDRRegionLead: line 34, column 1

Pro tip: always try/catch your DML!!!

Issue 2) You are trying to set an Id field (Lead.SDR_Region__c) with a Name field: line 33 or thereabouts is one example. Ignoring the fact that you are trying to set Trigger.new, consider your code:

newLead.SDR_Region__c = SDRR.SDR_Region_Name__c;

... I believe this should be:

newLead.SDR_Region__c = SDRR.Id

Pro tip: compartmentalize your logic. Don't boil the ocean all at once. Slow down. Focus on small piece of functionality, test your code, make sure it does exactly what you think it does (liberally apply "System.debug" statements throughout your code) before you move on to the next logic block.

Issue 3) Your initial map is always null, this map will always be empty on line 9:

Map < Id, SDR_Region__c > regionmap =  new Map < Id, SDR_Region__c > ();

I believe what you meant to do is:

Map < Id, SDR_Region__c > regionmap =  new Map < Id, SDR_Region__c > ([SELECT Id, Corporate_Sales_Region__c, Field_Sales_Region__c, Number_of_Employees_Lower_Fence__c, Number_of_Employees_Upper_Fence__c, SDR_Region_Name__c, States__c FROM SDR_Region__c ]);

Issue 4: understand the trigger context variables! Trigger.new is a list AND a map. That is a powerful concept. Using this knowledge, you can rewrite your entry loop. This code on line 11:

for (Lead newLead : Trigger.New){

should be re-written like so:

for(Lead newLead : [SELECT Id, NumberOfEmployees, Geography__c, SDR_Region__c FROM Lead WHERE Id IN: trigger.newMap.keySet()]) {

THIS. IS. HUGE. This changes "newLead" from being a direct reference to Trigger.new context variable (bad news bears... no updates allowed to that special variable) into a simple reference to a bunch of Lead records. But not just any Lead records... specifically, the records that were just DML'd and hence available to you in your Trigger context variables.

So, all that being said I'll give you back some functional, reworked code. I reworked your first IF. I have left debug statements throughout to make a point: you need to start doing this, debugging your code isn't so bad. Your IF/ELSE blocks are on you :) happy coding.

trigger SDRRegionLead on Lead(after insert, after update) {
List<Lead> leadUpdate = new List<Lead>();

Map < Id, SDR_Region__c > regionmap =  new Map < Id, SDR_Region__c > ([SELECT Id, Corporate_Sales_Region__c, Field_Sales_Region__c, Number_of_Employees_Lower_Fence__c, Number_of_Employees_Upper_Fence__c, SDR_Region_Name__c, States__c FROM SDR_Region__c ]);

for(Lead newLead : [SELECT Id, NumberOfEmployees, Geography__c, SDR_Region__c FROM Lead WHERE Id IN: trigger.newMap.keySet()]) {

If(Trigger.isUpdate) {
    Lead oldLead = Trigger.oldmap.get(NewLead.id);
    If(oldLead.NumberOfEmployees !=  newLead.NumberOfEmployees || oldLead.Geography__c !=  newLead.Geography__c) {
        System.debug('Hit 1! ' + regionmap);
        for (ID idKey : regionmap.keyset()) {
            System.debug('Hit 2! ' + idKey);

            SDR_Region__c SDRR = regionmap.get(idKey);
            System.debug('SDRR: ' + SDRR);

            if (newLead.Geography__c != NULL) {
                System.debug('in your BASE!');

                if (newLead.Geography__c == SDRR.Field_Sales_Region__c && (newLead.NumberOfEmployees >= SDRR.Number_of_Employees_Lower_Fence__c ||  newLead.NumberOfEmployees == SDRR.Number_of_Employees_Lower_Fence__c) &&  newLead.NumberOfEmployees <= SDRR.Number_of_Employees_Upper_Fence__c) {
                    System.debug('omg WAY in your BASE!!');
                    newLead.SDR_Region__c = SDRR.Id;
                    leadUpdate.add(newLead);
                }
            }
        }
      }
    }
 }

try {
    update leadUpdate;
} catch (Exception e) {
    System.debug('OOPS its on FIRE: ' + e);
}
}
Related Topic