function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Theodosia TeniaTheodosia Tenia 

trigger that only fires if field condition is met

Hi, I currently have a trigger that sets the revenue schedule for opportunnity products.  Our SFDC is also integrated with an order management system (OMS) that has its own set of installed triggers which pushes back a revenue schedule once the order is sold and the opporutnity syncs with our OMS (note that this is propriatary and the company we use keeps the apex hidden so i have no insight into this code). We need both as our trigger allows us to flight revenue for the open pipeline and the OMS will update it to give us actual run revneue once a campaing is sold.  However, I am running into an issue where our revenue trigger is firing along with the trigger from our OMS whenever the OMS trys to adjust the schedule and it is causing revenue to be double counted. Since opportunites only sync to the OMS if the custom field i cerated is set to yes (it is a formula field that evaluates the sales stage and changes once it reaches 100%) I wuold like to amend our trigger to fire only the OMS_eligible__c field is set to "No".  If OMS_eligible__c is "Yes" then our trigger should just be ignored, allowing the OMS to make the update.

I have tried wrapping what we have in an if statement but when i test this i get the following error: 
'Apex trigger setRevenueSchedule caused an unexpected exception, contact your administrator: setRevenueSchedule: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.setRevenueSchedule: line 3, column 1 '

Here is the trigger:

trigger setRevenueSchedule on OpportunityLineItem (after insert, after update) {
   Opportunity o; { 
   if(o.OMS_Eligible__c=='No') {
    if(RecursionBlocker.flag){
                
        if (trigger.isAfter && trigger.isInsert){
            RevenueController.insertRevenue(trigger.new);
        }   
        
        if (trigger.isAfter && trigger.isUpdate){
            RevenueController.updateRevenue(trigger.newMap, trigger.oldMap);
        }     
    }//end of if recursionblocker is true.
  
} } 
}

Can someone help me understand what is going wrong?  Much appreciated.
 

Thanks!
 

Theo

Paul S.Paul S.
I believe that the issue is that you're trying to reference a field on the opportunity object without indicating which opportunity record the system should be looking at.  So when you say o.OMS_Eligible__c, the system doesn't know what "o" is.  (Sorry for deleting my original reply - it occurred to me that the code was incorrect.)
Theodosia TeniaTheodosia Tenia
Thanks Paul! So my quesiton now is should I be trying to revise the trigger?  Or should I reivse the apex class to indicate the opporutnity record?  Below I have included the apex class that is used for this trigger:

public class RevenueController
{   
    public static void insertRevenue(List<OpportunityLineItem> LI){
        List<OpportunityLineItemSchedule> oppLS = new List<OpportunityLineItemSchedule>();
        
        Date ServiceDate;
        Date EndDate;

        Decimal monthlyRevenue = 0, TotalPrice = 0, UnitPrice = 0;
    
        Integer NumberOfRevenueInstallments, numberOfDays;
        String RevenueInstallmentPeriod = 'Daily';
        String RevenueScheduleType = 'Divide';
               
        List<Id> oliIds = new List<Id>();
        for (OpportunityLineItem olit : LI){
            oliIds.add(olit.Id);
        }
        
        for (OpportunityLineItem item : [SELECT Id, ServiceDate, End_Date__c, UnitPrice, TotalPrice, PricebookEntryId FROM OpportunityLineItem WHERE Id IN :oliIds]) {
            
            ServiceDate = item.ServiceDate;
            EndDate = item.End_Date__c;
            TotalPrice = item.TotalPrice;
            UnitPrice = item.UnitPrice;
                    
            NumberOfRevenueInstallments = (((EndDate.year() * 12) + EndDate.MONTH()) - ((ServiceDate.year() * 12) + ServiceDate.month()));
            numberOfDays = ServiceDate.daysBetween(EndDate) + 1;
            
            monthlyRevenue = (TotalPrice / numberOfDays);
            
            Decimal computedRevenue = 0;
            for(Integer i=0; i<numberOfDays; i++){
                Date newDate = ServiceDate.addDays(i);
                computedRevenue = computedRevenue + monthlyRevenue;
                if(i == numberOfDays && (computedRevenue < TotalPrice || computedRevenue > TotalPrice)){
                    monthlyRevenue = (monthlyRevenue + (TotalPrice - computedRevenue)).abs();
                }
                if(i == numberOfDays && newDate > EndDate){
                    newDate = EndDate;
                }

            OpportunityLineItemSchedule opS = new OpportunityLineItemSchedule(OpportunityLineItemId = item.Id, Type='Revenue', Revenue = monthlyRevenue, ScheduleDate = newDate);
                oppLS.add(opS);
                                
            }
        }
                        
        RecursionBlocker.flag = false;
                                                
        try{
            insert oppLS;
            system.debug('#Success from insert :');
        } catch(system.DmlException e){
            system.debug('##Error OpportunityLineItemSchedule : ' + e.getMessage()); 
        }
    }   
        
