Saturday, July 29, 2017

DYNAMICS 365 - HOW TO KEEP YOUR CUSTOMERS UPDATED WITH THEIR CASES


One of the keys to increase the usability of the interaction with your customers, and to adopt your system, is to notify you customers with your Dynamics users updates on a case.

A tip of doing this, is to set a workflow to be triggered when a note is created on a case, the workflow will send an email to the customer, updating him/her with the note description.

You can do this by following the below steps,

1. Create workflow to run on Note entity

2. in the workflow, add a condition to check if the note is regarding a case.

3. If the condition is met, then send email to the customer and place the note description in the email.


4. Save and activate the workflow.


Thanks :)

Monday, July 24, 2017

Business Rules Vs Rollup Fields Vs Calculated Fields


FeatureTriggerExecutionClient / ServerScopeConditionsFieldsFunctionsLimitsUsage
Business Rules

OnLoad
On Change
Synchrounous / Real Time
Execution order:
First: System JavaScripts
Then: Custom Javascript  
Finally: Business Rules
Client: Specific Forms/ All Forms/
Server
Entity / All Forms / Specific FormsAnd / OR, not a mixureAll Fields on the form body
  • Show Error Message
  • Set Field
  • Set Business Required
  • Set Visibility
  • Set Default Value
  • Lock / Unlock Field
Fields updated through Business Rules do not trigger the fields on change event of JavaScript. Reducing potential of infinite loop.Perform field validations and apply field logic to improve user input and experience
Rollup FieldsOn Save / Every 1-12 hours / When User Presses Rollup Refresh ButtonAsynchronous / Every 1-12 hours
Rollups are calculated by scheduled system jobs Settings > System Jobs > View > Recurring System Jobs. System Job type: Mass Calculate Rollup Field or Calculate Rollup Field
ServerRelated Entity / Parent Child Relationship Upto 1 Level DeepAnd / OR, not a mixureWhole Number
Decimal
Currency
Date
SUM / MAX / MIN / COUNT / AVGCannot use other Calculated or Rollup fields as part of a rollup.Aggregate calculations of child entities. The difference between Calculated Fields is Rollup fields are not virtual, they are physical attributes. Such as no. of open opportunities, activities, revenue, etc.
Calculated Fields

OnSaveSynchronousServerEntity/ Parent Child Relationship Upto1 Level DeepAND or OR , Not a mix of both
  • Single line of text
  • Option Set
  • Two Options
  • Whole Number
  • Decimal Number
  • Currency
  • Date and Time
ADDHOURS, 
ADDDAYS,
 ADDWEEKS,
ADDMONTHS,
ADDYEARS,
SUBTRACTHOURS,
SUBTRACTDAYS,
SUBTRACTWEEKS, 
SUBTRACTMONTHS,
SUBTRACTYEARS,
DIFFINDAYS, 
DIFFINHOURS,
DIFFINMINUTES,
DIFFINMONTHS,
DIFFINWEEKS,
DIFFINYEARS,
CONCAT,
TRIMLEFT, and TRIMRIGHT.
Two calculated fields cannot reference each other in their formulas
Floating point numbers cannot be used in calculated fields.
Won’t trigger workflow updates
Fields are virtual /not stored at the database level
Ability to populate a field with simple calculations based on other values and conditions on the form in a real time manner.   This alleviates the need for JavaScript in fairly straight forward scenarios such as adding days or months to a date, or adding or subtracting fields on the same entity.
Calculated fields can calculate based on other fields, including rollup fields and other calculated fields.

Sunday, July 16, 2017

Multi-Select Option Set in Dynamics 365

A new feature "Multi-Select Option Set" is introduced in Dynamics 365. Very useful feature, it will reduce lot of effort for the developers. In one of our project we used an external IP to implement this. Few screen shots on this awesome feature.











Sunday, July 9, 2017

RETRIEVE OPTIONS LIST IN MULTIPLE LANGUAGES in DYNAMICS 365

If you had a requirement where you want to retrieve a list of options of an option set in your CRM/365 organization depending on the language, for example if you pass to the method 1025 it will return the options in Arabic, if you pass 1033 it will return the options in English and so on.

For example, if you are integrating your Dynamics 365 with a portal, and you want to create a drop down list of these options coming from an option set in the 365, and this options maybe changed in the future, so its not practical to change the drop down list options.

