Tuesday, August 14, 2018

Microsoft Common Data Service (CDS) V2 for Dynamics 365 CRM and AX - Data Integration - Advance Technical Preview

Hello World,

I consider my self lucky as I am getting to experience the new features of the Microsoft CDS V2 (spring update) releases fresh out of their oven, under technical preview for about a year now. It's quite fascinating to see how it grows into a highly capable product gradually.

Microsoft's original definition of CDS: "The Common Data Service is the Microsoft Azure-based business application platform that enables you to easily build and extend applications with their business data. The Common Data Service does the heavy lifting of bringing together your data from across the Dynamics 365 family of services so you can focus on building and delivering the apps, insights and process automation that matter to you and your customers with PowerApps, Power BI, and Microsoft Flow."

Now this post is about the data integration between Dynamics 365 (CRM) and Dynamics 365 Finance and Operations (AX) using CDS, as it work for bringing the Dynamics 365 family together. 

The Data Integration feature is currently available as a tab in the PowerApps Admin Center. Microsoft uses a feature flag to enable Data Integration for technical preview. So we go as, https://preview.admin.powerapps.com/environments?feature.showDataIntegration=true

The basic setup for integration is as below diagram,



Prerequisites to use CDS for Data Integration
  • Microsoft Dynamics 365 for Finance and Operations (AX), Enterprise edition July 2017 update with Platform update 8 (App 7.2.11792.56024 w/ Platform 7.0.4565.16212). Support for App 7.1 will be added with a hotfix. Or,
  • Dynamics 365 Sales, Enterprise Edition (CRM). The integration solution is compatible with Microsoft Dynamics 365 Customer Engagement Version 1612 (8.2.1.207) (DB 8.2.1.207) online.

And, you must also have:

An environment in the Common Data Service. The environment must have a database for integration and you must be an environment administrator for that database. 

First thing to setup are the Connections. For that you have to setup Connections for both source and target environments using normal power apps connection tab.



Then go to the PowerApps Admin Center and create the Connection Set by giving Source and Target Environment Connections.



Okay now all done to Create a project. Here you can select any template Microsoft has already published with complete data mappings, or you can create your own Custom Template.



For now Microsoft Templates are available for CRM and AX Sales, FSA and PSA Combinations and I have witnessed it growing for the past few months.

Sales Integration Map

To use Microsoft Templates for Sales, you have to add Prospect to Cash Integration Solution (Which is very bulky) into your Dynamics 365 environment. Yet it's not required if you know how to manage data integration with keys. Therefore I went with my custom maps with small configuration changes in CRM side (like just adding a ContactNumber field in CRM to map with AX Contact Number).

FSA Integration Map

PSA Integration Map

Good Documentation of the Data mapping between Dynamics 365 and Dynamics 365 Finance and Operations can be found in https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/data-entities/data-integration-cds?toc=/fin-and-ops/toc.json

Now with the showDataIntegration=true, feature flag the new feature available is the Advance Query option.


In the Advance Query View you get freedom to use Power Query Language ( M Language) and apply various Filters and Queries for Source Data (Working on this Advance Query section kind of feels like old SSIS, if you know what I mean :) ). Reference to Power Query can be found in https://msdn.microsoft.com/en-us/query-bi/m/power-query-m-reference

There's more to tell about advance querying. Next post for sure.

Thanks for reading, if you came this long. :)

Wednesday, July 4, 2018

Dynamics 365 (CRM) Get Primary Field name and Primary Id field name of an given entity



Hello World,

When you get to a scenario where you are writing a generic logic to be shared in few plugin steps and you are not sure about the entity you will get to process, but you need to know the schema names of primary field and id of the given entity. So pathetic right :)

Here is my solution. Use metadata.

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;


//Create RetrieveEntityRequest
  RetrieveEntityRequest retrievesEntityRequest = new RetrieveEntityRequest
    {
         EntityFilters = EntityFilters.Entity,
         LogicalName = primaryEntityName
    };

