Tip #533: Tipster guide to automatic record creation in Dynamics CRM

Hey, it’s Friday and our video dude is back from the brink. With many new service related features on the horizon, we take some time to refresh knowledge on current service features. In this video we show you how to use Dynamics CRM’s Automatic Record Creation feature. This can be used to create CRM records automatically from other records such as emails, tasks, etc.

YouTube player

Give us your feedback, all of it: good, bad, and ugly, I’m sure we can take it. Suggest new topics either in comments or by sending your ideas to jar@crmtipoftheday.com.

Tip #531: CRM, SPA and CORS walk into a bar

If you wanted to access your CRM from the javascript using web services, the only option until CRM 2016 was to wrap your script as a webresource. That way script is hosted in the same domain as CRM and “rides” authenticated session of your browser. External pages were no go because of the Cross-Origin Resource Sharing (CORS) issues.

CRM 2016 has CORS enabled so now you can create awesome things like single-page applications (SPA) that securely talk to CRM. I thought of putting some cool code together but, as usual, Jim “That’s Mr SDK for you” Daly was the first off the blocks with an SPA sample for CRM.

The most tedious part is authentication but now it’s an absolute breeze with the release of ADAL for javascript. Kilolines of code are now reduced to (simplified version, of course):

  window.config = {
      tenant: "contoso.onmicrosoft.com",
      clientId: "ef46083a-abba-dead-beef-4aafd81a93f5",
      postLogoutRedirectUri: 
           "http://contoso.com/crmspa.html",
      endpoints: { orgUri: 
           "https://contoso.crm.dynamics.com" },
      cacheLocation: 'localStorage', 
  };
  var ac = new AuthenticationContext(config);
  ac.login();
  ac.acquireToken(config.endpoints.orgUri, talkToCRM);

Detailed documentation is available, of course, from the Jim’s team. If you’re thinking of reusing your old code, that’s a no go, unfortunately, as CORS is only supported for Web API and not SOAP or OData v2.

Tip #530: CRM 2016 is available

Happy new

Earlier today at Convergence EMEA, Jujhar Singh announced general availability of Dynamics CRM 2016. The CRM Tipsters would like to wish everyone in the CRM community a happy new (CRM) year, and we are very excited to finally be able to talk about it.

The temptation for any CRM blogger is to say “hey, look at these shiny new features.” And there is a lot of shiny new goodness in CRM 2016. But the way we CRM is to look at what the features mean to real users. Hopefully we will get at least 250 more tips from this release.

The following are the areas about which we are most excited regarding CRM 2016:

For all users

  • Document generation
  • Documents in mobile
  • Mobile app linking (Export to Excel and generate Word Documents on mobile)
  • Hybrid Exchange server synchronization

For on premises users

  • Goodbye to the CRM 2013 sitemap and form nav bar.
  • Hello CRM for Phones

For CRM Online users

  • Offline mobile
  • Office 365 groups general availability
  • Significantly improved sandbox management
  • CRM App for Outlook (in another year or two we will fondly recall the ‘early’ days of the Outlook CRM Client)

Developers (They are users too. In a sense)

  • Web api (OData v2 is dead deprecated)
  • CORS support (single page apps, here we come)
  • Solution patching
  • New mobile custom controls
  • Web resources and iframes support in mobile
  • Online/on-premises parity (for now)

Tip #529: Queuing things in CRM workflow and code

I know it’s and oldie but I just got this question today so perhaps time for a refresher. The question was on “how to queue activities and other things in CRM workflow – I vaguely recall ‘assign’ operation but I can only assign to a user and not a queue”.

Long, long time ago CRM introduced ability to queue arbitrary (well, almost) entities – just need to enable an entity for the queues (careful though – it’s a one way street, once enabled, you won’t be able to remove this flag). To queue these and any built-in queue-enabled entities (like tasks, cases, etc) inside a workflow or inside your code, you simply need to create a new Queue Item record and set the properties such as Queue Name and Queue Item (i.e. the record to queue). Optionally set Worked By and you are done.

