Microsoft Typescript

In the last few years Javascript has largely taken over the world, ever since we first laid eyes on Google Suggest and Outlook Web Access to see what could be possible using Javascript (and later AJAX) to make Web Applications as fluid and dynamic as desktop applications, Javascript has been a growing technology. (debatably outstripping it’s parent language Java which it now has little in common with)

The counterbalance to this is that Javascript brings all the bad old ways of any other scripting language – no intellisence, no compilation, difficult to use namespaces and well managed names, fairly poor error handling and a worrying tendency to code bloat.  These problems can be avoided through good development standards and carefully usage, but the language naturally leans into some difficult to manage areas for the average developer.

(how many Dynamics CRM projects have we seen with several hundred lines of Javascript stuffed into the onLoad event – it’s better in CRM 2011 with the proper use of includes Web Resources but can still be a problem)

Despite all these points – Javascript is used the world over because it works in all browsers and adds the vital scripting logic to support basic HTML.

Today however Microsoft have released a simple framework that acts to allow developers to build Javascript in Visual Studio in a more manageable C# Development format that then ‘compiles’ into native Javascript.

http://www.zdnet.com/microsoft-takes-the-wraps-off-typescript-a-superset-of-javascript-7000004993/

This is aimed at providing developers a more structured approach to writing Javascript – in a way this is slightly off-topic for CRM 2011 Consultancy and Development, but as a long-time fan of making sure all your CRM Javascript (whether in CRM 4 files, or CRM 2011 Web Resources) is developed in Visual Studio and stored in a source-controlled Project, is also in a way very on-topic for CRM 2011 development.

TypeScript Hello World

When learning anything new in the development world, it tends to help by stripping all the complexity or ambiguity away by producing the most basic usage imaginable – the hello world example.

First of all – you can download the Visual Studio 2012 extension for Microsoft TypeScript at the following link: http://www.microsoft.com/en-us/download/details.aspx?id=34790

This installs a new Project Type into Visual Studio:

Creating a new TypeScript Project in Visual Studio 2012

Creating a new TypeScript Project brings up a Visual Studio Project containing  the following files:

App.ts – the pre-compiled source file for the TypeScript, this our code for developing the program code which will be compiled into Javascript.

App.js – the raw Javascript which the TypeScript compiler produces from the App.ts

Default.htm – the HTML file which includes the ‘app.js’ as a normal Javascript include.

We can then edit our ‘App.ts’ code file using a more familiar C# syntax as way of writing the code at a higher level of abstraction to the underlying Javascript.

As way of an example, we could create the following simple object:

class MyClass {
    _activatedString: string = "(( hello world ))";
    _deactivatedString: string = ")) goodbye world ((";

    _myHTMLElement: HTMLElement;
    _stateElement: HTMLElement;

    constructor (outputElement: HTMLElement, stateElement: HTMLElement) {
        this._myHTMLElement = outputElement;
        this._stateElement = stateElement;        

        this.deactivate();
    }

    public click() {
        if (this.getActive() == false) {
            this.activate();
        }
        else {
            this.deactivate();
        }
    }

    private getActive(): bool
    {   
        if (this._stateElement.attributes["value"] == "true") {
            return true;
        }
        else {
            return false;
        }
    }

    private setActive(value: bool)
    {
        if (value == true) {
            this._stateElement.attributes["value"] = "true";
        }
        else {
            this._stateElement.attributes["value"] = "false";
        }
    }

    private activate() {
        this._myHTMLElement.innerText = this._activatedString;
        this.setActive(true);
    }

    private deactivate() {
        this._myHTMLElement.innerText = this._deactivatedString;
        this.setActive(false);
    }
}

NOTE: Proof of the TypeScript approach might be in whether WordPress’s CSharp engine is better than the Javascript engine for showing the source code here.

This gives us a simple object that encapsulates two HTML Elements, uses one as the object’s output and the other as a hidden element for storing the object’s viewstate. 

This compiles from the TypeScript to the following raw Javascript:

var MyClass = (function () {
    function MyClass(outputElement, stateElement) {
        this._activatedString = "(( hello world ))";
        this._deactivatedString = ")) goodbye world ((";
        this._myHTMLElement = outputElement;
        this._stateElement = stateElement;
        this.deactivate();
    }
    MyClass.prototype.click = function () {
        if(this.getActive() == false) {
            this.activate();
        } else {
            this.deactivate();
        }
    };
    MyClass.prototype.getActive = function () {
        if(this._stateElement.attributes["value"] == "true") {
            return true;
        } else {
            return false;
        }
    };
    MyClass.prototype.setActive = function (value) {
        if(value == true) {
            this._stateElement.attributes["value"] = "true";
        } else {
            this._stateElement.attributes["value"] = "false";
        }
    };
    MyClass.prototype.activate = function () {
        this._myHTMLElement.innerText = this._activatedString;
        this.setActive(true);
    };
    MyClass.prototype.deactivate = function () {
        this._myHTMLElement.innerText = this._deactivatedString;
        this.setActive(false);
    };
    return MyClass;
})();

In affect this is simply a clever use of the Javascript Prototype pattern which I’ve seen used for CRM 2011 Projects – but you can clearly see the similarities between the .ts and the .js, but the TypeScript here does seem to produce more human readable code and gives a set of syntax that is much in common with C#.

We also can leverage strongly typed fields such as string, number and HTML Element as opposed to Javascript’s var and object.

The big advantage to both OO Javascript and the TypeScript here is to instance the object as a single black-box unit of code, and potentially instance multiple times – so if we look at the HTML which will invoke this Javascript:

