DataMigration: KingswaySoft – ScriptComponent (Generate new guid)

I had a requirement where I need to generate a new unique id every time when a new record is inserted into the system. In such cases Script Component is very useful.

We can find Script Component under SSIS toolbox.

Now, going to Script Transformation Editor there we need to create a new column where we can create and store the newly generated ID.

Step 1: Click on Inputs and Outputs
Step 2: Click on Add Columns
Step 3: Name the column
Step 4: Select the required data type.

Figure 1: Script Component Editor (Create new column)

Select the datatype as GUID for generating unique ID.

Next, we need to go to Script and hit Edit Script.. button.

Figure 2: Edit Script for writing custom code

This will open a project where we need to write a line of code for generating new GUID.

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
Row.UniqueID = System.Guid.NewGuid();
}

Code for generating new GUID

Go to Input0_ProcessInputRow(Input0Buffer Row) method, under that write a line of code for generation of GUID.

Row.UniqueID = System.Guid.NewGuid();

That’s all we need to do for creating a new GUID, when a record is inserted into the destination system.

Hope this helps you!

DataMigration: KingswaySoft – Optionset Mapping

KingswaySoft provide us a Dynamics CRM OptionSet Mapping component under Common tab which lies inside SSIS toolbox. This component ease the data migration activity.

Figure 1: Optionset Mapping component

In my case, I haven’t used the Dynamics CRM OptionSet Mapping component. Reason the optionset mapping component didn’t populated the attributes which were of int type under Input Column field.

Figure 2: Optionset Mapping Input Column

Therefore we need to used Data Conversion and Derived Column components.

Assuming, Role is the name of option set attribute. So, under Data Conversion transformation editor we need to change the data type from int to string.

Select the Role attribute under Input Column, system will auto populate Copy of attribute name. In our case it will be “Copy of Role”, select the data type as Unicode string[DT_WSTR] and provide the length of the field as per your requirement. This Data Conversion transformation editor can be used for any attribute data type conversion.

Figure 3: Attributes Data type conversion.

Now, coming to Derived Column component. Here we need to create an expression for mapping the optionset label and value.

Figure 4: Mapping Optionset Label and Value

Expression used for OptionSet Mapping, if any of the option value is not found while data transmission then the system would enter “Not Found”.

 Role == 954660008 ? "Participating Person" : Role == 954660004 ? "Overlay Sales" : Role == 954660000 ? "Account Manager" : Role == 954660001 ? "Sales Reporting Manager" : Role == 954660002 ? "Vertical Head" : Role == 954660003 ? "Geo Head" : Role == 954660005 ? "Co-Owners" : Role == 954660006 ? "Service Offering Lead" : Role == 954660007 ? "Horizontal Head" : "Not Found"

There are multiple expression under Derived Column component which are very use full and can be used as needed such as Mathematical Function(like LOG, ROUND, SQUARE etc), String Function (like TRIM, LTRIM, RTRIM, REVERSE, REPLACE, UPPER, LOWER etc), Date/Time Functions (like DAY, MONTH, YEAR, DATEDIFF etc), NULL Functions(like REPLACE NULL, etc), Type Casts, Operators(like ADD, SUBTRACT, MULTIPLY, DIVIDE etc.)

Hope this post helps you!

Data Migration using KingswaySoft

KingswaySoft is a tool which helps us in data migration activity.

Why Choose KingswaySoft for data migration?

User friendly UI: KingswaySoft has a very nice and easy to understand user interface. As, I was totally new with KingswaySoft tool. The UI really helped me during the data migration process as I need not struggled much by navigating here and there for searching an option.

Establishing connection between two difference system was pretty easy using connection managers. Not even a single line of code was required. If you have worked before on SSIS then KingswaySoft would be very simple.

Let jump to the scenario where I used Kingswaysoft tool.

I had to migrate date from Microsoft Dynamics 365 to Third Party application SQL(OLE DB Destination) database. In our case CRM was acting as an up stream system.

Figure 1: Data flow diagram.

Attached is the data flow diagram.

We will not go into very basic like how to establish connections using Connection Managers.

Figure 2: Screenshot of Dynamics CRM Source