To move item to another queue, simply create another queue item – the system will take care of the cleanup of the now orphan item.

Tip #528: Execute them all

While our video dude is stuffing himself with turkey (who’d want to listen even to Morgan Freeman with a mouthful of dry meat?), I’d take this Friday to clarify few things about asking CRM server to do few things at once. There are two ways to do it.

ExecuteMultiple

ExecuteMultipleRequest has been around for quite some time (since 2011, in fact) and it’s been designed to improve performance of bulk operations. It improves the performance by removing the need to “chat” with the server – just package all requests that need to be processed, send single request over to the server and optionally get a bunch of responses back. Requests in the batch are independent of each other though you do have ability to stop the batch if something goes wrong (this is not a transaction, whatever happened prior to the error, will stay in the database). Repeat after me:

ExecuteMultiple is not a transaction

One interesting discovery I came across recently is that using ExecuteMultiple in plugins can be detrimental to the performance. Makes sense when you think about it – you’re already on the server, network latency is absent, conversation overhead is negligible and time is wasted on bundling/unbundling the requests.

If you’re doing what ExecuteMultiple is designed to assist with, bulk data load, and you’re also using multithreading to squeeze the last bit of performance, then you probably have seen the “server is too busy” error. As one of the “insiders” (or British scientist, make your pick) explained it to me:

The server too busy error with executemultiple usually means that they are issuing too many calls concurrently. Online instances are limited to 2 calls concurrently (although you may get more in some cases depending on how your calls are load balanced).

The batch size is not directly related to this, but smaller batches may be finishing faster and hence reducing that actual number of calls concurrently operating on the server.

If you’re planning to use ExecuteMultiple, do some reading (unless you are a cat on your 9th life, of course).

ExecuteTransaction

ExecuteTransactionRequest, introduced in CRM 2015 Update1, does wrap multiple requests as a single transaction. Note that if you are thinking of improving your application by bundling creation of a contact and 72 related tasks, the capability to perform transactional creation of related records has existed since 2011 days, and I would still recommend that over ExecuteTransaction.

Some good articles about ExecuteTransaction has existed for over half a year; and it’s very encouraging to see them coming from the vendors (meaning that their software just got better). There are some good takeaways, essential ones being throttling limit still applies and there could be a performance penalty due to a locking nature of the transactions.

Plugins

There seems to be some confusion how these messages behave inside the plugins. Anything executed at pre-validation step (i.e. outside of the database transaction) will behave as described above. At all other stages, according to the authority, things are wrapped inside the plugin transaction and

If a plug-in executes within a database transaction, the plug-in executes ExecuteMultipleRequest, and a transaction rollback is initiated, the rollback includes any data changes resulting from requests executed by ExecuteMultipleRequest

But the point is moot, however, because ExecuteTransaction is, uhm, transactional by default and using ExecuteMultiple inside the plugin does not do you any good, anyway.

Tip #527: Top CRM Turkeys

CRM TurkeyIt’s Thanksgiving in the United States today. That’s when Americans give thanks and eat too much (actually, they do that last one all year round). The traditional food of choice is turkey, a not so majestic fowl. I suspect that most people don’t actually like the taste of turkey, but they eat it because of tradition and sentimentality. This is reinforced by the fact that turkey is also synonymous with things that fail, flops, and general lame things.