In this case, I'm going to give you a code I was using to listing data from CRM 2016 to SharePoint 2016.

public Dictionary<int, string> LocalOptionSetList(String entityName, String optionSetName, int lcid)
        {
            try
            {
                if (lcid == 0)
                    lcid = 1033;// default english
                using (var xrmContext = new XrmServiceContext(CRMConnection.CRM))
                {
                    RetrieveAttributeRequest raRequest = new RetrieveAttributeRequest
                    {
                        EntityLogicalName = entityName,
                        LogicalName = optionSetName,
                        RetrieveAsIfPublished = true
                    };
                    RetrieveAttributeResponse raResponse = (RetrieveAttributeResponse)xrmContext.Execute(raRequest);
                    PicklistAttributeMetadata paMetadata = (PicklistAttributeMetadata)raResponse.AttributeMetadata;
                    OptionMetadata[] optionList = paMetadata.OptionSet.Options.ToArray();
                    Dictionary<int, string> dic = new Dictionary<int, string>();
                    foreach (OptionMetadata oMD in optionList)
                    {
                        dic.Add((int)oMD.Value, oMD.Label.LocalizedLabels.Where(x => x.LanguageCode == lcid).FirstOrDefault().Label.ToString());
                    }
                    return dic;
                    //StatusAttributeMetadata message if you want  to retrieve options from a status reason field
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

Wednesday, July 5, 2017

Best Practices when Writing Dynamics CRM Plugins



• For improved performance, Microsoft Dynamics 365 caches plug-in instances. The plug-in’s Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. Also, multiple system threads could execute the plug-in at the same time. All per invocation state information is stored in the context, so you should not use global variables or attempt to store any data in member variables for use during the next plug-in invocation unless that data was obtained from the configuration parameter provided to the constructor. Changes to a plug-ins registration will cause the plug-in to be re-initialized.

• Its a best practice to check for the target entity name and message name at the beginning of the plugin execute message to avoid running the plugin unintentionally.

• When you want to update fields on a record, it’s good practice to create a new entity or early bound type of the record and only add the fields you want to update. By only updating the fields you are changing you reduce triggering other plugins running needlessly.

• When retrieving an entity using SDK, make sure you are instantiating a new object (not just assigning a reference) and assigning it to the returned object from the retrieve SDK message for better performance.

• Do not update the retrieve Target entity because it will update all fields included in the target entity.

• The common method to avoid a recurring plugin is to check if  a plugins depth > 1.  This would stop the plugin from being run if was triggered from any other plugin.  The plugin would only run if triggered from the CRM form. This can resolve the problem of plugins firing more than once but it stops plugins being triggered from other plugins, this might not be the functionality you require.

Allows the user to enter numbers in the field, and only allows two numbers after the decimal place.

After long time gap working on .NET/MVC

I see developer are getting frustrated when adding validation on numbers & decimal digits.


it's better to prevent the user from making a mistake than to correct him after", here is my solution. It only allows the user to enter numbers in the field, and only allows two numbers after the decimal place.



 <script>

      // Retrieve last key pressed.  Works in IE and Netscape.
      // Returns the numeric key code for the key pressed.
      function getKey(e)
      {
        if (window.event)
           return window.event.keyCode;
        else if (e)
           return e.which;
        else
           return null;
      }
      function restrictChars(e, obj)
      {
        var CHAR_AFTER_DP = 2;  // number of decimal places
        var validList = "0123456789.";  // allowed characters in field
        var key, keyChar;
        key = getKey(e);
        if (key == null) return true;
        // control keys
        // null, backspace, tab, carriage return, escape
        if ( key==0 || key==8 || key==9 || key==13 || key==27 )
           return true;
        // get character
        keyChar = String.fromCharCode(key);
        // check valid characters
        if (validList.indexOf(keyChar) != -1)
        {
          // check for existing decimal point
          var dp = 0;
          if( (dp = obj.value.indexOf( ".")) > -1)
          {
            if( keyChar == ".")
              return false;  // only one allowed
            else
            {
              // room for more after decimal point?
              if( obj.value.length - dp <= CHAR_AFTER_DP)
                return true;
            }
          }
          else return true;
        }
        // not a valid character
        return false;
      }
    </script>

Get files of last hour in Azure Data Factory

  Case I have a Data Factory pipeline that should run each hour and collect all new files added to the data lake since the last run. What is...