Developing Dynamics CRM Plugins? I could use some feedback

Hey Everyone,

I’m finishing up my Deep Dive Plugins book and I am curious about the types of examples you feel would help you learn how to develop plugins.

If you have a couple of minutes, please let me know.

Hear a few I already have:

  • Qualify a Lead
  • Create a Marketing List
  • Create a list of associated records
  • Perform a zip-code lookup
  • Update a parent record when the child record changes

The link to the survey is here.

Thanks, Mitch

Bad Design: A tale of De-Architecture and De-Engineering

Every one of us has been guilty, or will be guilty, of creating a bad solution to a problem at some point in our career. If you have not done so yet, just be prepared, your day will come. Smile

Most of the time, people do not start off trying to create a bad solution, it just ends up like that. The cause can be just about anything, but here are a few:

  • Bad information (from research or the customer)
  • Change in design of Dynamics CRM (i.e., they changed something and didn’t tell you)
  • Assumptions
  • Over-thinking a problem
  • Under-thinking a problem
  • Unfamiliarity with the product, its features, and functionality points

Background

Back in 2011 I inherited a customer from another consultant who was too busy to handle the upgrade from CRM 4.0 to 2011. The system had been fairly customized and had a variety of plugins and a fair amount of JavaScript.

One of the things that had been done was to modify the calculations of the Quote/Order/Invoice system in order to incorporate a customer-requested design change.

When I saw the code, and there was a lot of it (plugins and JavaScript), I question the consultant on why it had been done this way. His reply was, “they had very specific requirements about how everything was calculated.”  Looking at the code, I could honestly not see what would have caused anyone to rewrite the calculation engine, but that is what had been done.

The main part of the customization was that custom total fields were added and the calculated values were stored in those fields while also updating the original total fields with the custom calculations.

The one thing that was different and extremely important was a custom field that allowed the user to enter a specific price per unit that would take the place of any system-calculated price.

So I upgraded everything, cleaned up the code a bit, and everything continued to work as designed/requested.

Then we upgraded to CRM 2015, and things started to NOT work as design.  Specifically with the Opportunity Product.  You would change a value and see before your eyes, the numbers change.

After spending about 3 hours one night tracing the actions of the system, I found this flow:

  1. User changes the quantity on the form
  2. Our custom JavaScript fires
  3. Internal CRM JavaScript fires which performed a calculation and saved the record
  4. Our custom Plugins fire
  5. [Possibly] Internal CRM plugins fire

The net result of this was that Dynamics CRM was overwriting our newly calculated values with their own, which was driving the users crazy.

Dynamics CRM Internals Notes

If you did not know, the Quote, Order, and Invoice entities are exactly the same, just in different buckets. Also, the Opportunity Product, Quote Product, Order Product, and Invoice Product entities also share the same structure.

These entities are really hard to customize because there is a fair bit of magic that happens behind the scenes through either JavaScript or Plugins, or both.

Also, even though these entities are similar in layout and design, it would appear that do not all function exactly  the same.

Also, everything is version-specific.  With CRM 2015, only the Opportunity Product uses the new form design. Quote/Order/Invoice Products still use the Information form.

Also remember that starting with Dynamics CRM 2013, the QOI and Opportunity forms were all redesigned to use the new layout which includes an editable grid for the Product line items. Since you can create records from the grid, and even change some fields, keep in mind that any JavaScript on the Product detail form will never be executed.

Any work that must be done on the create of one of these records must be accomplished using a plugin.

The Problem

The main problem was the internal Dynamics CRM code was overwriting the results of our custom code – somewhere – and after reviewing the facts, I realized there was just no way I could circumvent the actions of the product.

Correcting the Problem

The solution to this problem was actually rather simple and I still wonder why this wasn’t tried before.

It turns out that there is a Manual Discount field which is actually used by the automatic calculation engine.  After spending about 30 minutes with the customer, we were able to successfully test the use of the Manual Discount field as the basis for our custom per unit price.

I used that field to reduce the price per unit so that the calculation appeared to be using the manually entered price per unit, even though it was not. The code looks like this:

Code Snippet
  1. function newDiscountCalculation() {
  2.     if (Xrm.Page.getAttribute("new_netpriceperunit").getValue() == null) {
  3.         Xrm.Page.getAttribute("manualdiscountamount").setValue(0.00);
  4.         return;
  5.     }
  6.     var priceDifference = Xrm.Page.getAttribute("priceperunit").getValue() –
  7.                           Xrm.Page.getAttribute("new_netpriceperunit").getValue();
  8.     if (priceDifference === 0) {
  9.         return;
  10.     }
  11.     var manualDiscount = (priceDifference –
  12.                           Xrm.Page.getAttribute("volumediscountamount").getValue()) *
  13.                           Xrm.Page.getAttribute("quantity").getValue();
  14.     Xrm.Page.getAttribute("manualdiscountamount").setValue(manualDiscount);
  15. }

 

So that took care of the data issue, the remainder of the problem was corrected by removing ALL of the custom JavaScript and Plugins that also performed the calculations.

The only issue that remained was we had years worth of data in the wrong fields and many of the additional functionality points: Templates, reports, etc., were using these custom total fields.

Final Results

So here are the results of this process:

Functionality

As far as the users go, there was not change to the functionality they have been using for the past 7 years or so.

Plugins

I decommissioned and removed five plugins because their function was either unnecessary or redundant. The plugins that currently exist perform addition functions but the only pricing-related things they do are to put the values from the standard total fields into the custom total fields because those are the fields that are being used throughout the entire system.

JavaScript

About 95% of the JavaScript related to these entities was removed. Most of the work is actually done in the QOI Product entities and since the fields are named the same, I was able to have a single JavaScript library shared among all of these entities.

Lessons Learned

You’ve probably heard me say this many times but it is never a good idea to recreate Dynamics CRM built-in functionality.  Sooner or later you will pay the price for that decision and it is never pretty.

So, don’t do it.

Free webinar Friday: Defining and creating your Sales Process within Dynamics CRM

Hi Everyone,

This week’s free webinar Friday will be:

Defining and creating your Sales Process within Dynamics CRM

In this webinar we will discuss how you actually define your company's sales process and the steps required to use that process within Dynamics CRM.

Fri, May 13, 2016 10:00 AM – 11:00 AM CDT  Register here.

Drop me a line if you have any questions or suggestions.

Thanks, Mitch

Setting a Dynamics CRM field’s value to Title Case using JavaScript

In a thread on one of the community forms, Debra asked how to properly add some JavaScript she had found on another forum post to make the first letter in each word uppercase (while the remainder is lower-case). This is called title-case, by the way.

Taking the code that Debra mentioned, I modified it a bit, and ended up with this:

function upperCaseField(executionContext) {
    var field = executionContext.getEventSource()

    field.setValue(toTitleCase(field.getValue()));
}

function toTitleCase(str) {
    return str.replace(/\w\S*/g,
                       function(txt) {
                            return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
                       });
}

It is configured on an individual field like this:

js2

It is most imperative that you check the box for Pass execution context as first parameter.  If you do not, then the function will fail.

If you wish to add this function to multiple fields, you can do so using this technique, as mentioned in that thread by @aileengusni:

function form_OnLoad() {
    Xrm.Page.getAttribute("field1").addOnChange(upperCaseField)
    Xrm.Page.getAttribute("field2").addOnChange(upperCaseField)
    Xrm.Page.getAttribute("field3").addOnChange(upperCaseField)

}

Dynamics CRM Webinars for May from xRM Coaches

 

Hi Everyone,

This month I will be holding the following webinars:

Defining and creating your Sales Process within Dynamics CRM

In this webinar we will discuss how you actually define your company's sales process and the steps required to use that process within Dynamics CRM.

Fri, May 13, 2016 10:00 AM – 11:00 AM CDT  Register here.

Introduction to the Dynamics CRM Interactive Service Hub

In this webinar we will discuss the Interactive Service Hub feature of Dynamics CRM 2016 and how it can be used to increase the productivity of your service desk personnel.

Fri, May 20, 2016 10:00 AM – 11:00 AM CDT  Register here.

JavaScript and .NET Code upgrade best practices

In this webinar we will discuss upgrading your JavaScript and .NET code from version the Dynamics CRM 4.0-level APIs to the Dynamics CRM 201x-level APIs.  There is still a lot of code that was never upgrade from 4.0 to 2011 during the initial migration and as companies move toward Dynamics CRM 2016, it is imperative that this code be updated. This is is a follow-up to last Friday's JavaScript upgrade walk-through webinar I did, but It contains a wider range of information.

Fri, May 27, 2016 10:00 AM – 11:00 AM CDT   Register here.

Drop me a line if you have any questions or suggestions.

Thanks, Mitch

Repurposing Dynamics CRM Fields. Just Say No!

I was preforming a pre-upgrade cleanup for a customer when I ran into this:

badDesign

As you can see, they took a relatively unused field, Address 1: County, and repurposed it and called it Current Software.

This is a very, very, bad thing.

For one, it is totally unnecessary.  Maybe back in the 1980’s when we measured things in kilobytes and megabytes; where gigabytes was just something on a mathmagician’s chart.

But that is not today, when people regularly, and with a straight face, speak of and use petabytes and beyond.

Don’t let me catch you doing this. It is just plain bad design and can lead to fascinatingly odd problems to fix.

Is it time for you to hire a Dynamics CRM Coach?

Hi Everyone,

Have you ever seen a sports team without a coach? Probably not.

Coaches can help guide both the team and the individual players to a higher level of accomplishment and are an integral part of a winning solution.

That is why I created my Dynamics CRM Coaching Program.

The idea is simple: Most of us do not have all of the answers and rather than waste valuable time and energy searching for answers, why not bring in someone with more experience?

Consider these scenarios:

  • Need someone to bounce Dynamics CRM design ideas off of?
  • Need to see if you are on the right track?
  • Have so many “what-if” scenarios lying around you have turned into a mountain of indecision?
  • Not sure of the proper course of action to get your people trained-up enough to support your upcoming rollout?
  • You are trying to bring a product to market but Dynamics CRM is new to you and your team and you are not sure where to start.

If any or all of these sound familiar, then maybe we should talk.

Click here for more information and to find out more about my Dynamics CRM coaching program.

Thanks, Mitch

Sharing information and lessons learned with other developers

Sign up for our new KnowledgeBits service and get news, tips and tricks and more, delivered straight to your inbox.