Build a fetchxml with the required data/columns which needs to be inserted in the destination system. For me to push the desired data in destination I need to use source type as FetchXML.

Use of Data Conversion: This is used for conversion of an attribute data type like if the source system has an attribute of int type and the destination have the same attribute column in nvarchar datatype.

Use of Derived Column: This is where we can use multiple expression on our columns and populated the values in the destination table columns.

Expression which we can use are like:

Mathematical Functions, String Functions, Date/Time Functions, NULL Functions, Type Casts and Operators.

For attribute which are of option set type I needed to convert the int values into string format because the destination table column was of string type. Therefore I used Data Conversion.

Use of Script Component: This was used by me for creating unique id. When a new row gets inserted into destination table then generate a unique guid for each row..

OLE DB Destination: This is where we establish the connection with the destination system database. Mapping the Source System columns with Destination System columns.

Calling Namespace Javascript function in Dynamics CRM

I still see many people have some issue in understanding/calling namespace Javascript function.

Below pattern is a simple way of writing a Javascript in Dyanmics CRM, which most of the people are familiar with:

function MessagePopUp(executionContext)
{
 var formContext = executionContext.getFormContext();
 var email = formContext.getAttribute('emailaddress1').getValue(); 
 alert('Welcome mail sent to ' + email); 
}

Now, the namespace format, which is recommended by Microsoft. To avoid conflict within the functions name.

var Namespace = window.Namespace || {};
(
 function (){
 this.formOnLoad = function(executionContext)
{
 var formContext = executionContext.getFormContext();
 var email = formContext.getAttribute('emailaddress1').getValue();
 alert('Welcome mail sent to ' + email);
}
}
).call(Namespace);

In the above code we have declared the variable as “Namespace”. The same should be called at the end of the function as .call(Namespace).

this.functionName = function(executionContext) /* In namespace notation javascript function should be called using this keyword, */

For calling a above namespace notation javascript, we need to call it as Namespace.formOnLoad on the event handler.

Figure 1: For calling formOnLoad function we need to use Namespace.formOnLoad
Figure 2: Screenshot from Event Handlers

Save and Publish the code.

Refreshing the contact entity page and we will get the message pop-up on form onload.

Figure 3: Message Pop-Up

Hope this blog help in understanding Namespace Notation Javascript!!

Plugin Development: Retrieve data using images

Images are useful for data comparison before and after core operation. We can register plugins on two type of images:

  • Pre-Image
  • Post-Image

Pre-Image can be used for retrieving the value of an entity attribute before core operation takes place.
Post-Image can be used for retrieving the value of an entity attribute after the core operation has taken place.

Scenario: On contact entity we have email address field. Let’s stop users from updating the email address field by showing them the old and new values.

using System;
using Microsoft.Xrm.Sdk;

namespace HelloPlugin
{
public class PreImagePlugin: IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// Get a reference to the Organization service.
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = (Entity)context.InputParameters["Target"];

try
{
//Implement Plugin Business Logic here
string newemailaddress = string.Empty;

if (entity.Attributes.Contains("emailaddress1"))
{
newemailaddress = entity.Attributes["emailaddress1"].ToString();
}

Entity preImageContact = (Entity)context.PreEntityImages["PreImage"]; //PreImage is user defined name you can name anything.

string oldemailaddr = preImageContact.Attributes["emailaddress1"].ToString(); //preImageContact will provide us the value which was saved before the update event.

throw new InvalidPluginExecutionException("The email address is modified from " + oldemailaddr + " to " + newemailaddress);
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message);
}
}
}
}
}

Below is the screenshot of the exception message thrown by our plugin:

Figure 1: Populating email address using pre-image

Plugin Development: Duplicate Check

Today we will learn how to restrict users from entering duplicate value in MS Dynamics CRM.

Let’s take as an example of Contact entity where we need to restrict users from entering duplicate email address which is already present in CRM while creating or updating a contact record.

I know there would a thought in your mind why don’t we use Duplicate Detection rule instead of plugin. So the answer to this question is duplicate detection rule will give user a warning message about the presence of duplicate record but still user will have the ability to ignore the warning message and save the record. Therefore, plugin is required for restricting users from entering duplicate records.

Note*: Below are the different techniques using which we can retrieve records. In this plugin we will be using Query Expression.

  • Fetch XML
  • Using Retrieve
  • Query Expression
  • Query By Attribute
  • LINQ
using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace HelloPlugin
{
public class DuplicateCheck: IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// Get a reference to the Organization service.
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
//Obtain the target entity from the input parameter
Entity contact = (Entity)context.InputParameters["Target"];

try
{
//Implement Plugin Business Logic here
string email = string.Empty; //Variable declared to check whether emailaddress field is empty or not.

if (contact.Attributes.Contains("emailaddress1"))
{
email =  contact.Attributes["emailaddress1"].ToString();

QueryExpression query = new QueryExpression("contact");
query.ColumnSet = new ColumnSet(new string[] { "emailaddress1" });
query.Criteria.AddCondition("emailaddress1", ConditionOperator.Equal, email);

EntityCollection collection = service.RetrieveMultiple(query);

if (collection.Entities.Count > 0)  //Check if any record is present with duplicate email address
{
   throw new InvalidPluginExecutionException("Contact with email   already exist");
}
}
}
catch (Exception ex)
{
   throw new InvalidPluginExecutionException(ex.Message);
}
}
}
}
}

Points to Remember for registering the plugin. Add two steps one for create contact another for update contact.

  • Message = Create and Update
  • Primary Entity = contact
  • Pipeline Event = PreValidation

Hope this helps!!

Plugin Development: Create follow up task on create of Contact.

Create a follow up Task on create of Contact. The task should be completed in 2 days from the contact created on date.

Register the Plugin on:

  • Message = Create
  • Primary Entity = contact
  • Pipeline Event = PostOperation
using System;
using Microsoft.Xrm.Sdk;

namespace HelloPlugin
{ 
public class CreateTask: IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// Get a reference to the Organization service.
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
//Obtain the target entity from the input parameter
Entity contact = (Entity)context.InputParameters["Target"];
try{
//Implement Plugin Business Logic inside try block
Entity taskRecord = new Entity("task");   //Creating object taskRecord of task entity.

//Single line of text(String fields)Append Follow Up on Task entity Subject field 
taskRecord.Attributes.Add("subject", "Follow Up"); 
//Append Need to follow up with contact statement on Task entity description field 
taskRecord.Attributes.Add("description", "Need to follow up with contact");   

//Set value in Date field
taskRecord.Attributes.Add("scheduledend", DateTime.Now.AddDays(2));  //Added 2 days from the Contact creation date.

//Set value in Optionset field (use Optionset value not lable) 
taskRecord.Attributes.Add("prioritycode", new OptionSetValue(2));  

//Set Parent Record to Task record.
//taskRecord.Attributes.Add("regardingobjectid", new EntityReference("contact", contact.Id)); //Old Methodology

taskRecord.Attributes.Add("regardingobjectid", contact.ToEntityReference());//New Methodology -- Link to Contact Record.

//Create a task record
Guid taskGuid = service.Create(taskRecord);
}

catch (Exception ex)
{
   throw new InvalidPluginExecutionException(ex.Message);
}
}
}
}
}
Figure 1: On create of Contact, follow up task got automatically created.

Security Role Issue with OfficeGraphDocument entity

Today I went through an issue where I had a custom security role (Business Admin) having almost the same privilege as system admin user expect the update permission on custom master entities.

Issue: When user having Business Admin role was trying to assign security roles to other users then suddenly a message popped up on screen as permission issue.

RoleService::VerifyCallerPrivileges failed. User: a52a0940-6fde-e811-a96a-000d3af05828, PrivilegeName: prvReadOfficeGraphDocument, PrivilegeId: 39016011-ae1a-41d1-9a22-a2611ad16702, Depth: Global, BusinessUnitId: be4a982d-8cd0-e811-a964-000d3af05df5 If you contact support, please provide the technical details.

Reading the above message it is clearly state that read privilege needs to be provided on OfficeGraphDocument entity. But The entity is not visible on the security role form therefore the system admin user cannot go ahead and provide the permission

While investigating on the issue I found that Office Graph integration for Dynamics 365 for Customer Engagement apps was deprecated on August 31, 2017, at the same time that Office ends GQL query support. Customers can continue to use Office Graph integration through August 31, 2017. After August 31 that date, the Office Graph trending documents component will cease to function, and you’ll see the following error message:

