Showing posts with label ms crm customization. Show all posts
Showing posts with label ms crm customization. Show all posts

Saturday, April 6, 2019

How to I hide App navigation in Dynamics 365 CE?

My favorite secret weapon is a Chrome extension called Stylebot. I can change navigation, colors, and even compress whitespace!

After you install it, refresh your screen and open it using the CSS icon in Chrome. You can click on the element you want to change (or hide), and it has friendly buttons to make quick changes. It will save the style changes using the URL of the site. You can export and import the style mods and share them with other users.

Wednesday, February 27, 2019

What is the solution version number used for?

A recent thread of discussion on the CRMUG forums about this topic got me thinking – here is my take on the subject.

For the smaller clients with no integration, I think there is value in using the current date in the solution version number so when you export it so that you can easily keep track of which file in your downloads folder is the right one. A quick acknowledgement to @Gus Gonzalez's for making that suggestion. End users can easily comprehend it and it adds value to them. A solution file can have literally anything in it and the (typical) version number does nothing to help you with figuring out what is major/minor/patch or resolving dependencies. By using Gus's technique, the date of the solution is built into the exported file name. By using Gus's technique, you avoid having multiple copies of a file called "SolutionName_1_0_0_0.zip" and trying to figure out which one is relevant. I would argue that for the people creating solutions for small(er) organizations, it is not easy to make the distinction of major vs minor. Can anyone here define how many fields on a form must move before you cross the threshold from a patch to a minor release, or how many business rules must be changed before it becomes a major release?


But for a company that has a staff of developers that depend on integration with other systems and have governance policies, we should consider the benefits to the version number with a traditional approach. For many of my past projects, I have clearly agreed with @Ben Bartle's position because I come at this as a developer. The reason has to do with traditional software development practices: When writing applications that have dependencies on a multitude of libraries (.DLL's), then keeping track of the version number helps you identify whether an update to a library will significantly impact your application. With a DLL it is easy to define what is major, minor or a patch based on best practices.

For a consultant that is configuring systems for many clients, I would recommend that you have the name of the client for the solution name, and put the D365 version in the first two decimal positions of the version number, and date in YYMM.DD format in the last two positions. This makes it easy to tell which version of D365 you exported the solution from (which could be significant if the development area is not in sync with staging and production) and the date it was exported.

To bring this point back into context of this discussion, when you modify a D365 solution and then promote it to production, you are actually updating the API endpoints. Consider what happens when you alter the behavior of workflows, deprecate entities/fields, or make the field length shorter. When you promote that solution into production, you run the risk that integration code will break.

Personally, I have been putting the date in the solution's Information/Description field.  While this is not as pretty as using the version number as a proxy for a date, it serves it purpose because you can see the solution description gets updated in the production system. The only downside with that approach is that you have to either import the solution file to see the description containing the date, or rip apart the zipped solution file and read the XML files.

With respect to keeping track of whether the solution file contains a major/minor/patch to a system, that is something everyone should be documenting anyway regardless of whether you go with Gus or Ben's recommendation. By keeping a log of changes and/or implementing a full version control system between development/staging/production, you must be communicating your changes to your testing staff or your end users, no matter how small the change is. If users detect a change that you were not in control of, they might think the system is unstable, and they will lose confidence in your system.

Sunday, December 2, 2018

Customizing D365 forms using JavaScript

I know, a lot of people have written about customizing CRM forms with JavaScript, but I am learning some cool stuff and wanted to share what I learned this week.
The big news for me was that Promises are supported in D365 forms now. I am sure this is not news to many people, and to others they have no idea what I am talking about, so this article is for them.
Why are Promises important?
If you have written a JavaScript function that uses a “call back” (passing a function name as a parameter into another function), then you have probably run into the fact that the call back can happen at any time. If you have several of them that need to be run in a sequence, they will sometimes cause your code to fail because it does not execute them synchronously.
I have seen many programmers try to solve this problem by building “Christmas tree” code that nests one function inside the other until you are 15 levels deep in brackets, and lord help you if you if there is a syntax error with one bracket out of place. Even worse is the difficulty to test and maintain all permutations of “Christmas tree” code so that you are sure there are no errors. Promises are an excellent solution to that problem.
A Promise design pattern is way to write a function that will leverage the asynchronous nature of JavaScript with the ability to sequentially perform a series of tasks. 
I learned about Promises from a Pluralsight course authored by Jonathan Mills called JavaScript Best Practices. I did some research and found a few code samples in GitHub for CRM projects that used Promises. Here are some links that I used to learn more, but frankly, some of it was deeper than I needed.
Promises
https://blogs.msdn.microsoft.com/ie/2011/09/11/asynchronous-programming-in-javascript-with-promises/
Promise API framework for CRM
https://code.msdn.microsoft.com/CRM-Web-API-Functions-and-87cd0b45#content
It uses https://github.com/stefanpenner/es6-promise
https://github.com/mariusso/WebAPI.REST.js/releases