At tip of the day, we love Dynamics CRM, but like many things that are great, not all of its features have always been good. In the spirit of turkey day, lets look back at some of the CRM turkeys from the past:

  • Announcements: The purpose of this feature was to provide useful notifications to users. The problem was that it did not alert them. To see the announcements, the users had to navigate to the announcements. Sure you could make that their primary sitemap area, but users can change that, and no users in the Outlook client saw them. A few releases ago, announcements were removed from the sitemap. Nobody cared.
  • Mobile Express: Mobile express bears the honor of being the first mobile interface for Dynamics CRM. However, it was doomed from the start. When it was released in 2009, the iPhone had already been out for two years, but Mobile Express remained stuck in the Blackberry age, with single column forms and no form automation. Nobody shed any tears when the new CRM for Phones was released in CRM 2015 update 1.
  • Invoices: In the words of George Doubinski

    I used the invoice entity one time, and later wished I hadn’t.

    Not that the invoice is bad, it just doesn’t fit many real-world scenarios. Nobody generates invoices in their CRM system — they do that in their ERP or accounting software. If you are the rare company that converts orders to invoices you may like it. If you generate invoices in another system and integrate them to CRM, a custom entity can give you everything that the invoice entity delivers with additional flexibility (like working on mobile).

  • Faxes: Ah fax entity, what can I say about you? Back in your CRM 3.0 glory days, you were busy integrating with WinFax. After faxing died (except for my doctor’s office), you still had life as the go-to activity entity to be re-used whenever somebody needed an SMS, chat, or some other type of custom activity. Then the product team introduced custom activity support, and now you sit there in lonely solitude while all of the cool kids are eating with accounts and unified service desk.
  • Mail merge: There was a time when CRM mail merge was cool. And that time was 2007. As CRM and Microsoft Office capabilities matured, mail merge remained the same, with the same limitations in number of fields and inability to show related entity data. I’m using CRM mail merge to generate party invitations to the funeral for CRM Mail Merge now that CRM 2016 introduces new document generation capabilities.
  • Read-Optimized Forms: The day Read Optimized Forms were announced as the new default in CRM 2013 Update 7, many of us mounted the barricades in one of the Advanta Building’s conference room and began singing “One Day More” – mostly because of the resulting user experience would have been a disaster for all but a very small number of users. Thankfully, the product team heard our cry, they quickly made some minor adjustments, and RO Forms were released without a hitch. – In a subsequent version, the R-O-Forms quietly went away and were replaced with the significantly improved “Turbo Forms” – a much better, more usable experience all around.
  • Knowledge Base Articles: Since the beginning of CRM there has been a “Knowledge Base” – of sorts. In practice, its only use was to allow someone to answer an RFP honestly with “Yes, there is a KB out-of-the-box. Next question?”. – Thankfully, happy days are here again! – The Parature acquisition in 2014 opened the doors to a dramatically re-engineered Knowledge Management area for CRM 2016. I’m excited to see this area get some much needed love and attention.
  • Contracts: With a rigid lifecycle, uneditable templates and a twisted world where “invoiced” does not mean “invoiced”, no wonder only a few brave legends ventured into the world of contracts. With SLAs and entitlements picking up pace, who needs contracts anyway?

Bonus features

Not exactly the turkeys, these are the features CRM could have happily lived without:

  • Unneeded “Bonus” Contact Attributes: Children’s Names, Anniversary, Birthday, UPS zone, etc.(it’s a really, really long list) – I am guessing that at some point prior to CRM 1.0, there was a group of Product Managers sitting around a room brainstorming all the attributes that *might* be useful to someone someday. – (and I’m sure someone somewhere is really fond of having these fields out of the box…)
  • Auto-numbering – “Dear customer, your case is CAS-00033-AS7OX3. No, those are zeros. Except the one before the ‘X’. Yes, unfortunately CAS-00034-DOUCHE is your other case number. I’m sorry, we don’t control it and cannot change it.” Ugh. No wonder every self-respecting CRM consulting and ISV company rolled out auto-numbering solution of their own.
  • Sites, subjects, resources – not entirely useless but without any ability to customize, extend, and re-use, these entities fall into a category “I wouldn’t have used these if I had a choice”. Unfortunately, a lot of other useful entities and features are so intertwined with this bunch that we just have to bite the bullet and explain to every customer why they cannot add a cost centre code to a site.

Got another turkey? Comment below or send it to jar@crmtipoftheday.com.

Tip #526: Team is always more than sum of its parts