//Execute Request
  RetrieveEntityResponse retrieveEntityResponse = (RetrieveEntityResponse) service.Execute(retrievesEntityRequest);
  var idFieldName = retrieveEntityResponse.EntityMetadata.PrimaryIdAttribute;

  var primaryFieldName = retrieveEntityResponse.EntityMetadata.PrimaryNameAttribute;



Need to discuss about getting entity relationships too. Next post for sure.

Monday, May 7, 2018

Set up and initialize Firebase for Cloud Functions

Hello World,

Serverless Computing is setting it's way up for about 2 years now. Now we have Azure Functions, AWS Lambda and Google Cloud Functions.

This post is on simple steps to create Google Cloud Function setup.

Cloud functions is a serverless provided by Google Firebase. Developers can upload their back-end code in functions to the cloud and the cloud automatically executes the corresponding logic based on event triggers and HTTP requests.

For more details you can refer https://firebase.google.com/docs/functions/get-started

We will create two functions here as,
                addMessage()
                makeUppercase()

1.  Install Node.js. Firebase CLI requires Node.js and npm.

2.  Install the Firebase CLI using Node Command Prompt in admin mode.
     "npm install -g firebase-tools"

3.  Authenticate the firebase tool
             Run "firebase login"

4.  Go to https://console.firebase.google.com/ an create your project there. Go to your Firebase                 project directory.
             Run "firebase init functions"

5.  Select the firebase project or create a new one. Install dependencies with npm if needed.

6.  Select the language.

After these commands complete successfully, your project structure looks like this:


myproject
+- .firebaserc # Hidden file that helps you quickly switch between
| # projects with `firebase use`
|
+- firebase.json # Describes properties for your project
|
+- functions/ # Directory containing all your functions code
|
+- .eslintrc.json # Optional file containing rules for JavaScript linting.
|
+- package.json # npm package file describing your Cloud Functions code
|
+- index.js # main source file for your Cloud Functions code
|
+- node_modules/ # directory where your dependencies (declared in # package.json) are installed


7. Open the index.js file and add your functions


For the addMessage() function, add these lines to index.js:

// Take the text parameter passed to this HTTP endpoint and insert it into the // Realtime Database under the path /messages/:pushId/original exports.addMessage = functions.https.onRequest((req, res) => {   // Grab the text parameter.   const original = req.query.text;   // Push the new message into the Realtime Database using the Firebase Admin SDK.   return admin.database().ref('/messages').push({original: original}).then((snapshot) => {     // Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.     return res.redirect(303, snapshot.ref.toString());   }); });
For the makeUppercase() function, add these lines to index.js:
// Listens for new messages added to /messages/:pushId/original and creates an // uppercase version of the message to /messages/:pushId/uppercase exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')     .onCreate((snapshot, context) => {       // Grab the current value of what was written to the Realtime Database.       const original = snapshot.val();       console.log('Uppercasing', context.params.pushId, original);       const uppercase = original.toUpperCase();       // You must return a Promise when performing asynchronous tasks inside a Functions such as       // writing to the Firebase Realtime Database.       // Setting an "uppercase" sibling in the Realtime Database returns a Promise.       return snapshot.ref.parent.child('uppercase').set(uppercase);     });


8.  Run this command to deploy your functions: 

          "firebase deploy --only functions"



9.   Now go and check your https://console.firebase.google.com/ project you will see the functions  available there. Use the URL provided by CLI which will be available in firebase console function as well. It will be similar to below with your project name in it.
https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
10. Now use this url in a browser and you will be navigated to firebase database where you can see the funtion results.


Windows PowerShell to deploy packages Dynamics 365 V9


Hello Troubled World,

I used Powershell to deploy some configuration data along with solutions into Dynamics 365 following https://msdn.microsoft.com/en-us/library/dn688182.aspx. It worked well for V8.2 and bellow.

Then with the V9 update I followed https://technet.microsoft.com/en-us/library/dn647420.aspx instructions and yet came across in below error w
hen running the RegisterXRMPackageDeployment.ps1 in powershell 3.0 as administrator, I get "Cannot verify the Microsoft .NET Framework version 4.5.2 because it is not included in the list of permitted versions" message and it continued exporting cmdlets.