<body>
    <h1>TypeScript HTML App.</h1>
   
    <input id="t1_button" type="button" value="Click Me" />
    <input id="t1_state" type="hidden" value="false" />
    <div id="t1_content"></div>

    <input id="t2_button" type="button" value="Click Me" />
    <input id="t2_state" type="hidden" value="false" />
    <div id="t2_content"></div>    
</body>

We can see two sets of HTML controls which our script will use as (mostly) encapsulated objects:

window.onload = () => {
    // declare 1st instance of the class
    var myClass = new MyClass(document.getElementById('t1_content'), document.getElementById('t1_state'));
    document.getElementById('t1_button').onclick = () => myClass.click();

    // declare 2nd instance of the class
    var myClass2 = new MyClass(document.getElementById('t2_content'), document.getElementById('t2_state'));
    document.getElementById('t2_button').onclick = () => myClass2.click();
};

This gives us 2 simple controls each with their own viewstate:

The Resulting HTML Webpage using the Javascript compiled by the TypeScript – showing two controls with their own javascript managed viewstates.

And when working in the TypeScript Visual Studio environment – a good level of intellisense for using the classes we define:

Using the TypeScript Intellisense in Visual Studio 2012 for the MyClass type

So far, so normal web development, but this could provide a useful way of developing and producing (or at least managing) CRM Javascript and certainly could be a help for HTML Webresources.

Depending on how useful TypeScript proves to be for CRM Form Scripting and how much of the Object Orientated Intellisence model we can leverage, this could be a topic to keep in mind for CRM Development.

Handy TypeScript Links

I imagine this will expand depending on how popular TypeScript becomes, but the following links come from more experienced JavaScript developers looking into TypeScript from a similar Hello World perspective:

http://www.devcurry.com/2012/10/hello-typescript-getting-started.html

http://www.amazedsaint.com/2012/10/microsoft-typescript-and-quick.html

http://blog.markrendle.net/2012/10/02/the-obligatory-typescript-reaction-post/

Posted in Consultancy, Development, JavaScript, Technical | Tagged , , | Leave a comment

The Customer in CRM – Going Social?

In between the technical concerns of deploying a CRM System such as Dynamics CRM there is always the wider more important strategy of how a company incorporates a CRM Solution (of which the system is but a part of) into their business – and this strategy obviously has aims or expected benefits that come from the changes involved.

Often these aims have looked inward to a business and as a result focused on the Business User Experience of a CRM Solution, however a strongly implemented CRM Solution should also focus on the other key part of a business, the Customer.

This post aims to look at how the Customer may have changed in the recent past and how this may affect the Analysis and Design of a CRM Solution in terms of examining the Customer Experience hand-in-hand with the User Experience.

The rise of a social product

Often in today’s culture customers have a concept of not simply buying a ticket or going to an event – but buying into the event, the social nature of whatever that event is.  This may sound superfluous – but if we look at how the world has changed with the advent of the network providing instant easy access to almost everyone:

– How many people go to the cinema to watch a film and then check out other people’s thoughts and comments on the film the next day? Not just limited to traditional reviews of the film, but comments on people’s reactions to the film – often mostly from their social circle of online friends but also from other random sources.

– How many people now regularly post what gigs or festivals they are attending, and then use replies or apps to then guide what they will do when they are there.

– Not to mention the number of people who will update their Status to register that a particular product or purchase has arrived, or to detail a particularly good (or bad!) experience they have had with a brand or company.

Essentially people (or customers) have always done this and discussed events or products with their friends or family, giving rise to the power of word of mouth marketing and the ability for customers to trust products or suppliers based on this word of mouth.

Going Social is a bit of a myth, people have always been social and naturally enough taken that into how they buy products and services.

However the advent of social media has given us all new channels to communicate this word of mouth, and in a way define ourselves via certain experiences, products and brands that we associate with.

Often when I have read about these applications of Social Media in the past I have been quite sceptical about whether people actually engage or want to engage on these points – however I think the rise of Web 2.0 (which is now almost old-hat, but I guess that is the point in a way!) with the mainstream adoption of Facebook, Twitter and Mobile Apps have changed people’s perceptions on these points.

Having worked in ‘old-style’ Sales and Event environments where our promotion of products was largely limited to traditional outlets (face-to-face, leaflets and so on) – it has become increasingly common for customers to expect and want more active social promotion than I have seen in the past; I found customers wanting an event to be something that is worth buying into, and so something that already has that social presence that they can spread to their friends/followers as a way of identifying themselves.

In a way this is how we might define the outcome of the Customer Experience that the customer has with our service or product, essentially the result of the relationship between us as the supplier and the customer.  This relationship being at the heart of CRM as a strategy for our business.

Where is the Customer in CRM?

What this aims to describe is the ‘Customer Experience’ or how the Customer relates to a particular Product or Service which should in theory be at the heart of what Customer Relationship Management is all about – the understanding and possible facilitation in how Customers relate to a Product or Service.

However if we look at many of our CRM Projects today, how many of them look into the idea of how the Customer looks at the business’s product? Often CRM Projects largely focus on automating or assisting a business’s internal processes – sometimes the goal being simply to improve existing processes via more sophisticated technology.

(how many times have we seen the requirement to replace X, Y. Z legacy system to avoid £30,000 support costs a year say; or to produce a all-singing all-dancing system that integrates better to reduce data re-entry?)

There is obviously nothing wrong with these projects, saving money and being more efficient as a business is a good aim – however are these really CRM-focused projects, is the customer at the heart of these projects or simply a concept described through the more important needs of the business.

