Monday 28 September 2015

Business Day Calculation in Apex Salesforce

        Here is the utility method to calculate various business day calculation such as getting next business days, business hours, validating date is business day or not, total business days between two dates, etc.


  1. public class BusinessDays {
  2. private List<Boolean> businessDay = new Boolean[7];
  3. private List<Time> startHours = new Time [7];
  4. private List<Time> endHours = new Time [7];
  5. private Date knownSunday = date.newInstance(201316);
  6. private String businessHourId;
  7. private Boolean considerHolidays = false;
  8.    
  9.   // Constructor creates businessDay array
  10.    public BusinessDays(String businessHourName, Boolean considerHolidays) {
  11.      
  12.      BusinessHours bh;
  13.      
  14.      this.considerHolidays = considerHolidays;
  15.      
  16.      if(businessHourName == null) {
  17.          bh = [SELECT SundayStartTime, MondayStartTime, TuesdayStartTime,WednesdayStartTime, ThursdayStartTime, FridayStartTime,SaturdayStartTime, SundayEndTime, MondayEndTime,TuesdayEndTime,WednesdayEndTime, ThursdayEndTime, FridayEndTime,SaturdayEndTime
  18.                             FROM BusinessHours
  19.                                 WHERE IsDefault = true ];
  20.      }else {
  21.          bh = [SELECT SundayStartTime, MondayStartTime, TuesdayStartTime,WednesdayStartTime, ThursdayStartTime, FridayStartTime,SaturdayStartTime, SundayEndTime, MondayEndTime,TuesdayEndTime,WednesdayEndTime, ThursdayEndTime, FridayEndTime,SaturdayEndTime
  22.                             FROM BusinessHours
  23.                                 WHERE Name =: businessHourName ];
  24.      }
  25.      
  26.      businessHourId = bh.Id;
  27.      
  28.      businessDay[0] = (bh.SundayStartTime != null);
  29.      businessDay[1] = (bh.MondayStartTime != null);
  30.      businessDay[2] = (bh.TuesdayStartTime != null);
  31.      businessDay[3] = (bh.WednesdayStartTime != null);
  32.      businessDay[4] = (bh.ThursdayStartTime != null);
  33.      businessDay[5] = (bh.FridayStartTime != null);
  34.      businessDay[6] = (bh.SaturdayStartTime != null);
  35.      startHours[0] = bh.SundayStartTime;
  36.      startHours[1] = bh.MondayStartTime;
  37.      startHours[2] = bh.TuesdayStartTime;
  38.      startHours[3] = bh.WednesdayStartTime;
  39.      startHours[4] = bh.ThursdayStartTime;
  40.      startHours[5] = bh.FridayStartTime;
  41.      startHours[6] = bh.SaturdayStartTime;
  42.      endHours[0] = bh.SundayEndTime;
  43.      endHours[1] = bh.MondayEndTime;
  44.      endHours[2] = bh.TuesdayEndTime;
  45.      endHours[3] = bh.WednesdayEndTime;
  46.      endHours[4] = bh.ThursdayEndTime;
  47.      endHours[5] = bh.FridayEndTime;
  48.      endHours[6] = bh.SaturdayEndTime;
  49.    }
  50.    // Check if today is a business day - Date
  51.    public Boolean isBusinessDay(Date inputDate) {
  52.      // index i is index into the businessDay array based on inputDate
  53.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  54.      Boolean isBusinessDay = businessDay[i];
  55.      
  56.      if(considerHolidays) {
  57.          isBusinessDay = (isBusinessDay && BusinessHours.isWithin(businessHourId , datetime.newInstance(inputDate.year(), inputDate.month(),inputDate.day())));
  58.      }
  59.      
  60.      return (isBusinessDay);
  61.     }
  62.    
  63.     // Check if today is a business day - DateTime
  64.    public Boolean isBusinessDay(DateTime inputDateTime) {
  65.      
  66.      Date businessDate = inputDateTime.date();
  67.      Time businessTime = inputDateTime.Time();
  68.      
  69.      // index i is index into the businessDay array based on inputDate
  70.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(businessDate)),7);
  71.      Boolean isBusinessDay = isBusinessDay(businessDate);
  72.      Boolean isBusinessHour = false;
  73.      
  74.      if(isBusinessDay){
  75.          isBusinessHour = ( businessTime > getStartTime(businessDate) && businessTime < getEndTime(businessDate) );
  76.      }
  77.      
  78.      return (isBusinessHour);
  79.     }
  80.    // Get the start time
  81.    public Time getStartTime(Date inputDate) {
  82.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  83.      return (startHours[i]);
  84.    }
  85.    
  86.    // Get the End time
  87.    public Time getEndTime(Date inputDate) {
  88.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  89.      return (endHours[i]);
  90.    }
  91.    // Gets next business day, skipping non business days
  92.    public Date nextBusinessDay(Date inputDate) {
  93.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  94.      Date returnDate = inputDate;
  95.      
  96.      do {
  97.          returnDate = returnDate.addDays(1);
  98.          i++;
  99.      } while (!businessDay[Math.mod(i, 7)]);
  100.        
  101.      if(considerHolidays) {
  102.          if(!BusinessHours.isWithin(businessHourId , datetime.newInstance(returnDate.year(), returnDate.month(),returnDate.day() ))) {
  103.              returnDate = nextBusinessDay(returnDate);
  104.          }
  105.      }
  106.      
  107.      return returnDate;
  108.    }
  109.    
  110.    // returns back date in numberOfDays business days
  111.    public Date addBusinessDays (Date startDate, integer numberOfDays) {
  112.         Date returnDate = startDate;
  113.         Integer holidayCount = 0;
  114.         for (integer x = 0; x < numberOfDays; x++) {
  115.             returnDate = nextBusinessDay(returnDate);
  116.            
  117.             if(considerHolidays){
  118.                 if(!BusinessHours.isWithin(businessHourId , datetime.newInstance( returnDate.year(), returnDate.month(), returnDate.day() ))){
  119.                     holidayCount++;
  120.                 }
  121.             }
  122.         }
  123.        
  124.         if(holidayCount > 0) {
  125.             returnDate.addDays(holidayCount);  
  126.         }
  127.         return returnDate;
  128.    }
  129.    
  130.    //get the total business days between two dates
  131.    public Integer getTotalBusinessDays(Date inputDateStart, Date inputDateEnd) {
  132.        Integer totalDays = 0;
  133.        Date returnDate = inputDateStart;
  134.        
  135.        do {
  136.            returnDate = returnDate.addDays(1);
  137.            if(isBusinessDay(returnDate)) {
  138.                totalDays++;
  139.                
  140.                if(considerHolidays){
  141.                    if(!BusinessHours.isWithin(businessHourId , datetime.newInstance( returnDate.year(), returnDate.month(), returnDate.day()))) {
  142.                        totalDays--;
  143.                    }
  144.                }
  145.            }  
  146.        } while (returnDate != inputDateEnd);
  147.        
  148.        return totalDays;
  149.    }
  150.  }



Thanks to my dear friend Purushothaman Annamalai, who shared this code.

Blog: Salesforce Quest

Wednesday 23 September 2015

Final static variables can only be assigned in their declaration or in a static block salesforce

       You cannot assign the final static variable value other than the declaration of variable or static block. If you try to assign it, then you will get an error as "Final static variables can only be assigned in their declaration or in a static block"

To solve this issue, you need to assign like below,

  1. public class StaticFinalController
  2. {
  3.     // assign value for get property variable using static block.
  4.     public static final string staticFinalVariable{get;}
  5.     static
  6.     {
  7.         staticFinalVariable = 'Test Value';
  8.     }
  9.     // Assign value on declaration
  10.     public static final string staticFinalVariable1 = 'Test';
  11.  
  12.     public StaticFinalController()
  13.     {
  14.       system.debug('### Final Value is:::::'+staticFinalVariable );
  15.     }
  16.  
  17. }


Note: Static code blocks run before the constructor.

Reference:

Static and Instance Methods, Variables, and Initialization Code

Activities: Assign Tasks to a Queue Salesforce Lightning

Salesforce announced to assign Tasks to a Queue beginning from Spring'20 release. How does it work? In Setup, enter Queues in th...