Some of the above links say that you need to include the e6promise.js library, and that may have been necessary in earlier versions of CRM, but I am working in V9.1 and it is not necessary to add any other framework to your project, but it did help me understand what is going on.
What got me started on this article was when I needed to build a customization and realized that I needed several sequential calls to fetch data first, then create new records, but they had to be executed in order.
I noticed that Jason Lattimer’s CRM REST Builder used a Promise syntax when I used the Xrm.WebApi option to build a request for fetching data, so I decided to see if I could make that work for me. Besides, I like the succinct format of WebAPI over the XMLHTTP format.
I created a form script called Library.js and in following best practices, created a FormLib namespace so all my methods and properties are prefixed with “FormLib.”.
First I used CRM REST Builder to create an asynchronous call to get some data for me that looks like this:
Xrm.WebApi.online.retrieveMultipleRecords("tn_changeorder", "?$select=tn_changeorderid&$filter=statuscode eq 0 and  _tn_quoteid_value eq <giud>").then(
     function success(results) {
         for (var i = 0; i < results.entities.length; i++) {
             var tn_changeorderid = results.entities[i]["tn_changeorderid"];
         }
     },
     function(error) {
         Xrm.Utility.alertDialog(error.message);
     }
);
Notice the “then” that follows the async call – this was my clue that the Xrm.WebApi was a Promise.
Following Jonathan Mills instructions, I created a wrapper function :
FormLib.GetChangeOrder = function () {
     return new Promise(function (fulfill, reject) {
         // begin REST code

        // end REST code
     });
};
and then I inserted the “fulfill” and “reject” into the REST code, and put it all together so that now my code looks like this:
FormLib.GetChangeOrder = function () {
     return new Promise(function (fulfill, reject) {
         // begin REST code
         Xrm.WebApi.online.retrieveMultipleRecords("tn_changeorder", "?$select=tn_changeorderid&$filter=statuscode eq 0 and  _tn_quoteid_value eq  <guid>" ).then(
             function success(results) {
                 for (var i = 0; i < results.entities.length; i++) {
                     var tn_changeorderid = results.entities[i]["tn_changeorderid"];
                 }
                fulfill();
             },
             function (error) {
                 Xrm.Utility.alertDialog(error.message);
                 reject();
             }
         );
         // end REST code
     });
};

Now every time I make an async call, I create one of these functions (above) and can fire them sequentially using a syntax that looks like this:
FormLib.GetChangeOrder()
            .then(FormLib.CreateRelatedCase)
            .then(FormLib.SetupDetails)
The magic is the fulfill() that calls the next item in the “then-chain”. The reject() allows you to call an error handler and gracefully exit the chain. In my example above, the “.then(FormLib.CreateRelatedCase)” is passed into GetChangeOrder() and executed after it has completed its task of looking for an existing record.
You could argue that it is easier to just call the next function in the chain by using the specific function name instead of calling fulfill(), but then you would have tight coupling and it is difficult to maintain when you have to decipher the code to figure out what the chain is.
Promises solves the problem of deep nesting of functions by splitting them all out to discrete, re-useable, loosely coupled, and testable functions that can be called sequentially. The Promise Design Pattern also makes handling errors and parallel tasks easier to manage. I recommend you learn this design pattern if you are going to do any amount of JavaScript coding.

Sunday, August 29, 2010

MS CRM Autofilter gotcha

I am building a report using SSRS that I intend to use as an auto-filtered report inside of MS CRM (see http://blogs.msdn.com/b/crm/archive/2009/03/06/microsoft-dynamics-crm-pre-filtering-tips.aspx). The report pulls data from several views. Everything seemed to be working fine in development until I imported the report into CRM, then parts of the query seemed to stop working.

If you read the end of that article, it points out that all the entities referenced in the FROM or JOIN clauses will have a default filter applied to them that will limit what is included in the query to only records that were modified in the last 30 days.

In my case, I was using a parent entity with 4 outer joins, and I was only retrieving some of the data because some of the related tables had data that was not modified recently.

My solution to this problem was to create a single report that uses only one view with the CRMAF alias, and it used a sub-report that did not have the CRMAF alias on the views. This permitted me to associate the parent report with the entity, and pass the ID’s to the sub-report where there was no filtering.

In my case, I was creating a custom invoice for a custom invoice entity, so I created my parent report with just the one filtered view and gave it an alias of CRMAF_custominvoice. I embedded the sub-report in a table (tablix for VS 2008) control detail band, and gave the sub-report the ID value to pass as a parameter. In the sub-report, I had the rich and complex SQL that I wanted using filtered views, but not using the CRMAF alias.

Saturday, July 17, 2010

Open custom entity windows using ETN instead of ETC

I am connecting an Adobe Flex application to MS CRM and one of the tasks we need to do is open a CRM window of a custom entity. If you look at the URL of the custom entity, it contains a parameter that says "etc=1000x" where the number is a reference to the custom entity edit form. If you are developing on the production system (not a good idea) that number is safe to use. However, if you develop on a different system, there is a good chance that the "etc" number will be different.

I recommend that you use the "etn=new_customentity" parameter instead of the "etc=" because the name of the custom entity will always be the same between the development and production systems. The value for etn will be the custom entity name which you will find on the entity customization form.

Helpful tip: if you want to see the full URL of a crm form, press F11 to make the browser full size, then move your mouse to the top of the window and the URL bar will appear - then you can copy the URL and paste it into an editor for your inspection.

Please let me know if this helps and leave a comment.
Thanks!