In a way these are more Business Process Improvement projects that happen to use a CRM Application to achieve their results – you might use Dynamics CRM to give the Sales Team a standardised process that then feeds Order information to the back-end ERP system to allow Invoice statuses to be visible to the front-office as well as the back-office, but where is the customer in that project brief?

Am not sure that defining terms such as ‘what is real CRM’ is particularly helpful – however the following points may be useful when asking the question ‘where do your customers fit into this project?’ as opposed to CRM being purely focused on the requirements of the business rather than the requirements of the customers:

– When does the Customer interact with this business process

– Is the Customer interacted with (you to them), or do you expect the customer to interact with you? (them to you)

– What channels do you use or expect the Customer to interact with you throughout the process.

– Does the Customer know where they are with you at different stages in the process?  And if so, how?

There is a lot of fluff and hype around social media and terms like Customer Experience which can sometimes be unhelpful in understanding how a business might actually benefit and ultimately make money from these sometimes abstract concepts – however as CRM Consultants running workshops with different businesses, I think it is useful to think along these lines and frame questions away from ‘what are your requirements for a CRM Solution’ and more ‘what are the requirements that your customer has of you’ and then for us to provide the solution that delivers these customer-focused requirements.  In a way this dove-tails with the common (and crucial) concept of providing a User Experience for a new CRM System, but in a way that provides a Customer Experience as part of how a CRM Solution fits into the business.

Obviously the customers may never see or interact with the actual CRM System, but their experience of the business is obviously a crucial part of the CRM Solution that the system is a part of.

Does this Customer Experience really matter?

Whilst the idea of managing a customer experience towards building a better relationship is a good natural idea for a business – does this idea actually translate into higher sales in a real-world sense, and if so how can we actually ‘prove’ this to validate the idea.  Marketing Departments everywhere know the problem of convincing budget-holders that their efforts produce tangible sales from the back of brand promotion and other indirect channels.

In a sense more modern technologies allow us to roughly measure the benefits of the relationship that a customer has to us as the business – Twitter/Facebook hashtags, followers and other factors give us more tangible metrics that can be captured within a CRM Solution to give us a feel for the strength and productivity of a relationship.

To give a practical feel for this, I imagine a baseline of factors to capture might be the following:

– Relationship Strength, to describe how we perceive the customer relates to our business.

– Influence Rating, to describe the customer’s likely ability to influence other customers within the market.

– Network Rating, how well networked is a particular customer.  This can overlap with a customer’s level of influence but is essentially a different attribute given that a customer can be well-networked but not a strong influencer.

– Purchase Strength, how much purchasing power does the customer bring to our business – this factor may (and should) be known by CRM itself as opposed to external connections to Social Media but can then be compared against the strength of the Relationship and level of Influence.

These factors are not new and have been previously captured within CRM Solutions, but the rise of Social Media allows us a more direct method of collecting this data – even to automatically harvesting the number of mentions or updates concerning our business or product directly from Twitter or other media via CRM integrated with the media’s API.

The strength here being the ability for CRM Solutions to crawl Social Media alongside the usual manual factors and automatically give a score to a customer as way of identifying key customers that act as advocates or influencers for your brand.

Conclusion

Obviously many of these concepts are not new and have been discussed at some length with the now wide-spread use of Facebook, Twitter and others; but I believe these ideas have come of age now to the point where these are practical concerns for many businesses and deserve incorporation into our thoughts and designs for CRM Solutions – particularly in the Business-to-Consumer market which is increasingly cut-throat with the recessionary climate we find ourselves in, and the ability to build a strong brand that customers want to be a part of provides a powerful tool in resisting recessionary pressures.

Am always minded to remember that many businesses across the world are run (and sometimes very successfully) on a mish-mash of Excel Spreadsheets a million miles removed from these concepts, and often our initial brief as CRM Consultants and Project Managers is to simply consolidate these into a CRM Database, but I think that these concepts should increasingly find a place in the wider CRM Strategy we should be advising for a business.

Am a huge advocate of properly thinking through the User Experience for the Analysis and Design of CRM Solutions as I have seen many specifications which concentrate purely on the technical implications of a design without reference to the end-user, and I think defining the Customer Experience of the CRM Solution is now becoming just as important to creating a successful project.

And above all after a weighty 1500 words or so – Happy 2012 to everyone reading this!  After a heady wait since 2005, the Olympics are coming to my corner of the world very soon now!

References / Interesting Reading

There is many great references on how Social Media interacts with CRM, the following is a small list that I have found a good read on the topic without losing sight of the day-to-day reality of business:

How should firms adapt to serve the channel agnostic customer? – MyCustomer.Com

http://www.mycustomer.com/topic/customer-intelligence/how-should-firms-restructure-channel-agnostic-customer/126641

CRM 2012 Forecast – The Era of Customer Engagement – Paul Greenberg, ZDNet

http://www.zdnet.com/blog/crm/crm-2012-forecast-the-era-of-customer-engagement-part-i/3753?tag=search-results-rivers;item0

Posted in Consultancy, Project Management, Social CRM | Tagged , , , | 2 Comments

Integrating Dynamics CRM Data into SharePoint 2010

Years ago I worked on a development team looking at the requirements of a good CRM System that could be developed to fit various business models, and one of the key requirements we determined was the ability to pull data from other sources around a business into the solution as a way of integrating business data (possibly as external entities) into the core business CRM Solution.

Sounds simple in theory but can be pretty tricky in practise.

When SharePoint 2007 came on the scene a few years ago, the Business Data Catalogue looked an ideal solution to this requirement – able to define and pull certain areas of data from external Datasources by defining them as Business Data Entities.  However despite the BDC being sold as a ‘no-code’ tool for integrating this data into SharePoint, it did involve specifying your Data Areas via a bespoke XML file – and to me documenting the schema of your data via XML felt pretty much like writing code, and not easy to implement. (honourable mention to Lightning Tools which made this process easier with a workable front-end)

With SharePoint 2010 I thought it was about time to take another look at this topic as the Business Data Catalogue has regenerated into the Business Connectivity Service and now comes alongside SharePoint Designer to allow for easier actual ‘no-code’ solutions to this age-old problem of integrating external sources of data into a single Line of Business Solution.

To look at how this can be implemented in SharePoint and coming from a Dynamics CRM angle, this post will be focused on how we can integrate CRM 2011 data into SharePoint 2010.

To make this post more readable given the technical complexity of SharePoint, the article is broken down into the following sections:

1. SharePoint Designer
2. Defining an External Content Type
3. Using the External Data within other SharePoint Lists
4. Adding Custom Actions
5. Conclusion and References

1. SharePoint Designer

SharePoint Designer is a fantastic little desktop application which connects to a SharePoint site to increase the speed and ease in which standard customisations can be added to the site.

Microsoft first tried this approach by adding functionality to FrontPage (TODO: Link) to connect to SharePoint 2003 sites with mixed results, and I often found it easier to simply perform the customisations using SharePoint’s native Web Interface – however in my experience SharePoint Designer is leaps and bounds ahead of these early efforts and makes adding and customising Custom Lists and other aspects of SharePoint sites considerably easier and quicker than the native Web Interface.

image

The SharePoint Designer home-page

This post will refer heavily to the SharePoint designer (alongside the Web Interface in places) for making the necessary changes to a SharePoint Site to facilitate the integration with CRM Data.

The SharePoint Designer is freely available can be downloaded via the following links:

Download SharePoint Designer (64-bit) http://www.microsoft.com/download/en/details.aspx?id=24309

Download SharePoint Designer (32-bit)http://www.microsoft.com/download/en/details.aspx?id=16573

2. Defining an External Content Type

First of all we need to activate External Content Types within our deployment of SharePoint via the Central Administration area by ensuring that Business Data Connectivity Service is running.

This will allow us to view and amend the list of External Content Types within SharePoint Designer:

image

Showing the list of External Content Types in a SharePoint Deployment via the SharePoint Designer

From here we can add a new External Content Type that acts as a wrapper to show CRM Data within SharePoint.

This is done via the following steps:

(1) Add a new External Content Type with a unique name.

image

Creating the new External Content Type in SharePoint Designer

(2) Define the External System that the External Content Type is reading data back from – the SharePoint Designer allows a external system to be defined from either a .NET Type, SQL Server or WCF Service.

image

Selectiong the type of connection for the External Content Type

For a simple example of how we can connect SharePoint to CRM we can opt for a SQL Server Datasource that then uses the CRM View to facilitate a read-only connection from CRM to SharePoint using CRM’s Filtered Views.  This provides a direct connection between CRM and SharePoint that maintains the CRM Security Model – however this does need to be Connected as the User’s identity such that the Windows Authentication for the account accessing the SharePoint List is used for accessing the Filtered View.

image

Defining the SQL Database details for the External Content Type's connection

With the underlying connection in place, we can choose which table or view to use as the Data Source – in this case, the view for ‘FilteredContact’.

image

Selecting the SQL View or Table to use as the source data for the External Content Type

(3) Define the Read Item and Read List Operations

With the source data selected, different operations can be defined to be made accessible within SharePoint to effect the data.  In this case using the Filtered View for the Contact entity, we can define simple read-only operations for reading back lists of Contacts or an individual Contact Record into SharePoint.  Initially for reading back a single record from CRM:

image

Defining the Read Item Operation for the External Content Type

Defining this operation within SharePoint allows us to define which fields should be read back from the CRM Datasource when viewing a record of this external type.

Initially to define the unique identifier field to be used:

image

Defining the Unique Identifier for the Read Item Operation

And then to define which other fields should be pulled from the CRM Datasource into the SharePoint External Content Type:

image

Specifying which fields from the source data will be used as part of the External Content Type

With the same being done for the List Operation to ensure that the SharePoint External Content Type can be used for showing either individual records or lists of records within SharePoint.

(4) Set Permissions for the External Content Type

With the two basic read operations defined, our last step to configuring the External Content Type is to define which SharePoint users will have permissions to view data from the External Content Type, to do this we must access the External Content Type page from within the SharePoint Web Application as opposed to the SharePoint Designer.

This is done by opening the SharePoint Central Administration area and then browsing Application Management, Manage Service Applications and then Business Connectivity Services.  This then opens the Web Interface for adding or making changes to External Content Types in the same fashion as we have been doing through the SharePoint Designer.

Selecting the External Content Type we wish to modify will then bring up a modification form for the External Content Type – which includes a ribbon button for ‘Set Object Permissions’.  This brings up a prompt to select which Users or Groups should be able to access data through the External Content Type.

image

Adding a particular Active Directory Group or User to have access to work with the External Content Type

This will then be shown in the SharePoint Designer underneath the Permissions tab:

image

How the resulting Object Permissions are shown in SharePoint Designer

(5) Create a SharePoint List to present the External Content Type

With the connection and e are able to create a new SharePoint List based from this External Content Type to make this data available in the standard SharePoint List format:

image

Creating a new SharePoint List to present the External Content Type within SharePoint

NOTE: If at this step you receive a ‘No Finders available in the View Group’ error, this is a generic SharePoint Designer error which can have many causes – in regards to using CRM Data as an external content type for SharePoint this is often related to using the calculated view fields such as ‘accountidname’ that SharePoint then struggles to incorporate into the Content Type.