    public static void updateRevenue(map<Id, OpportunityLineItem> newOppsMap, map<Id, OpportunityLineItem> oldOppsMap){
        
        List<OpportunityLineItemSchedule> oppLS = new List<OpportunityLineItemSchedule>();
        List<OpportunityLineItemSchedule> oldoppLS = new List<OpportunityLineItemSchedule>();
    
        list<OpportunityLineItem> newOppLiList = new list<OpportunityLineItem>();
        
        Date ServiceDate;
        Date EndDate;
        
        Decimal Revenue = 0, TotalPrice = 0;
    
        Integer NumberOfRevenueInstallments, numberOfDays;
        String RevenueInstallmentPeriod = 'Daily';
        String RevenueScheduleType = 'Divide';
        
        Set<Id> opportunityLineItemIds = new Set<Id>();
        Set<Id> newId = new Set<Id>();
        
        for(Id liId :newOppsMap.keySet()){
            opportunityLineItemIds.add(newOppsMap.get(liId).Id);
            OpportunityLineItem temp = new OpportunityLineItem();
            
            if((newOppsMap.get(liId).ServiceDate != oldOppsMap.get(liId).ServiceDate) || (newOppsMap.get(liId).End_Date__c != oldOppsMap.get(liId).End_Date__c)){
                newId.add(newOppsMap.get(liId).Id);
            }

            temp.OpportunityId = newOppsMap.get(liId).OpportunityId;
            newOppLiList.add(temp);
        }
        
        if(newId.size() > 0){
            for(OpportunityLineItemSchedule ps : [SELECT Id, OpportunityLineItemId From OpportunityLineItemSchedule Where OpportunityLineItemId IN :opportunityLineItemIds]){
                OpportunityLineItemSchedule tempS = new OpportunityLineItemSchedule();
                tempS.Id = ps.Id;
                oldoppLS.add(tempS);
            }
            
            for (OpportunityLineItem item : [SELECT Id, ServiceDate, End_Date__c, UnitPrice, TotalPrice, PricebookEntryId FROM OpportunityLineItem WHERE Id IN :opportunityLineItemIds]) {
                
                ServiceDate = item.ServiceDate;
                EndDate = item.End_Date__c;
                TotalPrice = item.UnitPrice;
                        
                NumberOfRevenueInstallments = (((EndDate.year() * 12) + EndDate.MONTH()) - ((ServiceDate.year() * 12) + ServiceDate.month()));
                numberOfDays = ServiceDate.daysBetween(EndDate) + 1;
                                
                Revenue = (TotalPrice / numberOfDays);
                
                Decimal computedRevenue = 0;
                for(Integer i=0; i<numberOfDays; i++){
                    Date newDate = ServiceDate.addDays(i);
                    computedRevenue = computedRevenue + Revenue;
                    if(i == numberOfDays && (computedRevenue < TotalPrice || computedRevenue > TotalPrice)){
                        Revenue = (Revenue + (TotalPrice - computedRevenue)).abs();
                    }
                    if(i == numberOfDays && newDate > EndDate){
                        newDate = EndDate;
                    }

                OpportunityLineItemSchedule opS = new OpportunityLineItemSchedule(OpportunityLineItemId = item.Id, Type='Revenue', Revenue = Revenue, ScheduleDate = newDate);
                    oppLS.add(opS);
                                    
                }
            }
                            
            RecursionBlocker.flag = false;
                                                            
            try{
                insert oppLS;
                system.debug('#Success insert oppLS : ' + oppLS.size());
            } catch(system.DmlException e){
                system.debug('##Error OpportunityLineItemSchedule : ' + e.getMessage()); 
            }
            
            try{
                delete oldoppLS;
                system.debug('#Success Delete oppLS');
            } catch(system.DmlException e){
                system.debug('##Error OpportunityLineItemSchedule : ' + e.getMessage()); 
            }   
        }
    }
}

Thanks!



Theo
Paul S.Paul S.
Yeah, I think it's the trigger that needs to modified.  Let's try this:
trigger setRevenueSchedule on OpportunityLineItem (after insert, after update) {
    List<Id> oppId = new List<Id>();
    for (OpportunityLineItem oli : trigger.new){
        oppId.add(oli.OpportunityId);
    }
    for(Opportunity opp : [SELECT Id,(SELECT Id FROM OpportunityLineItems WHERE Id IN :trigger.new) FROM Opportunity WHERE Id IN :oppId]){
        if(opp.OMS_Eligible__c == 'No'){
        	for(OpportunityLineItem oli : opp.OpportunityLineItems){
                if(RecursionBlocker.flag){
                    if (trigger.isAfter && trigger.isInsert){
                        RevenueController.insertRevenue(trigger.new);
                    }
                    
                    if (trigger.isAfter && trigger.isUpdate){
                        RevenueController.updateRevenue(trigger.newMap, trigger.oldMap);
                    }
                }
        	}
        }
    }
}