Thursday 29 October 2015

Set Due Date by Considering Working Days in CRM

Hi,
 
Today we got a requirement to create a task where the due date of it next 2 working days from today.
Immediately, our minds thought very complex logic of having a custom entity and storing values etc to find working days logic..
 
After some search, we have designed a simple approach for it by using OOB Business closures Calendar.
 
Here is the procedure for it.
 
1) Go to Settings-> Business Closures
2) Create your holiday list here
3) Use the following code for getting date by considering the working days as a parameter.
 
public static DateTime GetDatePlusWorkingDays(IOrganizationService iService, int intDaysToAdd)
{
      // Get business closure calendar
      QueryExpression calenderQuery = new QueryExpression
      {
           EntityName = "calendar",
           ColumnSet = new ColumnSet(true),
           Criteria =
           {
               Conditions =
               {
                   new ConditionExpression("name", ConditionOperator.Equal, "Business Closure Calendar")
                }
           }
       };
       EntityCollection businessClosureCalender = iService.RetrieveMultiple(calenderQuery);
       // Advance start date by 1 day until required number of working days have been added
       DateTime requiredDate = DateTime.Now;
       // int daysToAdd = 3;
       while (intDaysToAdd > 0)
       {
           requiredDate = requiredDate.AddDays(1);
           if (isWorkingDay(businessClosureCalender, requiredDate)) intDaysToAdd--;
       }
       return requiredDate;
}

// Check whether a date/time is a working day or not
public static bool isWorkingDay(EntityCollection businessClosureCalender, DateTime time)
{
     // Check if date/time is a Saturday or Sunday
     if (time.DayOfWeek == DayOfWeek.Saturday || time.DayOfWeek == DayOfWeek.Sunday)
     {
           // Weekend = non-working day
           return false;
     }
     // Check if date/time falls within a Business Closure period
     if (businessClosureCalender.Entities.Count > 0)
     {
           EntityCollection businessClosureRules = (EntityCollection)businessClosureCalender.Entities[0].Attributes["calendarrules"];
           foreach (Entity rule in businessClosureRules.Entities)
           {
                if ((DateTime)rule.Attributes["effectiveintervalstart"] <= time && (DateTime)rule.Attributes["effectiveintervalend"] > time)
                {
                     // Business closure= non-working day
                     return false;
                }
           }
      }
      // Date/Time is not a weekend or within a business closure period, so it is a working day
    return true;
}
 
Hope this helps.
 
--
Happy CRM'ing
Gopinath

No comments:

Post a Comment