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).

Tip #523: Tipster guide to invoking custom actions without code

Hey, it’s Friday and time for another video tip. In the last week’s video we talked about how to create custom action, add parameters to it, define conditions and steps, etc. This week we continue by demonstrating how to call your custom actions from real-time workflows (or dialogs) without writing any code.

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 #522: Escape CRM Online sandbox

I said it before and I said it again that presenting at the conferences like eXtremeCRM can be a real eye-opener. You quickly learn, for example, that Bob could not make it and you also learn how much people know about CRM. With all the accumulated knowledge it comes as a surprise that some of the features that has been around for years are misunderstood, and underused.

Take, for example, this menu item:
Register Service Endpoint
As it turns out, people are still unsure what it’s there for and what exactly does it do.

Without writing a single line of code it allows registration of an endpoint that is similar to a standard plugin registration so that you can register steps with it, like create for the account entity. The difference is that, instead of executing your plugin code this endpoint will push the data out of CRM to the Azure Service Bus with all the plugin context intact. For example, push it to the queue and then create a listener on the other end and pick up whatever CRM pushed out.

Why would we want to do that? How about:

  1. Remoting the lengthy processing to bypass 2 minutes sandbox limit.
  2. Publishing context for partner’s consumption – the data pushed out is protected by service bus security but no longer governed by CRM.
  3. Copying data to on-premises database for processing and reporting – listener can be behind the firewall and get an easy secure access to the service bus.
  4. Run small listening service on users’ computers notifying them almost in real-time when something important happens
  5. Big opportunity win notification

Of course, there are some additional moving parts to the story like creating an Azure Service Bus, negotiating security between CRM and the service bus, etc, but all steps are documented to death in MSDN and there are some good articles and walkthroughs written about it.

Go and create some goodness.

Tip #521: SharePoint integration in a CRM Online trial

So you set up a Dynamics CRM Online 30 day trial and you want to also try the document and OneNote integration. Here is how to get a SharePoint Online trial to use with your Dynamics CRM trial. There are two approaches:

  1. If you have already set up a CRM Online trial, from the Office 365 account associated with your trial, sign up for the Office E3 trial (https://products.office.com/en-us/business/office-365-enterprise-e3-business-software). This trial includes SharePoint.
  2.  If you have not already set up a CRM Online trial, start with an Office 365 trial, open O365 portal, go to Purchase and add CRM trial.

 

Tip #520: Appointment meeting invitations

In Dynamics CRM 2013 or later, synchronized appointments send meeting invitation emails to meeting attendees when they are created or updated. This is a feature that was commonly requested by CRM users, but there are some scenarios where you may not want this to happen.

Meetings created or updated after the meeting happens

Some users may want to update the appointment attendees to accurately reflect who attended the meeting. Or you may want to create an appointment record after the meeting occurred. In these scenarios, you don’t want the attendees getting a retroactive meeting invitation.

One approach that can help with this is to modify the appointment synchronization filter to only include meetings where the start date is in the future (say the next 500 days or something). Alternatively, you could create a “do not synchronize” flag on the appointment record, then update users synchronization filters to not include records flagged as “do not synchronize.

Gustaf Westerland says that if you don’t want any attendees getting notified, you may want to take more dramatic action, such as breaking appointments out to separate mapping entity and then using precreate/update plugin to prevent the notification email from being sent.

Sensitive meeting notes

Another concern is that if a user updates the body of the appointment with notes from the meeting, the attendees will receive a meeting update email. We addressed this in tip 287. Don’t use the appointment body/description for meeting notes. Replace it with the notes pane (or OneNote if you are online). Set the body to not synchronize between CRM and Exchange. This will prevent embarrassing notes or comments from being sent to your customers.