With the List created we should now have a External Content Type linked to a particular SharePoint List with associated user interface:

image

The resulting SharePoint List connected to the External Content Type

Which also now appears in the list of SharePoint Lists in the SharePoint Designer:

image

The resulting SharePoint List shown in the 'List of Lists' within SharePoint Designer as a External List

From here we have a list of data within SharePoint that is synchronised with a particular CRM entity – such that any data recorded within CRM is accessible via SharePoint:

image

The final List shown within SharePoint, listing the Contact records held in Dynamics CRM

This List can then be modified as per any other SharePoint List to modify the View Columns or Sort Order.

3. Using the External Data within other SharePoint Lists

This external content list in SharePoint can then be used within other SharePoint-only lists as a lookup – providing a method for using reference data pulled from CRM to store data solely within SharePoint via a Lookup field type.

image

Adding a new Lookup field based on the External CRM List on a separate SharePoint Expense List

Allowing entries to be recorded in the list against a list of lookup records which is being synchronised from CRM.

image

Selecting a CRM Contact within SharePoint to be used as the value of the Lookup field in this separate Expense list

Allowing the selection of the lookup value from the list of CRM records, either via automatic text resolution or a lookup window:

image

The Lookup Selector Window in SharePoint showing the list of CRM Contacts available for selection

In effect allowing the selection of a particular CRM Contact for each Expense, in effect building an association between the SharePoint Expense record (in this case, an expense) and the CRM Contact record – bridging the two systems relatively seamlessly.

image

The resulting Item Record in the separate Expense List, linked back to the CRM Contact record through the external list.

This then allows us to effectively synchronise data between CRM (or any other SQL, .Net or WCF system for that matter) into SharePoint, and then put this data to use in SharePoint via linked lists or reporting – further allowing SharePoint to be a ‘one-stop-shop’ of data from around an organisation.

4. Custom Actions

In addition to showing CRM Data within a SharePoint List we can add actions within SharePoint that can act to manipulate the data – in a simple case this can be simple as opening the CRM Form for the selected record from the SharePoint List.

To do this we can define a Custom Action that opens a dynamics CRM URL, which we can add into the SharePoint External Content Type by browsing to the Content Type within the Business Connectivity Services

image

Viewing the External Content Type in the SharePoint Web Interface

This will bring up a New Custom Action form where we can define what this particular action will do – in this simple case, providing the URL in CRM that the Action should open and any dynamic properties (such as the Record Id for the record in CRM that should be opened) that should be supplied to the URL.

image

Adding a Custom Action to the External Content Type through the SharePoint Web Interface

SharePoint’s Custom Action format for parameters allows a parameter to be defined from any of the fields in the External Content Type as a Parameter No – this Parameter No can then be used in the URL via supplying the number as {0}, {1} and so on.  So with ‘contactid’ defined as parameter {0} we can use the following URL to dynamically open the correct CRM Form URL:

http://[CRMServer]:5555/CRMReports/Viewer/DrillOpen.aspx?ID={0}&LogicalName=contact

This then adds the action to new instances (such as lists) where the External Content Type is used within SharePoint:

image

The Custom Action shown within the SharePoint List for each item.

Clicking this action will then open the Contact record within MSCRM:

image

Opening the record in CRM 2011 as a result of the action in SharePoint

5. Conclusion and References

This post outlines how to use the Business Data Connectivity Services Application in SharePoint 2010 to incorporate data from Dynamics CRM into a SharePoint List – but why would we want to do this?  The simple answer is to continue the SharePoint principle of encompassing a one-stop-shop of data throughout an organisation – in this fashion CRM Data can be constantly accessible from within a SharePoint site for publication and reporting outside the standard CRM User Group.

When we consider how SharePoint List Data can then be used within other areas of SharePoint, particularly within Search, this gives a powerful outlet for sharing data and incorporating CRM Data into the central business intelligence of an organisation.

This can be a powerful step to ensuring that SharePoint is the joining piece for integrating an organisation’s data into a single place across many possible disparate systems – and providing a single venue for Content Management and Reporting.  In subsequent posts I may aim to expand on this further, in terms of how a Business Solution can incorporate SharePoint as the ‘hub’ for the business’s individual systems whether they be CRM, Accounting/ERP, HR or indeed any other operational systems.

The following post from the MSDN Magazine was the inspiration for my revisiting this area of SharePoint, and is an excellent read on the topic:

http://msdn.microsoft.com/en-us/magazine/ee819133.aspx

Posted in CRM 2011, Integration, MSCRM, SharePoint | Tagged , , , , , | 10 Comments

CRM 2011 Integration with SharePoint: Custom Document Management

The previous post on CRM and SharePoint integration focused on looking at the workings of the default CRM 2011 functionality to see how the underlying structure of SharePoint Site and SharePoint Document Location records could cater for much more than the basic ‘out-of-box’ Document Management.

This article aims to describe how we can leverage this flexibility via custom development to define a more bespoke Document Management solution between SharePoint 2010 and CRM 2011, using different arrangements of Document Libraries, Folders and an initial look at Metadata.

Developing a Plugin to integrate CRM to SharePoint

Towards achieving a custom format of Document Management between CRM and SharePoint, we can look at creating a Plugin which will automatically integrate a new CRM Record with a new SharePoint Document area for a particular entity or entities in CRM.

This is similar to how custom Document Management Integrations were often implemented between CRM 4 and SharePoint 2007, however with the advent of SharePoint 2010 we are able to use the SharePoint Client Object Model to make this development simpler and less code-heavy. The aim here being to focus on the desired business logic of our Document Management and not get bogged down with the coding for the SharePoint development.

However our first difficulty here is incorporating the SharePoint Client Object Model DLL in the CRM Plugin to allow us to communicate remotely with our deployment of SharePoint 2010. CRM Plugins are standalone DLLs which are then registered to the Database which makes referencing external DLLs such as the SharePoint Client Object Model difficult – however this can be done via a variety of methods:

(1) Register the Plugin DLL via Disk, and then store both the Plugin DLL and SharePoint Client Object Model DLL in the Bin folder of the CRM Website.

This is functional solution to the problem but in impossible for Online or IFD Deployments of MSCRM.

(2) Merge the SharePoint Client Object Model DLL into your Plugin DLL to form a composite Plugin.

This is almost a functional solution, however the merge makes the Plugin DLL very large and often too large to correctly register with CRM – and is a bit of a hammer to crack to a nut really.

(3) Place the SharePoint Client Object Model DLL in the GAC for the Plugin DLL to reference.

This is the most practical solution as allows us to register our Plugin to the Database – but we have no access to the GAC for Online and usually limited access to the GAC for IFD Deployments of CRM.

(4) Develop the Plugin to call out to either a Webservice which can then access SharePoint.(either one of the standard SharePoint Webservices or a custom Webservice which can then invoke the SharePoint Client Object Model)

This is a workable solution for CRM Online deployments but does require SharePoint to be publically facing to accept the Webservice calls – the best bet in this scenario would be to have CRM Online communicating to Public Webservice which in turn communicates to SharePoint Online.

For this example, we will look into option (3) of using the GAC, as this is likely the most appropriate option of On-Premise deployments of CRM.

Adding the SharePoint Client Object Model DLL to the GAC

Assuming we have access to our CRM and SharePoint Servers, adding the Client Object Model DLL to the GAC is easily done.

First of all we can find the SharePoint DLL on the following location of our SharePoint Server where can take a copy for use on the CRM Server – C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI.

image

The location of the SharePoint Client Object Model on a SharePoint 2010 Server

There is then various ways of adding these DLLs to the GAC, but the simplest is simply to use Windows Explorer to add the files to the following location on the CRM Server – C:\Windows\Assembly.

image

The SharePoint Client DLLs added to the GAC

With these DLLs copied into the GAC, we should be ready to develop a new CRM Plugin which incorporates the Share Point Client Object Model as a reference.

Referencing SharePoint DLLs in Visual Studio

Referencing the SharePoint Client Object Model DLLs in Visual Studio

Developing the Plugin

For the Plugin to create a new Document Library for each new Account, the logic of the Plugin’s execute method will need to carry out the following steps.

(1) Check whether the Account (or other record in CRM) already has a Document Location associated.

(2) If not, then create a new Document Library in SharePoint

(3) Associate the Account in CRM to the newly created Document Library by creating a new SharePoint Document Location record in CRM.

These steps will involve methods that communicate to both CRM and SharePoint, such that the Plugin will break down into three distinct sets of code: methods to retrieve/insert data to CRM, methods to insert data to SharePoint and the core Plugin Execute call that uses these methods to carry out the logic.

If initially we look at how the code could implement this core logic:

#region Plugin Business Logic

string recordName = string.Empty;
Guid recordId = Guid.Empty;

if ( crmAccount.Attributes.Contains(entityIdField) )
{
    recordId = (Guid)crmAccount.Attributes[entityIdField];
}
else
{
    throw new Exception("CrmConsultancy.CRM2011.CustomDocumentManagement.SharePointIntegration :: Could not find a '" + entityIdField + "' attribute for the " + crmAccount.LogicalName + " record");
}

bool createDocumentLibrary = false;

if (crmMethods.DoesCRMRecordHaveSharePointLocation(recordId) == false)
{
    createDocumentLibrary = true;
}

if (createDocumentLibrary == true)
{
    if (crmAccount.Attributes.Contains(entityNameField))
    {
        recordName = (string)crmAccount.Attributes[entityNameField];
    }
    else
    {
        throw new Exception("CrmConsultancy.CRM2011.CustomDocumentManagement.SharePointIntegration :: Could not find a '" + entityNameField + "' attribute for the " + crmAccount.LogicalName + " record");
    }

    SPSite connectedSite = crmMethods.GetDefaultSPSite();
    if (connectedSite != null)
    {
        // create the Document Library in SharePoint
        SharePointMethods sharePointMethods = new SharePointMethods(connectedSite.AbsoluteUrl, "mySharePointUserAccount", "myPassword", "myDomain");

        string documentLibraryName = sharePointMethods.CreateDocumentLibrary(recordName, "Document Library for CRM Record");

        Guid newSharePointLocationId = crmMethods.AddRootSharePointLocation(connectedSite.Id, entityLogicalName, recordId, recordName, documentLibraryName);

    }
    else
    {
        throw new Exception("CrmConsultancy.CRM2011.CustomDocumentManagement.SharePointIntegration :: CRM is not configured for SharePoint Document Management");
    }

}
else
{
    // CRM Record is already connected to a SharePoint Document Location
    // likely no need to create and link to a new location, take no further action
}

#endregion

We can see here the basic Plugin logic for determining the Record Id and Name from the Account via a Post Image, and using these fields to carry out the logic via calls to either CRM Methods or SharePoint Methods.  The highlighted lines in the code above then refer to the points where these calls are made, if we look at these in turn:

DoesCRMRecordHaveSharePointLocation(recordId)

Method to determine whether the CRM Record already has a related Share Point Document Location associating the record to an area in SharePoint. This is essentially simple query in CRM to return a true/false flag depending on whether a record is found.

