0

I am trying to change the Opportunity Line Item schedule when a custom field is changed. The schedule works fine when the field is enterd, but when I edit the custom field it throws the exception. I did try null check for the list but that is messing up the schedule. Greatly appreciate any help on this

Here is the trigger and the class

Trigger

trigger OpportunityReScheduling on Opportunity (after update, before update, after insert) 
    {
        for (Opportunity o: Trigger.new)
        {
            if (Trigger.isBefore)
            {
                if(o.Category__c == 'Solutions'){
                Opportunity prevOpportunity = Trigger.oldMap.get(o.ID);
                    if(o.Effective_Date__c <> null){
                if (o.Effective_Date__c != prevOpportunity.Effective_Date__c) 
                {
                    Integer DayDiff = prevOpportunity.Effective_Date__c.daysBetween(o.Effective_Date__c);

                    OpportunitySchedulingHandler.ScheduleDateUpdate(o.id, DayDiff);
                }
            }
            }
            }
        }
    }

CLass

public with sharing class OpportunitySchedulingHandler {

     //Update LineItemSchedule dates for all scheduling dates

    public static void ScheduleDateUpdate(String oppid, Integer DayDiff)

    {

       List<OpportunityLineItem> idval = [SELECT id FROM OpportunityLineItem WHERE OpportunityId=:oppid];

       List<OpportunityLineItemSchedule> datelist = new List<OpportunityLineItemSchedule>();

       for (Integer i = 0; i < idval.size(); i++)

       {

           datelist = [SELECT ScheduleDate FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId =:idval[i].id];

           Date firstDate = datelist[0].ScheduleDate.addDays(DayDiff);

           datelist[0].ScheduleDate = firstDate;

           Integer day = firstDate.day();

           Integer month = firstDate.month();

           Integer year = firstDate.year();

           for (Integer k = 1; k < datelist.size(); k++)

           {

               Integer nYear = year;

               Integer nMonth = month + k;

               Integer nDay = day;

               if (nMonth > 12) {
                nMonth = nMonth - 12;

                   nYear = nYear + 1;

               }

               Set<Integer> longMonths = new Set<Integer> {1,3,5,7,8,10,12};


               if (nDay == 31 && ! longMonths.contains(nMonth)) {

                   nDay = 30;

               }

               if (nDay > 28 && nMonth == 2) {

                   nDay = 28;

               }

               Date mydate = date.newInstance(nYear,nMonth,nDay);

               datelist[k].ScheduleDate = mydate;

           }

           if(!datelist.isEmpty())

           {

                update datelist;

           }

        }
    }   

}
1
  • 3
    Please dont write "soql"query inside for loop!!!!... – SFDC Learner Mar 27 '18 at 17:06
3

When you perform a query like this one:

       datelist = [SELECT ScheduleDate FROM OpportunityLineItemSchedule WHERE OpportunityLineItemId =:idval[i].id];

You don't need to be checking for datelist to be null. It won't be. If something goes wrong with the query, you'll simply get an exception.

Instead, you need to check for datelist.size() > 0 prior to referencing datelist[0]. You are attempting to access an element that is beyond the bounds of the list, the bounds being empty (no items at all).

Your code has a much deeper issue, however. You are performing a SOQL query inside not one but two for loops. You call OpportunitySchedulingHandler.ScheduleDateUpdate once per Opportunity, and then within that method you perform SOQL once for the OpportunityLineItem list and then once per OpportunityLineItem to obtain OpportunityLineItemSchedule. You're going to need to put some work into bulkifying this trigger before you take it to production.

3
  • I did try that initially , but I think I had two conditions where I was looking if the list is null and the size, and that messed up. Now I am able to fix the issue. Somehow I am still unable to create the schedule directly off the custom field instead of Opportunity Close Date. Is that the standard way? – user43146 Mar 27 '18 at 17:12
  • I'm afraid I don't know what that means - I don't really work with line item schedules. If this issue is solved, please consider accepting an answer and opening a new question for any separate issues. – David Reed Mar 27 '18 at 17:15
  • That said, I'd really recommend refactoring and bulkifying the code before trying to debug, as you have some radical changes to make. – David Reed Mar 27 '18 at 17:17

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.