Dynamics CRM TipperAnother mini truck stop, this time to assist Dylan “Not a real Kiwi” Haskins preserve his sanity.

tl;dr

If a team has user-level privileges, members of that team will NOT have these privileges for the records owned by individuals and not the team. For example, if the team has a user-level create privilege then a team member will not be able to create their own records, CRM will only allow them to create records owned by the team.

The Question from Dylan

Am I losing my mind, or does a User Level permission defined in a Role on a Team NOT work.

We have a role assigned to a team that gives Basic (User Level) write permission on Activities, and the user is part of the team, but their own activities appear read-only. If I assign the role directly to the user they can edit their activities as expected.

The answer

Jukka “I am not a developer!” Niiranen

Dylan, I bet you’ll find the explanation from this excellent article by Adam: “Security Roles and Teams in CRM – An Inconvenient Half-Truth”.

http://blog.crmguru.co.uk/2013/06/25/security-roles-and-teams-in-crm-2011-an-inconvenient-half-truth/

The authority

The author of this incredibly useful, thorough, though at times mind-bending monstrosity, Adam “I pwned the truckstop” Vero, chimed in as well:

I wonder how many people, both new to CRM or even some old hands, still get caught out by this. Would it not make more sense to change the key / legend in the Security Role editor form so that the first option is labelled “Owner” instead of “User” to try and avoid some of this confusion?

Please vote for this (now one year old) Connect suggestion: Reword security role colour key so that “User” level is labelled “Owner”

Tip #525: Solution Export Naming Party Trick

The solution version number is often overlooked as an easy way of keeping backups of your solution separate as you configure CRM.

You can number them according to a strict 4-part version numbering (e.g. 1.0.0.1, 1.0.0.2, etc.) but that’s relatively boring and tough to keep consistent.

The most straight forward and easy to maintain method of versioning for solutions is to utilize a pseudo timestamp as the version number.

Anytime a solution is going to be exported, the version number should be updated by the administrator, and saved before it’s actually exported. For simplicity, use the format of YYYY-MM-DD-##, where ## is the intra-day revision number that is just incremented with each version created on a particular day, e.g. the first update/export of a solution on October 9, 2015 would have a version number of 2015.10.09.01 as shown in the following image. (Before exporting again on the same day, just rev the last 2 digits to 02)

2015-11-23_17-30-46

The exported file will be named with the solution “Name” plus the version number (date + rev)  giving it a unique name and making it easy to keep track of current and older versions.
2015-11-23_17-35-08

Following this convention means your deployment team is never confused about which iteration to install and you can clearly see in production which solutions is live.

Tip #524: Inactive optionsets

One of the advantages of using lookups vs optionsets is the ability to create a “dynamic” set where the available values can be filtered and deactivate when they become obsolete. Optionsets still are very useful because they are easy to set up and use – dropdown as a UI element is all too familiar to discard.

So what can you do if you need to remove some of the values from the existing optionset? Firstly, using advanced find, figure out if the value to be removed is actually used. If not, simply remove it from the optionset. If the value is in use, however, and you don’t want to break existing functionality, then values can be filtered on the fly by removing them when the form loads.

function form_onload() {
   var value = Xrm.Page.getAttribute("industrycode")
                       .getValue();
   var ctrl = Xrm.Page.getControl("industrycode");
   var inactive = getInactiveOptions("industrycode");
   inactive.forEach(
      function(i) {
         // check if value is in use
         if(i != value) ctrl.removeOption(i);
      }
   );
}

function getInactiveOptions(field) {
   if(field == "industrycode") 
      return [1,2];
   else
      return [];
}

This script removes couple values from the industry code list when the form loads. It does not completely solve the issue but it does the job as far as user interface is concerned. You can improve usability of the script by adding words “(obsolete)” to the inactive values that are “in use”. More advanced versions could use a custom action call to the server to find out the list of inactive values – that way they can be maintained in one central location (helper entity, for example).