You are currently browsing the tag archive for the ‘Dynamics CRM 2011’ tag.

Other than using Bing, you can easily integrate other geo-location sources. One of the most enterprise level solution is of course Esri Maps. They have a very good solution for mapping. They can also be pricy, so if you are looking for a solution on the cheap, and are not afraid of doing very little coding, read on.

Google Maps provides a very robust mapping API. You can find more details HERE.

To integrate this into your existing CRM, you will use an iFrame, and a custom HTML web resource. Your HTML will include a div tag with an id of “geolocation”. You can use another id, we’re using “geolocation” in the context of this example. Basically, your div will look like so:

<div id="geolocation" style="width: 800px; height: 500px;"></div>

Define the style width and height as needed to render properly within the iFrame at a standard screen resolution set at the enterprise level.

Pass the context to the iFrame, so you can retrieve the address fields. You will use these to build the address string you pass to retrieve the longitude and latitude.

With the new v.3 of the maps API, you do not need a API Key anymore, which makes it a lot easier to move your solution between various environments, and to have the solution internal only (no IFD).

When calling the API, if your CRM is set to use HTTPS, use the HTTPS Google API URL, otherwise use the HTTP address.

Add in the header of your HTML web resource the reference to the JS library:

<script src="http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>

In this example I am using HTTP.

In your HTML web resource, first function you want to call on page load is a function that takes the value of the address fields, and concatenates it all into a string. It will be along the lines of:

var _address = street + city + province + country + postalCode;

check and use only the fields where you have a value populated.

Once you have this address as a string, pass it to the first function that converts the address into latitude and longitude. This will look as follows:

ParseAddress: function(address) {
    var url = "
http://maps.googleapis.com/maps/api/geocode/json?" +
    "address=" + address +
    "&sensor=false"

    var xhr = base.createCORSRequest(‘GET’, url);
    if (!xhr) {
        alert(‘CORS not supported’);
        return;
    }

    // Response handlers.
    xhr.onload = function () {
        var text = xhr.responseText;
        var _start = text.indexOf("\"location\" :") + 12;
        var _location = text.substring(_start, text.indexOf("}", _start) + 1);

        geoCode.Initialize(_location);
    };

    xhr.onerror = function () {
        $("#message-area").append("Woops, there was an error retrieving server data.");
    };

    xhr.send();
},

This example is using CORS. CORS stands for “Cross-Origin Resource Sharing”, and for more details on CORS see the W3C documentation HERE.

This function makes a call to the Google API and on successful retrieval of data, calls another function called Initialize, passing the trimmed returned string that includes the location lat and lng.

The Initialize function takes this location, builds the map representation, sets the zoom on it, and drops a pin at the location provided by the coordinates:

Initialize: function (_location) {

    var jsonData = $.parseJSON(_location);
    var _bGeoLocation = new Array();
    _bGeoLocation = jsonData;
 

    var myOptions = {
        zoom: 16,
        center: new google.maps.LatLng(_bGeoLocation .lat, _bGeoLocation .lng),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    // Draw the map
    var mapObject = new google.maps.Map(document.getElementById(“geolocation”), myOptions);
    // Place the marker
    new google.maps.Marker({ map: mapObject, position: userLatLng });

}

Et voila, now you have a map with a pin on it pointing to the record’s address.

image

Enjoy!

Today my book has been released. As I mentioned in an earlier post, it has been available for pre-orders for a short while, and now it’s out.

The book is available from the publisher’s website at:

http://www.packtpub.com/microsoft-dynamics-crm-2011-scripting-cookbook/book

8826EN

A big thank you goes to PAKT for great guidance on the publishing process, to the editors involved in the process, the technical reviewers and to Mark for the initial kick in the butt that got me started on this project.

Enjoy!

So, one of these days I had a pretty interesting case. Just to give you an overview, on-premise environment, custom security roles, activity feeds installed.

The issues was as follows:

Navigating to any of the main entities, going on the Ribbon and adding a file that way worked just fine.

Creating a note, then opening it and trying to add an attachment resulted in the following error:

image

Pretty interesting, so I go first to Notes, and the group permissions are as follows:

image

Ok then, so the problem is not there. Just for kicks, I checked also the Append and Append To on the hosting entities (Case, Account, Contact). All looking good.

Last resort, let’s have a look at the logs then. Just to make your life easier, since tracing is not enabled by default on the server, there is nice free tool that allows you with a click of a button to enable/disable tracing, among other things. It is called Diagnostics Tool for Microsoft Dynamics CRM 2011 and can be found on Codeplex at

http://crmdiagtool2011.codeplex.com/

Once you’ve got a hold of the trace file, start looking for errors. It appears that this particular issue resulted in a message of: “Principal user … is missing prvReadmsdyn_PostAlbum privilege” message.

This is related to the Activity Feeds. Basically, what is requires is this: in the security role your user is in, go to the Custom Entities tab, and look for Profile Album entity. Make sure that Read is set to at least User.

image

Now try adding a file again to an existing note. Everything works as expected.

Enjoy!

So we all know about the standard options for hosting Dynamics CRM 2011: Cloud and On-Premise. Some of us might have also heard of 3rd party hosting, based on the cloud model. But there are also other alternatives.

On-Premise Partner Hosted

Otherwise known as colocation, in this model the environment is hosted by a 3rd party hosting provider. On the partner’s end, it will look very much like an On-Premise deployment, most likely a multi-tenant one. Possible models are determine by individual SLA’s. We could have some choice over items like uptime (choosing one of the available options offered), authentication model used, as well as integrations options. Do not assume that a 3rd party hosting company will not be willing to go over and beyond to offer something you can’t get with the standard Cloud offering from Microsoft. Some of the providers actually offer additional services to differentiate themselves. This could include include anything from integration alternatives, additional customization packages, as well as public portal templates.

One of the more complex scenarios, including redundancy and allowing both internal and external access to the environment (including mobile access) can be described by the following diagram. Note that the SharePoint environment can be located in either the hosting partner’s environment or on site.

OnPremPartnerHostedRedundant

A less complex model, non-redundant system, is depicted by the next diagram. Just as before, the SharePoint environment can be located either On-Premise or with the 3rd party hosting provider.

OnPremPartnerHostedNonRedundant

Alternatively, if only internal access is required, the environment can look as follows

OnPremPartnerHostedRedundantInternal

or

OnPremPartnerHostedNonRedundantInternal

Hybrid Hosted Model

Alternatively, with less separation, we can look at a hybrid hosting model. In such scenario, part of the environment is hosted by a 3rd party hosting provider, while still integrating and allowing certain components to function from within the internal network.

While this approach could be more cost-efficient, a good relation with the hosting provider is essential in such scenario. The following diagram depicts a possible scenario with redundancy

HybridRedundantInternetAccess

or with no redundancy

HybridNonRedundantInternetAccess

Any of these models can also be configured with no external access. One simple scenario can be depicted as

HybridNoInternetAccess

I hope this helps some of you looking for alternatives.

Enjoy!

One basic requirement received not too long ago prompted me to think about how to make this look pretty. I needed to show states/provinces by penetration in a nicely formatted dashboard.

The prep. work includes the creation of 3 map images for each state/province, using a set of defined colors, let’s name them Red/Yellow/Green. The percentages are irrelevant, you can set them up as required.

The work around the images is pretty important, as we will need to save them with transparency, and properly aligned so they overlap nicely.

Additionally, we will create a html resource, which is the actual page that we load the images onto.

Scripting is also pretty simplistic. First off, we have a process behind that calculates the state/province rating based on a formula. We will only define a custom field on the Account form that will hold the resulting value, as one of the three colors (options).

As part of the setup, and in this case it worked based on the business model, we have one Account for each state/province, with multiple child accounts.

Next, all we have to do on load, is define based on the rating value, which one of the three images we will load. Thus, the script could look something like this:

if(_rating == "Red") {
    _html += "<img src=’prov_red.gif’ />";
}
else if (_rating == "Yellow") {
    _html += "<img src=’prov_red.gif’ />";
}
else if (_rating == "Green") {
    _html += "<img src=’prov_red.gif’ />";
}

Additionally, to make it more dynamic, on the image we can define hot spots (yeah, do you remember the old days of static html?) over each state province. Here’s a link to remind you how that’s done:

image-map

Each URL of the hot spot areas defined will point to one Account on the system. We can either do this static, or dynamic by looking up the account by name or abbreviation (e.g. AB, IL, FL, etc.) I prefer abbreviation, as it is less typing.

The end result could look something like the following image:

image

Additionally, since we already have the resources in place, we can also enhance each account with a small image of the state/province, colored according to the penetration rating.

image

The possibilities are endless.

Enjoy!

MVP Reconnect

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 617 other followers

Follow Dynamics 365 Wizardry on WordPress.com