internal bool DoesCRMRecordHaveSharePointLocation(Guid recordId)
{
    try
    {
        ColumnSet cs = new ColumnSet(new string[] { "sharepointdocumentlocationid", "name" } );

        ConditionExpression regardingCondition = new ConditionExpression("regardingobjectid", ConditionOperator.Equal, recordId);
        ConditionExpression stateCondition = new ConditionExpression("statecode", ConditionOperator.Equal, 1);

        FilterExpression f = new FilterExpression(LogicalOperator.And);
        f.Conditions.Add(regardingCondition);
        f.Conditions.Add(stateCondition);

        QueryExpression q = new QueryExpression("sharepointdocumentlocation");
        q.Criteria = f;
        q.ColumnSet = cs;

        EntityCollection crmLocations = _service.RetrieveMultiple(q);

        if (crmLocations.Entities.Count > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    catch (Exception ex)
    {
        throw new Exception("CrmMethods -> DoesAccountHaveSharePointLocation (" + ex.Message + ")");
    }
}

GetDefaultSPSite()

Method to retrieve the details of the Default SharePoint Site that is connected to CRM via the Document Management area of CRM – this provides the Plugin with the SharePoint URL and ‘root location’ to invoke for calling SharePoint, again however, this is a fairly simple query in CRM to retrieve the relevant record.

internal SPSite GetDefaultSPSite()
{
    try
    {
        ColumnSet cs = new ColumnSet(SPSite.ColumnSet);

        ConditionExpression c = new ConditionExpression("isdefault", ConditionOperator.Equal, true);

        FilterExpression f = new FilterExpression(LogicalOperator.And);
        f.Conditions.Add(c);

        QueryExpression q = new QueryExpression("sharepointsite");
        q.Criteria = f;
        q.ColumnSet = cs;

        EntityCollection crmSites = _service.RetrieveMultiple(q);

        if (crmSites.Entities.Count > 0)
        {
            return new SPSite(crmSites[0]);
        }
        else
        {
            // no SharePoint Sites defined in CRM
            throw new Exception("CRM does not have any default SharePoint Sites");
        }
    }
    catch (Exception ex)
    {
        throw new Exception("CrmMethods -> GetDefaultSPSite (" + ex.Message + ")");
    }
}

new SharePointMethods(connectedSite.AbsoluteUrl, “administrator”, “myPassword”, “MyDomain”)

This constructor methods creates the initial connection to SharePoint using the Absolute Url field from the [GetDefaultSPSite] method alongside valid security credentials. These credentials could be hard-wired in the code, or added to the SharePoint Site entity in CRM as custom fields.

internal SharePointMethods(string spSiteUrl, string spUsername, string spPassword, string spDomain)
{
    try
    {
        _siteUrl = spSiteUrl;
        _clientContext = new ClientContext(_siteUrl);

        _clientContext.Credentials = new System.Net.NetworkCredential
            (spUsername, spPassword, spDomain);
    }
    catch (Exception ex)
    {
        throw new Exception("SharePointMethods.Constructor --> [" + ex.Message + "]");
    }
}

CreateDocumentLibrary(recordName, “Document Library for CRM Record”)

This method is where the Plugin calls out to SharePoint using the Client Object Model to create a new Document Library.

public string CreateDocumentLibrary(string documentLibraryName, string documentLibraryDescription)
{
    try
    {
        Web web = _clientContext.Web;

        _clientContext.Load(web);
        _clientContext.ExecuteQuery();

        ListCreationInformation lci = new ListCreationInformation();
        lci.Title = documentLibraryName;
        lci.Description = documentLibraryDescription;
        lci.TemplateType = 101;

        List newDocumentLibrary = web.Lists.Add(lci);

        newDocumentLibrary.ContentTypesEnabled = true;
        newDocumentLibrary.Update();
        _clientContext.ExecuteQuery();

        return (_siteUrl + "/" + documentLibraryName);
    }
    catch (Exception ex)
    {
        throw new Exception("SharePointMethods.CreateDocumentLibrary('" + documentLibraryName + "') (General Exception: " + ex.Message + ")");
    }
}

AddRootSharePointLocation(connectedSite.Id, entityLogicalName, recordId, recordName, documentLibraryName)

This method adds a new Share Point Document Location record into CRM that associates the regarding object (in this case the Account record) to the new SharePoint Document Library via setting the Relative Url property the name of the new Document Library.

internal Guid AddRootSharePointLocation(
    Guid siteId,
    string regardingEntityType,
    Guid regardingRecordId,
    string regardingRecordName,
    string relativeUrl)
{
    try
    {
        Entity sharepointLocation = new Entity("sharepointdocumentlocation");

        sharepointLocation.Attributes.Add("name", "SharePoint Location for " + regardingRecordName + "");

        EntityReference lookupSharePointSite = new EntityReference(SPSite.EntityName, siteId);
        sharepointLocation.Attributes.Add("parentsiteorlocation", lookupSharePointSite);

        EntityReference lookupRegarding = new EntityReference(regardingEntityType, regardingRecordId);
        sharepointLocation.Attributes.Add("regardingobjectid", lookupRegarding);

        sharepointLocation.Attributes.Add("relativeurl", relativeUrl);

        return _service.Create(sharepointLocation);
    }
    catch (Exception ex)
    {
        throw new Exception("CrmMethods -> AddSharePointLocation (" + ex.Message + ")");
    }
}

This combination of the Plugin Business Logic, CRM Methods and SharePoint Methods then provides a basic Plugin for automatically integrating CRM and SharePoint each time a new Account (or other CRM entity) is created.

The full Visual Studio Solution and code listing can be found here.

Testing the Plugin

With the Plugin registered against CRM, we can then create a new Account in CRM and immediately have a new Document Library created in SharePoint (via the Client Object Model call) and linked into CRM without any further user action:

image

Creating the new Account in CRM 2011

Therefore upon saving the Account, we can browse to the Documents area to view the Documents and Folders in SharePoint via the newly created Document Location record:

image

Automatically created Document Location for the new Account

With this Document Location looking at a new Document Library in SharePoint as opposed to the standard folder inside a pre-existing Library:

image

Document Library within SharePoint 2010

This gives us a method of effectively controlling how we want our documents managed in SharePoint – in that we are no longer fixed into the default behaviour of creating a new Folder for each Account in a single Document Library, instead the custom Plugin has implemented a new system of creating a separate Document Library per Account.

However whilst this control of the Document Management structure is useful, this simply changes the way SharePoint behaves alongside CRM – our next step could be to bring more sophisticated SharePoint functionality into our Plugin as way of leveraging SharePoint’s strong Document Management features alongside CRM.

Namely Content Types.

CRM, SharePoint and Content Types

To provide a brief summary, Content Types are SharePoint’s method for allowing different kinds of Document to be stored with varying Metadata fields based on the Content Type involved.  In a way similar to CRM’s concept of different entities but with a heavier focus on inheritance.

So a Contract Document may have Metadata fields describing the Contract Type, Sent Date, Effective Dates and Compliance Contact; whereas a Proposal may have different fields for Proposal Type, Revision Number and so on – but both would have standard Document fields for Title, Last Modified and Last Modified By.

In SharePoint terms, this would be expressed as two Content Types for Contract and Proposal inheriting from the base Document Content Type.

Normally Document Libraries created in SharePoint have the Content Type functionality deactivated until explicitly activated in the Advanced Settings of the Document Library.

image

Therefore any Document Libraries created by the CRM 2011 SharePoint integration will not initially have this enabled – however with our Plugin now creating the Document Libraries via code, this can be changed to activate Content Types for each new Document Library created via the Plugin.

newDocumentLibrary.ContentTypesEnabled = true;
newDocumentLibrary.Update();
_clientContext.ExecuteQuery();

This would allow the Plugin to create new Document Libraries that are able to be attached to different Content Types. If we then create some Content Types in SharePoint, we can then extend this code to attach the Content Types we want to be accessible in this Document Library:

image

With this done we can alter the code that creates the Document Library to automatically make use of these Content Types for uploading documents:

newDocumentLibrary.ContentTypes.AddExistingContentType(someContentType);
newDocumentLibrary.Update();
_clientContext.ExecuteQuery();

To do this for the Contract Type and Proposal Content Types we have added, our code would have to loop through the Content Types defined in the SharePoint Site and, if found, add them to the Document Library in the same fashion:

_clientContext.Load(web.ContentTypes);
_clientContext.ExecuteQuery();

ContentType proposalContentType = null;
ContentType contractContentType = null;
for (int n = 0; n != web.ContentTypes.Count; n++)
{
    if (web.ContentTypes[n].Name == "Proposal")
    {
        proposalContentType = web.ContentTypes[n];
        _clientContext.Load(proposalContentType);
    }
    if (web.ContentTypes[n].Name == "Contract Type")
    {
        contractContentType = web.ContentTypes[n];
        _clientContext.Load(contractContentType);
    }
}

_clientContext.ExecuteQuery();

if (proposalContentType != null)
{
    newDocumentLibrary.ContentTypes.AddExistingContentType(proposalContentType);
}
if (contractContentType != null)
{
    newDocumentLibrary.ContentTypes.AddExistingContentType(contractContentType);
}

newDocumentLibrary.Update();
_clientContext.ExecuteQuery();

This would have the effect of associating each new Document Library with the predefined Content Types – presenting CRM Users with the option of a different set of metadata fields when adding or uploading a document in CRM:

image

Creating a new document of a different Content Type to SharePoint through CRM

The key here, as with many of SharePoint’s features, being the tight integration with Office to provide the user a seamless transition between CRM and managing the document:

image

Creating a new Document in Office directly from CRM with the SharePoint Metadata fields

With the normal SharePoint functionality for uploading existing documents as specific Content Types as well:

image

Entering the Metadata when uploading a document to SharePoint through CRM

image

Viewing the list of documents with different Content Types in CRM

This gives us a basic custom structure for how different types of documents may be stored using Document Libraries between CRM and SharePoint – essentially a new custom document management configuration for the CRM Solution through a fairly small amount of custom development.

Conclusion

This concept of using CRM Development to control the Document Management between CRM and Sharepoint allows us a great deal of flexability in how documents for a CRM Solution could be structured.

As we have seen here this allows a Solution Architect to consider other methods of goverance when storing documents provide the initial folder-per-entity structure that CRM provides by default. The inclusion of SharePoint Metadata then allows this to be taken one step forward towards SharePoint best practise for managing volumes of documents – essentially providing methods for taking unstructured document data and streamlining this into a structure that fits the business. (or in a more snappy way, working the way you do, and not you working the way the software does)

Moving beyond this, for the next article in this series I will aim to look into how the concept of SharePoint Metadata can be used alongside CRM for SharePoint Views and Templates to further extend a custom document management configuration, and begin to looking at how we could handle the migration of legacy data into CRM and SharePoint.

Source Code

Download from Public-facing Skydrive

Posted in CRM 2011, Development, MSCRM, SharePoint | Tagged , , , , | 36 Comments