The reason is Dynamics 365 V9 requires the .NET Framework 4.5.2 and we have to use TLS12 Security Protocol to use powershell in .net 4.5.2. 
When accessing services authenticated via AAD (Azure Active Directory) it  requires TLS 1.2 protocol. Somehow power-shell doesn't get the machine's setup for TLS 1.2 and hence we have to manually give the configurations.

by adding below line before accessing CRM will provide the required permissions.

[System.Net.ServicePointManager]::SecurityProtocol = 
[System.Net.SecurityProtocolType]::Tls12

eg:

Add-PSSnapin Microsoft.Xrm.Tooling.Connector
Add-PSSnapin Microsoft.Xrm.Tooling.PackageDeployment 
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
$CRMConn = Get-CrmConnection -InteractiveMode
Import-CrmPackage -CrmConnection $CRMConn -PackageDirectory D:\test\ -PackageName testPkg.dll -Timeout 1:00:00:00 -Verbose





Thursday, February 26, 2015

Backup a dll saved to database in the Plugin Registration Tool for Microsoft CRM 2011


Hello World,

When an assembly in the Plugin Registration Tool that is saved to the database to take a backup of it has to be done through CRM.

Have to export it as a solution:

1)      Create a new solution named 'Plugin Backup' or something (Settings->Solutions->New)
2)      Add the plugin (Plugin Assemblies -> Add Existing)
3)      Export the solution as an Unmanaged solution (Export Solution)
This will create a solution zip that contains your dll, which you can then re-import using 'Import Solution' if you need to restore to a previous version.


This is for CRM 2011 On-Premise

Monday, December 8, 2014

Get list of Entities in CRM query by Display Name (CRM bulk update)

Hello World,


MetadataSchema.Entity does not have the Display Name of the Entity in it. To get Display Name of a Entity we have to use MetadataSchema.LocalizedLabel
In the bellow query I get the all Entities where Entity Display Name starts from 'Z'.

select distinct e.Name, e.LogicalName, e.OriginalLocalizedName, OptionSetValue.Label
from MetadataSchema.Entity as e inner join
MetadataSchema.LocalizedLabel as OptionSetValue on (e.EntityId = OptionSetValue.ObjectId and
OptionSetValue.ObjectColumnName = 'LocalizedName')
where OptionSetValue.Label like 'Z%'
order by OptionSetValue.Label

With this we can easily get a list of entities and can do other necessary implementations in bulk. 


For example this is a good input to the query in below link,
http://matheeid.blogspot.com/2014/12/bulk-hide-entities-from-advance-find-in.html


Bulk Hide Entities from Advance Find in MS Dynamics CRM


Hello World,

If you are in trouble with unnecessary Entities in your Advance Find (that you created while ago and no longer needed) but you don't want to remove them. And you want to hide them from your customers. And you are too lazy and you want one query that works for all. :)
I was that lazy.

EntityMetadata.IsValidForAdvancedFind Property 

     - Gets or sets whether the entity will be shown in Advanced Find

if IsValidForAdvancedFind = 1 
then referring entity will be shown in Advance Find.


Therefore to hide a entity from Advance Find we can write - 

         update MetadataSchema.Entity
         set IsValidForAdvancedFind = 0
         where  Name = 'EntityName' 

Above will hide the contact  entity for all users  on the advanced.


Then to hide the Entity been displayed under related Entities we can write,

update MetadataSchema.Relationship 
set IsValidForAdvancedFind = 0
where ReferencingEntityId = (select MetadataSchema.Entity.EntityId 
    from MetadataSchema.Entity 
    where Name = 'EntityName') and IsValidForAdvancedFind  = 1)


If you have multiple Entities to update you can easily change the '=' to 'IN' and write all the Entities as a array.

update MetadataSchema.Entity 
set IsValidForAdvancedFind = 0 
where Name IN ('EntityName1', 'EntityName2', ......)


Hope this would be useful
Mathee