Friday, January 29, 2016

Working day calculation-Apex


When calculating working days in salesforce between two dates, we need to consider weekoff and company holidays to exclude between days.

Note: To setup organization holiday in salesforce, go to setup-->Company profile-->Holidays. view the holiday list which are already defined or click on new and enter the value for the  Holiday name,Date and select if this holiday is recuring holidday and enter appropriate value for it to create a new holiday in salesforce.

There Is a straight forward formula, which will give working days with excluding week off between two dates in below link here.
But we cannot access Holidays list of the organization using formula fiels, So we can use below apex logic  to calculate working days with excluding weekend and holidays.

public class CalculateDaysDiffExcludingHoliday {
    List<Holiday> holidayList = new List<Holiday>();
    public CalculateDaysDiffExcludingHoliday(){
        //Fetch all holiday list from the organization- you can check this from             //setup-->Company Profile-->Holidays
         holidayList=[Select StartTimeInMinutes, Name, ActivityDate From Holiday];
    }
    public integer CalculateWorkingDays(date startdt, Date enddt){
// to include both start and end date in calculation, add 1 with days //difference.
        Integer allDaysBetween = startdt.daysBetween(enddt)+1;
        system.debug('**allDaysBetween'+allDaysBetween);
        Integer allWorkingDays=0;
        //If start date and end date are same, then check is this date not fall in //holiday or weekoff
        if(startdt == enddt){
            system.debug('**startdt'+startdt+'enddt'+enddt);
            boolean isHoliday= false;
            //For excluding weekoff- week starts with Monday,As my week starts               //with sunday subtract 1 from weekstart. 
            Date weekStart = startdt.toStartofWeek().addDays(-1);
            system.debug('**weekStart'+weekStart);
           for(Holiday hDay:holidayList){
                if(startdt.daysBetween(hDay.ActivityDate) == 0){
                    isHoliday= true;
                }
            }
            if(weekStart.daysBetween(startdt) ==7 || weekStart.daysBetween(startdt) == 6){
               isHoliday= true;
            }
            system.debug('**isHoliday'+isHoliday);
            if(isHoliday == false){
                allWorkingDays = 1;
            }
        }
        else{//start date and end date are not same, so need to loop with all //dates to exclude weekoff and holiday list
            for(Integer k=0;k<allDaysBetween ;k++ ){
                if(checkifItisWorkingDay(startdt.addDays(k),holidayList)){
                    system.debug('**working day:'+startdt.addDays(k));
                    allWorkingDays++;//increment working date for each working //date.
                } 
            }
        }
        return allWorkingDays;
    }
    public boolean checkifItisWorkingDay(Date currentDate,List<Holiday> holidays){
        system.debug('**currentDate'+currentDate);
        Date weekStart = currentDate.toStartofWeek().addDays(-1);

        system.debug('**weekStart'+weekStart);
        for(Holiday hDay:holidays){
            //if date fall inholiday then return false.
            if(currentDate.daysBetween(hDay.ActivityDate) == 0){
                return false;
            }
        }
        //if date fall in weeknd return false
        if(weekStart.daysBetween(currentDate) ==7 || weekStart.daysBetween(currentDate) == 6){
            return false;
        } 
        else{//if date is not in holiday list and not in weekoff, return true to //indicate as working date.
            return true;
        }
      }
}

5 comments:

  1. @Debasis Sorry I am a naive person - How do I incorporate the above code to a custom object
    Ex: I have a communication object - which has 2 custom fields "Notification Period" and "Installation Period" which needs to be calculated between 2 dates considering holidays.
    I lost track as to how startdt & enddt are picked up in the above code. Will I be able to assign the calculated value to the fields? Please help.

    ReplyDelete
    Replies
    1. Yes you can assign the calculated value to the fields using the Apex trigger..

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. This concept is a good way to enhance the knowledge.thanks for sharing. please keep it up salesforce online training

    ReplyDelete