Pogo69's Blog

May 11, 2011

CRM Hidden Gems – #1 – Business Closures

Filed under: Cutting Code — pogo69 [Pat Janes] @ 14:18

From time to time I come across functionality in the CRM that isn’t obviously accessible to us as CRM Developers.  A large part of my job is to make the CRM do things that it isn’t supposed to be able to do.  So I get to dig around and hunt for undocumented features.

I’ve decided to start posting some of my findings.  I won’t be posting complete solutions that been developed as a result of my findings, but hopefully some of these ideas can prevent others from having to do quite as much digging as have I when trying to implement some of the more “esoteric” ideas that customers request.

How are Business Closures implemented?

Calendars

Business Closures are modelled in the CRM as a shared calendar.  There is one and only one calendar with the name ‘Business Closure Calendar’.  You can verify this in SQL Server Management Studio with the following query:

SELECT
	CalendarId, Description, Name, IsShared
FROM
	Calendar
WHERE
	Name = 'Business Closure Calendar';

The results of which should look something like:

CalendarId Description Name IsShared
C6F75360-E122-DD11-892E-0003FF6D78E5 Calendar for Business Closure Business Closure Calendar 1

Now, for every Business Closure added to the CRM Organisation, a Calendar Rule is created and attached to the ‘Business Closure Calendar’ Calendar.  Verify this with the following query:

Calendar Rules

SELECT
	Description, Name, EffectiveIntervalStart, EffectiveIntervalEnd
FROM
	CalendarRuleBase
WHERE
	CalendarId = 'C6F75360-E122-DD11-892E-0003FF6D78E5';

using the same CalendarId that we obtained from the previous query.  The results will look something like:

Description Name EffectiveIntervalStart EffectiveIntervalEnd
Holiday Rule Pogo Day Moved 2011-05-12 00:00:00.000 2011-05-13 00:00:00.000
Holiday Rule Pogo Week 2011-05-23 00:00:00.000 2011-05-28 00:00:00.000
Holiday Rule Pogo Rocks 2011-07-01 00:00:00.000 2011-08-01 00:00:00.000
Holiday Rule Next Year 2012-03-01 00:00:00.000 2012-03-02 00:00:00.000

How Do We Gain Access to Business Closures?

This is where it started to get tricky.  The CRM SDK does not provide direct access to the Calendar Rule entity – for ANY messages.  From the SDK:

The class for this entity is calendarrule. The calendar rule entity is accessed by using the messages on the calendar entity. See Calendar Entity Capabilities.

So… back to the Calendar entity again.  The Calendar class in the SDK is documented as having a “calendarrules” attribute defined as an array of “calendarrule” entities:

public calendarrule[] calendarrules {get; set;}

Awesome!?!?  Well… don’t get too excited just yet.  If we explicitly ask for the “calendarrules” attribute, CRM tells us that the ‘Calendar’ entity contains no such attribute!!

QueryByAttribute query = new QueryByAttribute();
query.EntityName = EntityName.calendar.ToString();
query.Attributes = new string[] { "name" };
query.Values = new object[] { "Business Closure Calendar" };
query.ColumnSet = new ColumnSet(new string[] { "name", "calendarrules" });

BusinessEntityCollection calendars = crmService.RetrieveMultiple(query);

So, is does it exist or does it not?  If instead, we specify that we wish all columns to be returned:

QueryByAttribute query = new QueryByAttribute();
query.EntityName = EntityName.calendar.ToString();
query.Attributes = new string[] { "name" };
query.Values = new object[] { "Business Closure Calendar" };
query.ColumnSet = new AllColumns();

BusinessEntityCollection calendars = crmService.RetrieveMultiple(query);

and we inspect the resultant Calendar object(s):

Turns out, it really *does* exist!!  So we can gain programmatic access to the Calendar Rules via the Calendar class, but we have to specify that ALL columns are returned and must NOT specify the column explicitly.

So What’s Going On?

At this point, I’m devolving into pure speculation.

My guess is that because “calendarrules” isn’t a “real” attribute (it is, in fact a collection of entity instances related to their parent entity via the “calendar_calendar_rules” relationship), it cannot be accessed by specifying it as an attribute.  The CRM Web Services return it as an attribute because that is the only mechanism available in the results of a RetrieveMultiple message.

Lessons Learned

  • Not everything in the CRM is as it seems
  • Even if it is documented in the SDK, things are not necessarily as the documentation makes things seem
  • Some things just aren’t documented at all
  • If you really want to achieve something “un” or “under” documented within the CRM, keep digging until you’ve exhausted all possibilities because there are all sorts of hidden gems awaiting the dedicated (stubborn) explorer

					
Advertisements

6 Comments »

  1. Actually, I think “calendarrules” functions exactly like activity parties for “multi-value” lookup fields. Otherwise, you seem to be spot-on in your analysis. Posted this as a response to a development forum thread. Capital work!

    Comment by David Berry — June 30, 2011 @ 04:14

  2. Great stuff, having had a play I needed to access the business closures from Javascript and as with the activityparty although the sdk wont allow direct access using FetchXML you can select directly from both activityparty and calendarrules.

    Good job, saved me a load of time

    Comment by mrmwink — November 17, 2011 @ 21:47

  3. Hi, I need a using for create a new instance de QueryByAttribute ?

    Comment by Silvia — November 24, 2011 @ 07:19

    • Hi Silvia,

      Apologies for the late reply; I’d imagine you don’t require it anymore, however:

      QueryByAttribute is a member of the ‘Microsoft.Xrm.Sdk.Query’ namespace, which is defined in the ‘Microsoft.Xrm.Sdk’ assembly.

      Comment by pogo69 — March 12, 2012 @ 12:01

  4. how to do it in Javascript? thanks 🙂

    Comment by PQ — March 27, 2012 @ 20:29


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: