Knowledge found and lost while working with Microsoft Dynamics CRM
RSS icon Home icon
  • CRM 4.0 Hotfix Rollup 5 has been released

    Posted on July 2nd, 2009 mitch Print Print No comments

     

    Here is the KnowledgeBase article.

    Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    53 views
  • Free Utility Released: Export JavaScript from CRM

    Posted on June 30th, 2009 mitch Print Print 1 comment

    Part of an upcoming commercial utility I am building exports custom JavaScript found in a CRM installation.  I needed that functionality for a current customer project so I decided to go ahead and create a separate utility that performs that one function.

    Here is the user interface:

    image

     

    JavaScript Extraction Rules

    The JavaScript found within each entity will be extracted using the following rules:

    • Only custom JavaScript is extracted. Built-in CRM JavaScript is ignored.
    • JavaScript for the Form’s OnLoad and OnSave events will be exported.
    • JavaScript for each Atttribute’s OnChange event will be exported.
    • Only active JavaScript is exported. If you don’t have the Active checkbox on the event checked, it is ignored.
    • If the JavaScript is Active but there is no JavaScript in the event, it is ignored.

     

    Output Folder

    A sub-folder will be created using the name of the CRM Organization in the folder where the utility is located.

     

    Output Contents

    Each event will be written to a separate file with a .js extension. The naming convention is:

    OnLoad

    <entity>_onload.js

    OnChange

    <entity>_<attribute>_onchange.js

    Here is what the new Demo CRM VPC installation’s output looks like:

    image

     

    Download it from the Free Utilities page.

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    102 views
  • Free CRM utilities moved to this blog

    Posted on June 30th, 2009 mitch Print Print No comments

    I moved my free CRM utilities to this site today.  They mostly work with CRM 3.0 but I plan to update a couple of them soon to support 4.0.

    Check out the following page:

    Free Utilities

    Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    80 views
  • Do you use CardScan for CRM?

    Posted on June 30th, 2009 mitch Print Print 2 comments

    I have added a new poll to this blog because I’m curious about how many people actually use the CardScan for MSCRM product.

    Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    90 views
  • The Dangers of Repurposing Existing CRM Entities

    Posted on June 11th, 2009 mitch Print Print No comments

    Since Dynamics CRM can be so easily customized, one of the traps that CRM developers and architects occasionally find themselves in is using an existing CRM entity for a different purpose.

    An example would be using the Case Entity (incident) to track product fulfillment requests.

    Usually, when such a decision is made, the entity being repurposed is not being used and as far as the designers can see, it will never be used.  So, they customize it to fit their needs and, in some cases, completely altering the visual and structural layout of the entity to where you can’t actually determine how it looked and worked before.

    Then, as is more the case than not, 6 to 12 months into the future, when Dynamics CRM is running your business, you find yet another need that can be filled by using parts of the system that were previously unused.

    The only problem is, you’ve repurposed that part ( the Case Entity, for example ) and it is so customized and heavily used that it would be almost impossible to move the customizations and data to a new entity and revert the original Entity back to it’s original design and purpose.

    Repurpose or Create

    If you are starting down the repurposing path, you need to ask yourself why you are doing so.  What is is about the Entity that makes you think:

    1. You will never use it
    2. It has some design feature that can’t be duplicated in a custom entity

    There are indeed occasions where a standard CRM Entity has a feature that you can’t duplicate on a custom Entity – like the Customer data type ( can be Account OR contact ).  But most of the time, you’ll spend as much time removing or hiding the existing functionality as you would have in creating a new Entity from scratch. 

    Sometimes even more time is spent customizing the standard Entity and it would be to just create the whole thing from scratch.

    Conclusion

    When your requirements call for a new custom Entity, start from scratch, don’t automatically look for an existing Entity that is not used and change it.  Microsoft spent a lot of time and effort into the design of Dynamics CRM and the relationships between the Entities is pretty well defined and understood.

    Have your design add value to CRM, not change CRM in ways that will cause issues later.

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    167 views
  • JavaScript: Working with Dates Returned from Web Service Calls

    Posted on June 10th, 2009 mitch Print Print 2 comments

    Revised Thursday, July 11th.

    I’ve been doing a lot of work recently using JavaScript to retrieve data from CRM via web service calls.  One of the issues I ran into is the date format returned by CRM is in Coordinated Universal Time ( UTC ) which is not the same format most programming languages use.  This leads to conversion issues or programming exceptions.

    To work around any issues, I created a JavaScript function that allows me to parse the UTC date and time string and return a JavaScript Date value.

    At this point, the function is only concerned with the date, but if you need the time, you can modify the function to add those additional parameters to the new Date() line.

    For more information on the JavaScript Date object, please visit the following link.

    function ConvertDateFromUTC(startDate){
    // UTC time formatted string
    //2009-03-25T09:30:00-00:00 // 1 2 //1234567890123456789012345 
     
    var year = parseInt(startDate.substr(0, 4),10);
    var month = parseInt(startDate.substr(5, 2),10);
    var day = parseInt(startDate.substr(8, 2),10);
    var hour = parseInt(startDate.substr(11, 2),10);
    var min = parseInt(startDate.substr(14, 2),10); 
     
    return new Date(year, month - 1, day);
    }

    July 11th: Corrected issues as pointed out by Moti, in the comments.

     

    Making It Work

    In this example, I’m using the excellent CrmService library released by Ascentium, to retrieve values from a contact.

    var oService = new Ascentium_CrmService();
     
    var asCols = ["fullname", 
                  "address1_postalcode", 
                  "address1_city", 
                  "address1_stateorprovince", 
                  "birthdate"];
     
    var beRetrievedContact = 
           oService.Retrieve("contact", 
           crmForm.all.customerid.DataValue[0].id, 
           asCols);
     
    var birthDateString = beRetrievedContact.attributes["birthdate"].value;
     
    var birthDate = new Date(ConvertDateFromUTC(birthDateString));

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    226 views
  • What keeps your people from selling?

    Posted on June 10th, 2009 mitch Print Print No comments

    This is one of the primary questions I ask when starting the discovery phase of a CRM implementation.

     

    Why is this important?

    This question is important to everyone because the more distractions that can be eliminated from the life of a sales person, the more time they have to sell.  Hopefully, the following equation fits into your organization:

    image

    And more sales generally translates into more money – for everyone.

     

    How do I make a difference?

    During your discovery process, ask these simple questions:

    1. What types of reports are your sales people required to produce?
    2. Is any data collected and returned to anyone in an Excel worksheet?
    3. What procedures or processes do your salespeople perform repetitively?

    Collect these answers, then review the native capabilities found with Dynamics CRM.  Implement out of the box solutions when you can and create custom solutions when you must.

    Your changes don’t need to occur all at once, and as always, keep the users involved in the process so they can see where you’re going and how the changes will help them sell.

    Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    133 views
  • Retrieving State and Status Options via the MetadataService

    Posted on June 9th, 2009 mitch Print Print No comments

    As you probably know, the State and Status options for a CRM entity are linked together.  You can’t change the State options or values but you can change the Status options ( which are generally shown in a picklist ).

    On a recent project, I needed to simulate the Cancel Opportunity dialog through a custom user interface.  Rather than build a hard-coded list of reasons for the cancelation, I decided to use the CRM MetadataService to dynamically pull the data using the following method ( in C# ):

    public SortedList RetrieveStatusList(
                          string entityName,
                          int statusValue)
    {
        SortedList list = new SortedList();
    
        AttributeMetadata attMetaData;
        RetrieveAttributeRequest request =
            new RetrieveAttributeRequest();
        request.EntityLogicalName = entityName;
        request.LogicalName = "statuscode";
        RetrieveAttributeResponse response;
    
        response =
            (RetrieveAttributeResponse)metadataService.Execute(request);
        attMetaData = response.AttributeMetadata;
    
        StatusAttributeMetadata status =
            (StatusAttributeMetadata)attMetaData;
    
        foreach (StatusOption o in status.Options)
        {
            if (o.State.Value == statusValue)
            {
                list.Add(o.Label.UserLocLabel.Label,
                         o.Value.Value.ToString());
            }
        }
    
        return list;
    }

    The method takes two parameters:

    1. The entity name
    2. The state code value

    I am using this method to populate a ASP.NET dropdown list box using the following code:

    DropDownList1.DataSource = RetrieveStatusList("opportunity", 2);
    DropDownList1.DataTextField = "Key";
    DropDownList1.DataValueField = "Value";
    DropDownList1.DataBind();

    In the case of the Opportunity, we have the following State code values:

    Name Value
    Lost 2
    Open 0
    Won 1

     

    Since we are canceling an Opportunity, we use the Lost state, which has a value of 2.

     

    How This Works

    The key to making sense of this process is the StatusOption object.  It contains data for both the Status Reason codes and the State with which are they associated.

    Since we are looking for a specific state, we check the State for the Option and if it matches our expected value, we add it to the list.

    Customization, Development, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    131 views
  • Using the Form OnSave Event

    Posted on May 11th, 2009 mitch Print Print No comments

    While working on a customer project recently, we added logic to prevent the user from saving should certain form conditions exist.  During testing, we found that Save events were coming from a variety of unexpected places.

    Take for instance the Opportunity Entity.  There are several related entities connected to Opportunity:

    image

    Clicking on the Orders link on the Opportunity allows you to  review or created new associated Orders.

    When you click the New Order button on the Orders pane, one of the first actions it will perform is to save the parent Opportunity with an internal call that looks something like this:

    crmForm.SubmitCrmForm(21, true, true, false);

     

    How This Causes Problems

    This system-originated save caused a problem in our solution because we had actually removed the Save and Save and Close buttons until our approval processes had been completed.  This “save from nowhere” broke our validation processes.

     

    Making Your Save Process Solid

    If you review the OnSave event documentation on MSDN ( or or the SDK help file ), you’ll see that you can actually determine from where the save originated.

    The property event.Mode will contain the origination point for the save activity.  In our case, we only wanted the OnSave event to fire if the event.Mode was 1 ( Save ), or 2 ( Save and Close ).  The code looks like this:

    if (event.Mode == 1 || event.Mode == 2)
    {
    }

     

    Finally, if it turns out that you need to watch for a specific save event, the first parameter of the crmForm.SubmitCrmForm will contain value that will be used to set the event.Mode.

     

    Stopping the Save

    As you will see in the SDK documentation, you can actually stop the save from occurring, using the following code:

    event.returnValue = false;

    This is useful should you need to inspect the form state and only allow the process to complete if all checks pass.

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    273 views
  • CRM 4.0 Hotfix Rollup 4 Released

    Posted on May 7th, 2009 mitch Print Print No comments

    Update 4 has been released:

    Update Rollup 4 for Microsoft Dynamics CRM 4.0 (KB 968176)

    Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    199 views