0

In the below, I populate field Implementation_Revenue_as_a_of_FSR__c in my WE_OppUpdates Class but when I try to reference that field in WE_MRFv3 Class it causes an error, while inserting a batch of Opportunities in a Unit Test (without setting a value for Implementation_Revenue_as_a_of_FSR__c).

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, WE_MasterOpportunityTrigger: execution of AfterInsert

caused by: System.DmlException: Update failed. First exception on row 0 with id 00656000002BhP2AAK; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, WE_MasterOpportunityTrigger: execution of BeforeUpdate

caused by: System.NullPointerException: Attempt to de-reference a null object

Class.WE_MRFv3.generateMRF: line 157, column 1 Trigger.WE_MasterOpportunityTrigger: line 12, column 1: []

Line 157 is increment = o.Implementation_Revenue_as_a_of_FSR__c/100;

Class.WE_OppUpdates.updateOpportunities: line 71, column 1 Trigger.WE_MasterOpportunityTrigger: line 20, column 1: []

Note - WE_ApexUtility just retrieves values from a Custom Setting

trigger WE_MasterOpportunityTrigger on Opportunity (
    before insert, after insert, 
    before update, after update, 
    before delete, after delete)
{

    if (Trigger.isBefore) {
        if (Trigger.isUpdate) {
            WE_MRFv3 forecast = new WE_MRFv3(Trigger.oldMap, Trigger.newMap);
            forecast.generateMRF();
        }
    }

    if (Trigger.IsAfter) {
        if (Trigger.isInsert) {
            system.debug('after Insert triggered');
            WE_OppUpdates oppPreparation = new WE_OppUpdates(Trigger.oldMap, Trigger.newMap);
            oppPreparation.updateOpportunities();

            WE_MRFv3 forecast = new WE_MRFv3(Trigger.oldMap, Trigger.newMap);
            forecast.generateMRF();
        }
        if(Trigger.isUpdate) {
           system.debug('isUpdate loop entered'); 
        }
    }
}

public class WE_OppUpdates {

        Map<Id, Opportunity> oldOpps;
        Map<Id, Opportunity> newOpps;
        Date cd;
        Opportunity oldOpp;
        List<Opportunity> oppsToUpdate = new List<Opportunity>();

        public WE_OppUpdates(
        Map<Id, Opportunity> oldTriggerOpps, 
        Map<Id, Opportunity> newTriggerOpps) {
          oldOpps = oldTriggerOpps;
          newOpps = newTriggerOpps;
        }

        public void updateOpportunities() {

            WE_ApexUtility apxUtil = new WE_ApexUtility(
                'EU Opps');

            apxUtil.checkApexControllerStatus();
            if (!WE_ApexUtility.setting.contains(true)){

                apxUtil.retrieveValidRecordTypes();

                if (Trigger.isInsert){

                    system.debug('isInsert loop entered');

                    List<Opportunity> insertedOpps = [SELECT Id, RecordTypeId, Implementation_Revenue_as_a_of_FSR__c FROM Opportunity
                                                       WHERE Id IN :newOpps.keySet()];

                    for(Opportunity o : insertedOpps){
                        if (WE_ApexUtility.validRecordTypeIds.contains(o.RecordTypeId) ){

                            if (o.Ramp_Profile__c == 'Standard'){
                                o.Implementation_Revenue_as_a_of_FSR__c = 5/2; // made up value
                                oppsToUpdate.add(o);

                            }else if (o.Ramp_Profile__c == 'Medium'){
                            // set different values - Implementation_Revenue_as_a_of_FSR__c is never set to null
                            }
                        }
                    }
                }
                update oppsToUpdate;
            }
                if (Trigger.isUpdate){
                    system.debug('isUpdate loop entered');
                }
        }
    }

public class WE_MRFv3 {

        Map<Id, Opportunity> oldOpps;
        Map<Id, Opportunity> newOpps;
        Set<Id> oppIds = new Set<Id>();

        Decimal increment;

        public WE_MRFv3(
        Map<Id, Opportunity> oldTriggerOpps, 
        Map<Id, Opportunity> newTriggerOpps) {
          oldOpps = oldTriggerOpps;
          newOpps = newTriggerOpps;
        }

        public void generateMRF(){

            WE_ApexUtility apxUtil = new WE_ApexUtility(
                'EU Opps');

            apxUtil.checkApexControllerStatus();
            if (!WE_ApexUtility.setting.contains(true)){

                apxUtil.retrieveValidRecordTypes();

                if (Trigger.isInsert){
                    for(Opportunity o : newOpps.values()){
                        if (WE_ApexUtility.validRecordTypeIds.contains(o.RecordTypeId) && o.Type != 'Existing Customer - Administration')
                        {
                            oppIds.add(o);
                        }
                    }
                }
                if (Trigger.isUpdate){
                    for(Opportunity o : newOpps.values()){

                        if (WE_ApexUtility.validRecordTypeIds.contains(o.RecordTypeId) && o.Type != 'Existing Customer - Administration' &&
                            o.Annual_Settlement_Value__c != null && o.Annual_transaction_volume__c != null && o.Monthly_Txn_Revenue_POS__c != null)
                        {
                            Opportunity oldO = oldOpps.get(o.Id);

                            if(oldO.Implementation_Revenue_as_a_of_FSR__c != oldO.Implementation_Revenue_as_a_of_FSR__c)
                            {
                                oppIds.add(o);
                            }
                        }
                    }
                }

                if (oppIds.size() > 0){

                    for(Opportunity o : [SELECT Id, Implementation_Revenue_as_a_of_FSR__c FROM Opportunity
                                          WHERE Id IN :oppIds]){

                            increment = o.Implementation_Revenue_as_a_of_FSR__c/100;

                            // remaining code removed, error on line above
                    }
                }
            }
        }
    }

I can't work out what I need to change in order to retrieve the values for Implementation_Revenue_as_a_of_FSR__c that I've populated in WE_OppUpdates, for use in WE_MRFv3?

Background

I'm trying to update my Opportunities and then use the values from the updated Opportunities to do some calculations, whose results I will use to populate fields on a related object Monthly_Revenue_Forecasts__c.

I need to make the changes to my Opportunities in the After Insert context, since the code needs to execute for Opportunities created during Lead conversion, which skips the Before context in my org.

Update

Having looked into this further, the sections of code within the if(isInsert line in my Trigger and if(isInsert line in my WE_OppUpdates Class, are not being executed.
The isInsert debug lines are not being posted in my log, while the isUpdate lines are.

2
  • 1
    Hey Alex, your questions will be much more accessible if you only include relevant code and don't just blindly dump dozens/hundreds of lines. Imagine (or try) viewing this post on mobile. It sucks. Most of this code looks completely irrelevant.
    – Adrian Larson
    Dec 5, 2015 at 17:24
  • @AdrianLarson having taken a second look at the code, you have a point. I was short of time when I posted my question so I didn't remove as many lines as I could have. I have now, thanks for the feedback.
    – Alex S
    Dec 5, 2015 at 20:24

1 Answer 1

0

The Opps are being updated in the database by WE_Updates but their field values in the trigger maps are still the same. You need to re-query them in the second class to get the non-null value that you set in WE_Updates.

1
  • 1
    Thanks for this, I've got the solution now. This was my first time working in the After context so it took me a while to understand the order of execution, when updating records in After Insert and to work out when oldMap would contain values but I got there in the end!
    – Alex S
    Dec 6, 2015 at 19:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .