Search code examples
c#dynamics-crmdynamics-crm-365

How to get business hours details programmatically in Dynamics 365


I have several SLAs in my Dynamics 365 ORG. Every SLA have different business hours attach to it.

I have a requirement that needs to fetch the details of the business hours in the SLA programmatically (call within plugin/custom workflow).

The details that I need will be:

  • The working hours each day (e.g Monday 8 - 5, Tuesday 8.30 - 5.30, etc)
  • The list of break time
  • The List of holidays attached

Have tried using retrievemultiple and CRM Message like QueryScheduleRequest and ExpandCalendarRequest but so far haven't manage to get all the details.


Solution

  • You can get business hours (calendar) details manually but there are quite a few steps. I've outlined them below roughly, but I'd recommend you create a quick console application to debug and step through the attributes available to you in real time.

    First query for the SLA you want. If you have the ID then use:

    var sla = service.Retrieve("sla", ID, new ColumnSet(new string[] { "businesshoursid" });
    

    Then get the ID of the business hours associated with the SLA:

    var businessHoursId = sla.GetAttributeValue<EntityReference>("businesshoursid").Id;
    

    Then retrieve the business hours (calendar) itself:

    var calendar = service.Retrieve("calendar", businessHoursId, new ColumnSet(true));
    

    A calendar can have multiple rules. Retrieve them using:

    var calendarRules = calendar.GetAttributeValue<EntityCollection>("calendarrules");
    

    These outer calendar rules will have a pattern which you can see using

    var firstRulePattern = calendarRules[0].GetAttributeValue<string>("pattern");
    // FREQ=WEEKLY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR
    

    But to get the working hours each day, you'll need the inner calendars. Using the first rule as an example:

    var innerCalendarId = calendarRules[0].GetAttributeValue<EntityReference>("innercalendarid").Id;
    var innerCalendar = service.Retrieve("calendar", innerCalendarId, new ColumnSet(true);
    var innnerCalendarRule = innerCalendar.GetAttributeValue<EntityCollection>("calendarrules").Entities.FirstOrDefault();
    

    From your inner rule, note the attributes duration and offset. These values are in minutes and will give you the working hours each day.