Search This Blog

Monday, January 14, 2013

Viewing Lead notes in related Accounts, Opportunities and Contacts

Anyone who has implemented Microsoft Dynamics CRM sales functionality has sooner or later run into a desperate call from a client who says the notes they added when a prospect was in a "Lead" stage no longer appears now that the "Lead" has been converted to an "Opportunity".

As most CRM consultants know, only activity records (Phone Calls, Tasks, Appointments, Emails, etc) entered in the Lead stage will transfer when the Lead is converted to an Account, Contact and Opportunity.  The notes will not transfer.  Whether this was by design or a design flaw is something the CRM nerds can debate about.  For now, lets look at a solution.

The following is a solution I built that will allow users to be able to view notes entered in the originating Lead record in the resulting Account, Contact or Opportunity records.

Basically, I added a tab on the evolved entity forms that will show the "originating lead" notes.

Original Lead Note




Opportunity Showing Lead Note


Implementing the Solution

To put this solution together, you should be comfortable with CRM 2011 field and form editing, solutions, Iframes, web resources and JavaScript.  Having a bit of knowledge on OData and REST endpoints can't hurt.  The CRM SDK is good resource to get up to speed.

Form Customization

The first thing to do is create a place to view the Lead notes. 

On the Account, Opportunity and Contact Forms (you can put this on all 3 or just the entity where you want to see the lead notes) add a Tab called "Lead Notes" and on the tab place a section and an IFrame.



For the IFrame, enter in a name like IFRAME_LeadNote (you will need to remember this for later for the JavaScript code) and for now, put in "about:blank" for the URL.  We will programmatically change these when the tab is selected.



In my solution, by default I am keeping the Lead Notes tab collapsed and triggering the code when the tab is expanded.  Feel free to trigger on the onload event if you want to have immediate visibility. 



Repeat creating the Tab, Section and IFrame for the Account and Contact forms if you wish.

If you haven't (and why not?) download the CRM 2011 SDK

Add the following jscript web resources to your solution from 

\sdk\samplecode\js\restendpoint\javascriptrestdataoperations\scripts\

json2.js
sdk.rest.js

Eventually, your web resources should look something like this:


Many times there will not be any Lead notes to display or the Account, Contact or Opportunity records may not have evolved from a Lead.  We want to show friendly message that there are no lead notes.  I created a simple HTML web resource that gets displayed when there are no notes to show.

The display will look something like this:



Enter the following and save it as an HTML file, then load it into your solution as a HTML web resource.

<HTML><HEAD><TITLE>No Lead Notes to Display</TITLE></HEAD>
<BODY style="BACKGROUND-COLOR: #f6f8fa" contentEditable=true> 
<STYLE type=text/css>
        .style1
        {
            font-family: Arial, Helvetica, sans-serif;
            font-size: small;
        }
    </STYLE>

<P class=style1>No Lead Notes to Display</P></BODY></HTML>


We now need to enter a script that will do the following;

When the "Lead Notes" tab is selected:
  • Check to see if there is an originating lead.
  • Check to see if the originating lead has any notes.
  • If so, point our IFrame to the Lead's notes.


Here is the JavaScript.  I used the REST endpoint to see if notes exist for the lead.  For more info on how that works, refer to the CRM SDK:

function leadNotes()
{
    //This Function builds proper URL for Iframe (IFD/OnPremise)
    function prependOrgName(sUrl)
    {
        return (IS_PATHBASEDURLS && ORG_UNIQUE_NAME.length > 0) ? ("/" + ORG_UNIQUE_NAME + sUrl) : sUrl;
    }

    //Get some values from CRM Foom
    var Primary = Xrm.Page.data.entity.attributes.get("originatingleadid");
    var IFrame = Xrm.Page.ui.controls.get("IFRAME_LeadNote");
    var NoNotesMsg = Xrm.Page.context.getServerUrl() + "/WebResources/rxrm_noleadnotes";

    //Check if this record was created from a lead
    if (Primary.getValue() != null)
    {
        //Get GUID of lead record
        var GUIDvalue = Primary.getValue()[0].id;

        //Use SDK rest library to see if any notes exists for the related lead
        SDK.REST.retrieveMultipleRecords("Annotation","$select=AnnotationId&$filter=ObjectId/Id eq guid'" + GUIDvalue + "'",
        function (results)
        {
            var firstResult = results[0];
            if (firstResult != null)
            {
                //If notes exist for related lead, show them in custom IFrame
                IFrame.setSrc(prependOrgName("/_controls/notes/notesdata.aspx?id=") + GUIDvalue + " &ParentEntity=3&EnableInlineEdit=false&EnableInsert=false");
            }
            else
            {
                //If no notes, display a friendly message
                IFrame.setSrc(NoNotesMsg);
            }
        },
        errorHandler,
        function ()
        {
            //OnComplete handler
        }
        );
       
    }
    else
    {
        //If record did not come from a lead, display a friendly message
        IFrame.setSrc(NoNotesMsg);
    }

}

function errorHandler(error)
{
    alert(error.message);
}

Save and add the script to the web resources.

You now will need to add the JavaScript libraries to the corresponding Account, Contact and Opportunity forms.  (json2, SDK.rest and the new lead notes script)

To tie this all up, you now need to trigger the "leadNotes" function from "TabStateChange" when the Lead Notes tab is selected on the CRM form:


Repeat for each entity, publish and test!

Note that you will not be able to add notes to the Lead entity, just view them.
You will want to make sure that your users have at least read access to Leads in their security roles in order to view the notes.

Like all things, I assume no responsibility for any of the code or suggestions here. 

Cheers!
Nick



Friday, January 4, 2013

CRM 2011 IFD issue and Rollup 11

Happy New Year!

Over the Christmas break I though it would be a good time to rebuild/reconfigure our development environment.  This is something that I hope to blog about later.

One of the things that I needed to do was to setup CRM 2011 Internet Facing Deployment (IFD) to allow the team to have quick and easy access to the dev orgs without dealing with VPN and RDP issues and performance. 

Setting up CRM IFD is something that I have done a number of times and each time it seems that I learn (ie- have issues) something new.

CRM 2011 requires the use of Active Directory Federation Services (ADFS), SSL certificates and a LOT of patience. 

If anyone were to build a tool that you put in your basic parameters (CRM server name, IP addresses, etc) and have it generate appropriate batch files, powershell scripts and checklists to setup CRM 2011 IFD, there would be a lot of premium beer in it for you.

I have found that good step by step guide for setting up CRM 2011 IFD can be found here: http://www.interactivewebs.com/blog/index.php/server-tips/microsoft-crm-2011-how-to-configure-ifd-hosted-setup/

I have a few notes on my well worn printed out copy, notably that the "setspn" commands need to be run on the CRM server, and the "Transform Windows Account Name to Name" rule in ADFS you need to choose "*Name" (blog posts indicates just "Name") and a few extra IISResets along the way, still, without that blog article, I might still be pulling my hair out.

On my new dev enviroment, I installed CRM 2011, I used the slipstreamed install with Rollup 6 embedded.  I also applied Rollup 11 to keep things up to date (at time of this blog, Rollup 12 was not yet released).

After fighting my way throught this, I ended up getting an "Unexpected Error" when trying to connect to CRM either via the internal or external claims based endpoints.  I was still able to get in via http://servername:port locally.

Digging deeper, I found in the event log that I had unhandled exception error, digging deeper I saw the details "Exception message: Could not find GUID for server: XRM2011$ With SearchFilter:samAccountName"

Thanks to Google, I found this posting:
http://community.dynamics.com/product/crm/f/117/t/93178.aspx

Essentially, you need to do the following steps (cut and pasted from article):

Change the Anonymous user identity of IIS Anonymous Authentication Credentials to Application pool Identity option:

1. On the CRM server, open the Internet Information Services (IIS) Manager;

2. In IIS Manager, click the CRM site;

3. In the Features View, double-click Authentication;

4. Select Anonymous Authentication , and then click Edit in the Actions pane;

5. In the Edit Anonymous Authentication Credentials dialog box, click the Application pool Identity , and then click Ok;

6. Do an IISRESET on CRM and ADFS server.

My situation Resolved! 

Kudos to the contributors to the posting above.  Apparently there will be a hotfix and Rollup 12 will also address this.

Hope this helps!
Cheers
Nick