Friday 22 October 2010

Microsoft Dynamics CRM 2011 & Bing Maps Integration

















Following on from a previous post, here is the code to plot Microsoft Dynamics CRM 2011 records using Bing Maps:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
&nbsp;
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>REST JQuery Map</title>       
    <meta http-equiv="X-UA-Compatible" content="IE=8" />
    <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>
    <script src="../ClientGlobalContext.js.aspx"></script>
    <script src="Scripts/jquery1.4.1.min.js" type="text/javascript"></script> 
    <script src="Scripts/RESTJQueryMap.js" type="text/javascript"></script>
</head>
<body style="border-width:0px;padding-left:0px;padding-top:0px;margin-left:0px;margin-top:0px;margin-bottom:0px;margin-right:0px">
    <div id="map" style="position:relative; width:650px; height:450px;"></div>
    <script language="javascript" type="text/javascript">
    // <![CDATA[


    //Create a new Bing Map
    var map = null;
    var results = null;
    map = new VEMap('map');
    map.SetCredentials("***KEY***");


    //Search CRM records
    function Search() {
        //Search London
        retrieveMultiple("AccountSet", "?$filter=substringof('London',Address1_City)", SearchCompleted, null);
    }


    //Callback - Search Success
    function SearchCompleted(data, textStatus, XmlHttpRequest) {
        //Display Map
        map.LoadMap();
        //map.LoadMap(new VELatLong(50.6, -0.3, 0, VEAltitudeMode.RelativeToGround), 10, VEMapStyle.Road, false, VEMapMode.Mode2D, true, 1);


        //Plot CRM Accounts on the map
        if (data && data.length > 0) {


            for (var i = 0; i < data.length; i++) {
                
                //Get Location of CRM Record and plot on map
                var geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations/" + data[i].Address1_PostalCode + "?output=json&jsonp=GeocodeCallback&key=***KEY***";
                CallRestService(geocodeRequest);
            }
        }


        map.SetCenterAndZoom(new VELatLong(51.51, -0.11), 13);


    }


    function GeocodeCallback(result) {
        //alert("Found location: " + result.resourceSets[0].resources[0].name);


        if (result && result.resourceSets && result.resourceSets.length > 0 && result.resourceSets[0].resources && result.resourceSets[0].resources.length > 0) {            
            // Add a pushpin at the found location
            var latlong = new VELatLong(result.resourceSets[0].resources[0].point.coordinates[0], result.resourceSets[0].resources[0].point.coordinates[1]);
            var pushpin = new VEShape(VEShapeType.Pushpin, latlong);
            map.AddShape(pushpin);


        }
    }


    function CallRestService(request) {
        var script = document.createElement("script");
        script.setAttribute("type", "text/javascript");
        script.setAttribute("src", request);
        document.body.appendChild(script);
    }


    window.onload = Search;
    // ]]>
</script>
</body> 
</html>

This sample also uses the Bing Maps REST Locations API to return longitude and latitude data for a given address!

You will need to replace ***KEY*** with your own Bing Maps API key. You can create a new developer account the following URL:
http://www.bingmapsportal.com/

Thursday 21 October 2010

Microsoft Dynamics CRM 2011 Map Integration

This blog post will explore how you can create an interactive map displaying a list of CRM Accounts for a user provided City:






















From the Microsoft Dynamics CRM 2011 Beta SDK:

What is REST?
REST stands for Representational State Transfer. REST is an architectural style in which every resource is addressed using a unique URI. In Microsoft Dynamics CRM a resource may be an entity collection or a record.  REST works the way the Internet works. You interact with resources using standard HTTP verbs such as GET, POST, MERGE, and DELETE. Various libraries can be used to process the HTTP requests and responses. REST provides a standard interface that you can use with any programming language. REST allows for either synchronous or asynchronous processing of operations. The capability to perform asynchronous operations makes REST well suited for Ajax and Silverlight clients.

By using REST and JQuery we can query the Microsoft Dynamics CRM data and return a collection of records. This example is based on sample code that can be found within the CRM 2011 beta SDK:
sdk\samplecode\cs\generalprogramming\dataservices\restjquerycontacteditor


Step 1 - Get a Map API Developer Account
For this example I am using Yahoo! Map Web Service, but you can use whatever service you prefer (Google, Bing etc)

Step 2 - HTML Page
You will need to build a web page that displays a map using the Web Service account created in Step 1.

Yahoo! Maps provide several API examples that you can use to get started. The following is my HTML page which provides a text box to enable users to search for Accounts (or any record type) by City:

JQueryMap.htm


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head>     
    <title>REST JQuery Map</title>     
        
    <meta http-equiv="X-UA-Compatible" content="IE=8" />     


    <script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&appid=***YOURAPPID***">
    </script>  
    <script src="../ClientGlobalContext.js.aspx"></script>
    <script src="Scripts/jquery1.4.1.min.js" type="text/javascript"></script> 
    <script src="Scripts/RESTJQueryMap.js" type="text/javascript"></script>
    <script language="javascript" type="text/javascript">


// <![CDATA[


    //Search Button Event Handler
    function SearchButton_onclick() {


        //Search where City contains data
        if (SearchText.value) {
            retrieveMultiple("AccountSet", "?$filter=substringof('" + SearchText.value + "',Address1_City)", SearchCompleted, null);
        }
        //Retrieve all Accounts
        else {
            retrieveMultiple("AccountSet", null, SearchCompleted, null);
        }
    }


    //Callback - Search Success
    function SearchCompleted(data, textStatus, XmlHttpRequest) {


        //Create a new Yahoo! Map
        var map = new YMap(document.getElementById('map'));
        map.addTypeControl();
        map.addZoomLong();
        map.addPanControl();
        map.drawZoomAndCenter(SearchText.value + ", United Kingdom", 11);


        //Plot CRM Accounts on the map
        if (data && data.length > 0) {


            for (var i=0; i<data.length; i++) {
                //Get CRM data and add a marker to represent the Account    
                var marker = createMarker(data[i].Address1_PostalCode, i, data[i].Name, data[i].AccountId);
                map.addOverlay(marker);
            }
        }
        else {
            alert('No records!');
        }
    }
    
    //Helper URL: developer.yahoo.com/maps/ajax/#ex4
    function createMarker(geopoint, num, name, id) {
        var myImage = new YImage();
        myImage.src = 'https://***YOURORG***.crm4.dynamics.com//WebResources/epuk_accountIcon';
        myImage.size = new YSize(16, 16);
        myImage.offsetSmartWindow = new YCoordPoint(0, 0);
        var marker = new YMarker(geopoint, myImage);
        var swtext = "<a target=\"_blank\" href=\"" + serverUrl + "/main.aspx?etc=1&id=%7b" + id + "%7d&pagetype=entityrecord\">View</a>" + name + "</A>"
        YEvent.Capture(marker, EventsList.MouseClick, function () { marker.openSmartWindow(swtext) });
        return marker;
    }
// ]]>
</script>
<style type="text/css">
#map {
height: 100%;
width: 100%;
}
</style>
</head>

<body style="background:lightblue;">
    <h3 style="font-family:Arial;">Search for Accounts by City</h3>
    <div>
        <label style="font-family:Arial;">City: </label>
        <input type="text" style="width:200px;" id="SearchText" />
        <input type="button" id="SearchButton" value="Search" style="width:80px;"   onclick="return SearchButton_onclick()" />
    </div>
    <div>
    <table style="width: 100%; height: 100%;">
<tr>
<td>
<div id="map"></div>
</td>
</tr>
    </table>
    </div>         
</body> 
</html>

You must remember to replace ***YOURAPPID*** and ***YOURORG*** with appropriate values for your Developer Account and Microsoft Dynamics CRM 2011 organisation.

Step 3 - JScript Files
The HTML page above refers to several JScript files, including:

ClientGlobalContext.js.aspx - The GetGlobalContext function exists in ClientGlobalContext.js.aspx. This function provides the Server URL.

JQuery1.4.1.min.js - A popular JScript library that includes capabilities to perform asynchronous data operations using the $.ajax object. jQuery1.4.1.js comes standard in a Visual Studio 2010 Web Application.

RESTJQueryMap.js - A generic library that can perform CRUD operations using jquery1.4.1.min.js. (This can be found within the sample code highlighted at the top of this post)


