Last month a colleague of mine asked if it would be possible to synchronize Dynamics CRM service calendars and holiday calendars using my Configuration Data Mover tool. At first it looked like it would be complicated, but after trying a few different approaches, it turned out to be incredibly simple. Before getting to the solution, let's look at how Dynamics CRM stores calendar data.
(If you don't care about the details of how it all works, skip to the end of this post for a link to download a sample job file.)
Dynamics CRM calendar entities
There are only two types of calendar entities in Dynamics CRM - calendars and calendarrules.
A calendar describes the availability of a service or a resource. Calendars are related to calendarrule records, which include details about the duration, start and end times, and recurring patterns of events included in the calendar.
Although there's only one calendar entity in Dynamics CRM, there are four types of calendars that are differentiated by their "type" attribute:
- Default (type 0) - All calendars that are not customer service, holiday schedule, or inner calendars.
- Customer Service (type 1) - Service calendars for customer service.
- Holiday Schedule (type 2) - Holiday schedule calendars for customer service.
- Inner Calendar type (type -1) - Inner Calendars are used by other calendars to build a graph of time slots available for customer service or service scheduling to be performed.
Calendar records also have a self-referencing relationship. This is how a customer service calendar can have a linked holiday schedule calendar.
Here's a FetchXML query to retrieve all the customer service calendars in an organization:
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0" > <entity name="calendar" > <attribute name="name" /> <attribute name="typename" /> <attribute name="type" /> <attribute name="primaryuserid" /> <attribute name="isshared" /> <attribute name="holidayschedulecalendaridname" /> <attribute name="holidayschedulecalendarid" /> <attribute name="description" /> <attribute name="businessunitid" /> <order descending="true" attribute="type" /> <filter type="and"> <condition attribute="type" operator="in"> <value>1</value> </condition> </filter> </entity> </fetch>
As for the calendarrule records, they cannot be directly modified using the SDK, but you can access them through their parent calendar records. Although the query above does not explicitly request the calendarrules, CRM does return them in the response. This allows the Configuration Data Mover to copy the calendars with their associated rules and closures to a destination organization relatively easily.
Copying the data
Copying service and holiday calendars from one CRM organization to another with the Configuration Data Mover requires three steps:
- Copy inner calendars
- Copy holiday calendars
- Copy customer service calendars
Here's a link to a sample job file that is already set up to do that: calendars-closures-noconnection.xml.
One thing to keep in mind is that the schema I was using to serialize output data to a flat-file destination up to version 220.127.116.11 does not support a nested entity structure like CRM uses to store calendar rules, so you need to make sure you are using that version or later if you want to use a flat-file source/target jobs. Otherwise you will get an error when attempting to import the calendar data from a flat-file source.
Getting the Dynamics CRM Configuration Data Mover
The source code is available in my GitHub repository here.
A compiled version can be downloaded here.