Sep 17, 2017

Importing Duplicate Detection Rules

Since early versions of Dynamics 365, we have been using Duplicate Detection rules and it is a handy feature. Ironically, still we can't import those rules with Solution. In most cases, users configure them in different environment and its not a big deal. Still, it can be error-prone and inconsistent.

So alternative is to consider Duplicate Detection Rule entities as reference data and import them using Configuration Migration Tool coming with SDK. Usually you will find this tool in below location of the SDK;

\SDK\Tools\ConfigurationMigration

Anyway, below are the two points to keep in mind when importing Duplicate Detection rules;

1) Rules should be Unpublished before importing.
2) Need to include both Duplicate Detection Rule and Duplicate Rule Condition in correct Order.


Hope this helps.

Sep 14, 2017

Convert in between Local Time and UTC Time

Though this is not a new subject, thought of sharing a simplified version of Code snippet to be used in converting Local Time and UTC Time as necessary. Base for this code was taken from SDK, but I have simplified and made a Ready Made class, which I though is helpful.

Let's remind few reasons why these conversions are very important to Dynmics 365 implementations;
  • DateTime fields are always kept in DB as UTC, but shown in UI with Users Local Time.
  • DateTime Retrieve with Web Service is always UTC.
  • Plugin/WF Context returns UTC time. 
Below are some of the scenarios you may come across that need conversions in your code.
  • When you need to do a calculation based on Time
  • When you need to pass Data to another System

Here is the class I suggest;
using Microsoft.Xrm.Sdk;
using System;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;

namespace CommonLibrary
{
    internal static class CommonUtility
    {
        internal static DateTime RetrieveLocalTimeFromUTCTime(IOrganizationService service, DateTime utcTime)
        {
            return RetrieveLocalTimeFromUTCTime(utcTime, RetrieveCurrentUsersSettings(service), service);
        }

        internal static DateTime RetrieveUTCTimeFromLocalTime(IOrganizationService service, DateTime localTime)
        {
            return RetrieveUTCTimeFromLocalTime(localTime, RetrieveCurrentUsersSettings(service), service);
        }

        internal static int? RetrieveCurrentUsersSettings(IOrganizationService service)
        {
            var currentUserSettings = service.RetrieveMultiple(
                new QueryExpression("usersettings")
                {
                    ColumnSet = new ColumnSet("timezonecode"),
                    Criteria = new FilterExpression
                    {
                        Conditions =
                        {
                    new ConditionExpression("systemuserid", ConditionOperator.EqualUserId)
                        }
                    }
                }).Entities[0].ToEntity<Entity>();
            return (int?)currentUserSettings.Attributes["timezonecode"];
        }

        internal static DateTime RetrieveLocalTimeFromUTCTime(DateTime utcTime, int? timeZoneCode, IOrganizationService service)
        {
            if (!timeZoneCode.HasValue)
                return DateTime.Now;
            var request = new LocalTimeFromUtcTimeRequest
            {
                TimeZoneCode = timeZoneCode.Value,
                UtcTime = utcTime.ToUniversalTime()
            };
            var response = (LocalTimeFromUtcTimeResponse)service.Execute(request);
            return response.LocalTime;
        }

        internal static DateTime RetrieveUTCTimeFromLocalTime(DateTime localTime, int? timeZoneCode, IOrganizationService service)
        {
            if (!timeZoneCode.HasValue)
                return DateTime.Now;
            var request = new UtcTimeFromLocalTimeRequest
            {
                TimeZoneCode = timeZoneCode.Value,
                LocalTime = localTime
            };
            var response = (UtcTimeFromLocalTimeResponse)service.Execute(request);
            return response.UtcTime;
        }
    }
}

Suppose we need to Retrieve Local time from UTC time (dateTime could be a field coming from Plug-in context);

DateTime dateTimeLocal = CommonUtility.RetrieveLocalTimeFromUTCTime(service, dateTime);

Sep 11, 2017

Azure Subscriptions for Dynamics 365 Developers

Now it’s time to jump in to Azure and find out what’s available for Dynamics Developers. First thing first, how to get azure subscription. I mean FREE subscription to play around and see.

Option 1
Get the general Azure Trial worth $200.

Check: https://azure.microsoft.com/en-au/free/

Only issue with this option is it last only 30 days, you must complete all your drama in 30 days!

Option 2
Register for Dev essentials program, which gives $300 worth credit for one year, which is good.

Check: https://www.visualstudio.com/dev-essentials/


Warning
What so ever, one thing you may need to know is these free subscriptions are NOT per account, BUT per person. Though you try with different email addresses Microsoft will nail you down with Mobile OR/AND Credit Card details. In fact, you can use one of the above two choices.
Sadly, registration form just through a generic error (i.e. We cannot proceed with signup due to an issue with your account. Please contact billing support) and you may not be able to understand why you can’t register.


Option 3
Now come the thrilling part. As Dynamics Developers we always work with Dynamics 365 trials. Though they expire in 30 days, we are ALLOWED to create as many instances as we want.

Check: https://www.microsoft.com/en-us/dynamics/free-crm-trial.aspx

Actually, once you create Dyanmics 365 instance, relevant Admin user get free subscription automatically assigned to that account! Isn’t it fun?

Problem solved! Though it is painful to create Dynamics 365 trials again and again, at least we know that we can get Azure subscriptions as we wish regardless of how many we had in the past.

Feel privileged to be a Dynamics 365 Developer!

(Thanks Sam and Proveen for the help in this regards)