We can’t get to the trending documents. Try again later.

Refer Microsoft site for more details: Click Here

Assuming you people are aware about XRMToolBox and establishing connection with Dynamic CRM Organization.

Resolution: Use XRMToolBox, connect the tool with the organization. Search for Role Updater plugin as shown below:

Figure 1: XRM ToolBox – Plugin Role Updater

Click on Role Updater and hit Load Roles and Privileges button. This will load all the entities and the privilege which are assigned on that entity.

Figure 2:Click Load Roles and Privileges button

Enter OfficeGraphDocument entity under Search box.

Figure 3: Enter OfficeGraphDocument

The below screen appeared with the privilege which OfficeGraphDocument entity had.

Figure 4: OfficeGraphDocument entity privilege visible (Read privilege can be set to access level as Organization or None.)

Select Read and

Step 1: Hit the organization button

Step 2: You will see that entity OfficeGraphDocument has beenprovidedOrganization level access on PrivilegeName: prvReadOfficeGraphDocument.

Step 3: Hit Next button to take effect in the connect organization.

Figure 5: Read privilege has been provided Organization level access.

Performing these steps resolved the issue.

Now, user having Business Admin security role was able to provide other users their desired security role excluding System Admin role.

Hope this blog helps anyone!!!

MS Teams integration with Dynamics CRM

MS Dynamics CRM and MS Team integration provide users the ability to pin up records/views which are most frequently used by the user.

We need to create a Team for achieving the above functionality.

Figure 1: Created Team

New team has been created now. Let’s name it as MS Dynamics and Team Integration. We need to click on (+) icon. To pin a record or view.

Figure 2: Use Plus (+) Icon to Pin Record

Search for Dynamics 365.

Figure 3: Search Dynamics 365

Click on Entity Selection –> Filter Entity for fast search (highlighted in blue) –> Enter the record name. Select the record and hit Save button.

Figure 4: Search Entity Record using filter

The selected record has been pinned on Team now.

Figure 5: Pinned Account Entity record

We need to follow the same steps to pin a View on Teams. Select the entity view and click Save button.

Figure 6: Search Account Entity View
Figure 7: Pinned Account Entity view (My Active Accounts)

When Microsoft Teams Integration is enabled, to get the Collaborate button appears on records in Dynamics 365 for Customer Engagement apps. We need to Enable Dynamics 365 and Teams Integration from System Settings.

Login to Dynamics CRM:

  • Go to Settings > Administration > System Settings > General tab
  • Enable Microsoft Teams Integration
Figure 8: Enable Microsoft Teams Integration – Collaborate button

Hope this blog help!!

MS Teams integration with Dynamics CRM

Today we will learn how to integrate Dynamics CRM with MS Teams.

Open Teams –> Go to Apps –> Search Dynamics

Figure 1: Login Team App
Figure 2: Search for Dynamics 365 App

Select the Dynamics 365 App, below screen would appear. We need to click on the Install button.

Figure 3: Install Dynamics 365 App

Select App

Figure 4: Open Dynamics 365 App

Select the CRM Environment and Dynamics 365 app for establishing connection with MS Team.

Figure 5: Select CRM Org. to configure with MS Teams
Figure 6: Selected CRM Org. Hexaware and Sales Hub App.

The below screen will appear after clicking Save Changes button.

Figure 7: CRM Dashboard in Teams

Teams provide us the ability to select CRM records and work on it having the same user experience as Dynamics CRM.

Figure 8: Access CRM record from MS Teams

Now, clicking on the Conversation tab and hit Configure button for using Teams Bot functionality.

Figure 9: Configure MS Teams Bot

Select the CRM Environment and hit Save button.

Figure 10: Select CRM Org.

Commands which can be currently used in Teams.

  • Search
  • Show
  • Change environment
  • Change App
  • Help
Figure 11: MS Teams Bot Commands

I entered show Hitachi Account.

Figure 12: Record fetch using MS Teams bot functionality

Next Session we will learn how to pin up CRM records on MS Teams. Click Here

Design a site like this with WordPress.com
Get started