Step 4 - Web Resources
You need to create web resources for all the bold files list above, within Microsoft Dynamics CRM 2011:

Be sure to “Save” and “Publish” all Web Resources. Use the Text Editor when creating JScript files, to avoid any syntax errors, when they run.

Name the Web Resources as follows:
1)    /RESTJQueryMap.htm (Web Page) – Refers to the html file above and is the web resource used for running the sample.
2)    /Scripts/jquery1.4.1.min.js (Script) – Refers to the minimized jQuery library.
3)    /Scripts/RESTJQueryMap.js (Script) – Refers to the custom ODataJQuery library.

You should also create a web resource for the CRM record type you would like to plot on the map. In this example I will upload the CRM Account icon and create the following web resource:
AccountIcon.gif (GIF)

Step 5 - Test Solution
Open the HTML web resource and click the Preview button to test:


















Step 6 - Add to Dashboard
Add the Web Resource to a new Microsoft Dynamics CRM 2011 Dashboard:


Thursday 23 September 2010

XRM

When I created a new online instance of Microsoft Dynamics CRM 2011, the first 3 characters of the CAPTCHA test were XRM!

Friday 17 September 2010

Microsoft Specialist Sales Accreditation - CRM

I have finally passed the Microsoft Specialist Sales Accreditation - Customer Relationship Management exam!


I thought I'd take a break from the Standard Sales exam for ERP and managed to get 83%!



Thursday 9 September 2010

Microsoft Dynamics CRM 5 Password Change Part 2

Having installed the latest CTP-4 bits for Microsoft Dynamics CRM 2011, I ran into another problem when Windows Server 2008 forced a password change.

"Can not log on locally to C:\Program Files\Microsoft Dynamics CRM\CRMWeb as user administrator with virtual directory password"

Make the following changes to resolve this problem:
  • Launch IIS Manager
  • Select the "Microsoft Dynamics CRM" and click "Basic Settings..." from the Actions pane
  • Click "Connect as..."
  • Click "Set..."
  • Enter updated credentials
















You might also need to change the credentials for the SQL Server 2008 services if you get the following error:

"A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)"

Make the following changes to resolve this problem:
  • Launch Services
  • Double click "SQL Server ()" service
  • Click Logon tab
  • Enter updated credentials
  • Repeat for all other SQL Server services

Wednesday 11 August 2010

Microsoft Dynamics CRM 2011 Installation


Firstly, start with a clean Windows Server 2008 R2 build or remove the existing Microsoft Dynamics CRM installation.

I had to perform the following additional tasks to get past several environment verification checks:

  • Repair the Microsoft .NET Framework 4 (Net.TCP Port Sharing Service errors)
  • Delete existing Microsoft Dynamics CRM Databases
  • Use Network Service security account for Microsoft Dynamics CRM services (optional)
  • Don't specify Email Router settings

Friday 23 July 2010

Microsoft Standard Sales Accreditation - CRM

I have finally passed the Microsoft Standard Sales Accreditation - Customer Relationship Management exam!

The exam tests these key business disciplines:

  • ability to manage sales cycle profitability
  • ability to employ solution selling techniques & apply business processes in the sales cycle
  • identify and sell the value of Microsoft Dynamics CRM
  • ability to articulate competitive value of Microsoft Dynamics CRM & licensing

I highly recommend the Microsoft preparation material and be sure to brush up on your Microsoft Solution Selling Process (MSSP) and Sure Step skills.

Wednesday 14 July 2010

Microsoft Dynamics CRM 5 Password Change

I recently changed the Administrator password on my Microsoft Dynamics CRM 5 CTP virtual machine.

When I tried to open CRM I received an "HTTP Error 503 - Service unavailable" error.

The following steps fixed the problem:

1) Update password on relevant Windows Service Accounts
















You need to sort by the "Log On As" column to ensure that all relevant credentials are changed. In my case I needed to update all the Microsoft Dynamics CRM and SQL Server 2008 services with the new password details.

2) Open IIS and update password on CRMAppPool
































































3) Restart Microsoft Dynamics CRM Asynchronous Processing Service

If you get the following error, you need to restart this service: