Archive

Archive for the ‘Uncategorized’ Category

CRM Record “Email a Link” feature not working

February 8, 2017 Leave a comment

Recently few of our CRM users complained OOB “Email a Link” not working.

email-link

Reason:

  • Machines default “Email” App was set to “Chrome”

email-settings

Fix:

  • Change default “Email” App to “Mail” or “Outlook” client

 

email-settings-set-to-mail-client

🙂

Categories: CRM, Uncategorized Tags: , ,

New field ‘Sort Date’ in Activity Pointer entity – Dynamics 365

January 26, 2017 Leave a comment

A new field ‘Sort Date’ (Schema Name – sortdate) has been added to the ‘Activity Pointer’ entity to control the sorting of the Activities.

sort-date-activities

Limitation with earlier CRM versions:

  • To display a list of activities and order them by date, we can only use the common date attributes like ‘Created on’ or ‘Modified on’ defined in the activitypointer entity.
  • What if you have to sort Email activities by ‘Sent On’ attribute rather than the modifiedon attribute value?

How ‘Sort Date’ Solves This:

  • With ‘Sort Date’ attribute, we can control how activities are sorted by desired date.
  • By default, the ‘Sort Date’ attribute value is null.
  • Set the ‘Sort date’ attribute value using a workflow or a plugin with required Date value (For example, set ‘Sort Date’ with ‘Sent On’ value in case of Emails) and use that in views.

🙂

Create a child record by copying mapping fields data from Parent – Using CRM SDK

January 26, 2017 Leave a comment

Let’s take the OOB Account and Contact related entities.

Whenever we click ‘Add New Contact’ button from the ‘Associated view’ of ‘Account’ form, all the mapping fields data would be copied to ‘New Contact’ form.

Account:

account-form

New Contact Form:

create-contact

This is native CRM behavior, to copy the content from Parent to Child record, using the Relationship ‘Mappings’ to avoid the overhead of manual data entry on child record.

account-and-contact-mappings

What If we have to create a Contact from a console application using CRM SDK and achieve the same behavior?  ‘InitializeFromRequest’ is the answer.

Steps to use ‘InitializeFromRequest’:

  • Instantiate the ‘InitializeFromRequest’
  • Set the Target as ‘Contact’
  • Set the ‘EntityMoniker’ as the reference of parent ‘Account’ which you would want to copy the data from
  • Execute the ‘InitializeFromRequest’
  • From the ‘InitializeFromResponse’, read the Contact object with copied data from Account (**Contact would not be created in CRM at this point**)
  • Fill the other attributes
  • Create the Contact

Source Code:

InitializeFromRequest initialize = new InitializeFromRequest();

// Set the target entity (i.e.,Contact)
initialize.TargetEntityName = “contact”;

// Create the EntityMoniker of Source (i.e.,Account)
initialize.EntityMoniker = new EntityReference(“account”, new Guid(“D4CBEE74-B5E3-E611-8109-C4346BDD8041”));

// Execute the request
InitializeFromResponse initialized = (InitializeFromResponse)orgService.Execute(initialize);

// Read Intitialized entity (i.e.,Contact with copied attributes from Account)
if (initialized.Entity != null)
{
// Get entContact from the response
Entity entContact = initialized.Entity;

// Set the additional attributes of the Contact
entContact.Attributes.Add(“firstname”, “Rajeev”);
entContact.Attributes.Add(“lastname”, “Pentyala”);

// Create a new contact
orgService.Create(entContact);
}

If you put the debugger and watch the ‘initialized.Entity’ you would see the populated fields.

initialized-entity-contact

Post execution of this code, a new Contact would get created with copied data from Account.

contact-form

🙂

Switch Business Process Flow using Jscript based on CRM form’s field value

April 30, 2016 1 comment

Recently we got a requirement to switch the Business process on Case form based on ‘Case Origin’.

Its easily achievable using Jscript “setActiveProcess” method.

Xrm.Page.data.process.setActiveProcess(processId, callbackFunction);

  • processId‘ is the GUID of the ‘Business Process Flow’. You can copy the GUID from URL.
  • Go to ‘Settings –> Processes’ open the ‘Business Process Flow’ and copy the value from ‘id’ parameter, between %7b %7d
Copy Business Process ID

Copy Business Process ID

  • ‘callbackFunction’ is your custom JScript function name which gets triggered post ‘Business Process’ switch.

Below are the scenario and steps.

  • I have 3 Active Business Process Flows on my ‘Case’ entity.
Active Business Process Flows

Active Business Process Flows

  • ‘Business Process Flows’ are Security Role Based, so if my user has access to all 3 ‘Business Process Flows’, he can switch the process using ‘Switch Process’option.
Swicth Business Process

Swicth Business Process

Multiple Business Process Flows

Multiple Business Process Flows

  • In my scenario, ’Switch Process’ should happen based on ‘Case Origin’ field.
    • If ‘Case Origin’= Phone; Set “Business Process1”
    • If ‘Case Origin’= Email; Set “Business Process2”
  • Below is the script

function onload() {
// If not new Case form
if (Xrm.Page.ui.getFormType() != 1) {
// Read Origin Option text
var origin = Xrm.Page.data.entity.attributes.get(“caseorigincode”);

if (origin && origin.getText()) {
var caseOrigin = origin.getText();

// Get Business process flow id
var processFlow1Id = “6CD44946-0DC5-47E3-9B62-6D7309254710”;
var processFlow2Id = “0B3A94CD-CD43-4F49-A9A3-93C4AC684CFA”;

// Get Current Active Process Id
var activeProcess = Xrm.Page.data.process.getActiveProcess();
var currProcessId = activeProcess.getId();

if (caseOrigin.toLowerCase() == “phone”) {
// Change the process only if current Active Process not the Target one
if (currProcessId.toLowerCase() != processFlow1Id.toLowerCase()) {
// Switch to the “Process Flow 1”
Xrm.Page.data.process.setActiveProcess(processFlow1Id, myCallBack);
}
} else if (caseOrigin.toLowerCase() == “email”) {
// Change the process only if current Active Process not the Target one
if (currProcessId.toLowerCase() != processFlow2Id.toLowerCase()) {
// Switch to the “Process Flow 2”
Xrm.Page.data.process.setActiveProcess(processFlow2Id, myCallBack);
}
}
}
}
}

// Call back function post Process flow switch
function myCallBack(response) {
if (response == “success”) {
alert(“BPF changed !!!”);
// Save the form
Xrm.Page.data.entity.save();
}
else {
alert(“Error changing BPF!!!”);
}
}

How do I use the script?

  • Copy the script and create a new ‘Web resource’ in CRM and add to ‘Case’ form.
  • Register ‘onload()’ function on form onload event.
Register onload event - Case form

Register onload event – Case form

  • Publish the Customizations.
  • Open the Case record and based on ‘Case origin’ system auto switches to the Business process Flow.
New Business Process Selected

New Business Process Selected

Key points on multiple ‘Business process flows’:

  • You can have up to 10 active business process flows per entity.
  • You can associate business process flows with security roles so that only people with those security roles can see or use them.
  • In case of multiple Active ‘Business process flows’, the first activated business process flow in that list is the one that will be applied by default.
  • Each record can have only one business process flow at a time.
  • If someone’s security roles do not allow them to use a specific business process flow, the current business process flow will be visible, but disabled.

🙂

Host a SSRS report which gets data from external Data Source – CRM on-premise

January 7, 2016 3 comments

We got a requirement to host a SSRS report in CRM, which gets data from external data source (i.e., Data Base from another SQL server).

CRM normally uses Shared Data Source when you upload any SSRS report which pulls data from CRM.

In our case we had to

  • Create a new Data Source
  • Override the CRM Shared Data Source with a new Data Source

Below are the steps.

Develop and Deploy Report in CRM

  • Design the report with Data Source connected to external Database.
  • Preview and make sure you are getting data properly.
  • Save the .rdl
  • Open CRM application
  • Create a new report and upload the .rdl
Upload SSRS Report To CRM

Upload SSRS Report To CRM

Configure the Report’s DB Connection

Now we got report in CRM and we need to point the report to Custom DataBase by following steps below

  • Connect to the SSRS server
  • Open the browser and type (http://servername/Reports) (You can also get URL from “Reporting Services Configuration Manager à Report Manager URL” tab)
Reporting Service Config Manager

Reporting Service Config Manager

  • In the Home page, click on ‘New Data Source’
Create New Data Source - 1

Create New Data Source – 1

  • Provide the Connection String and Credentials and Save
Create New Data Source - 2

Create New Data Source – 2

  • Go back to the report server home page.
  • Open the folder by name (YourCRMORG_MSCRM)
  • Go to ‘CustomeReports’ folder and select your report (Refer ‘Description’ column for Report Name)
  • Choose Manage from context menu
Create New Data Source - 3

Create New Data Source – 3

  • Choose ‘Data Sources’ tab and select newly created ‘Data Source’
Select the Data Source

Select the Data Source

  • Click on ‘Apply’
  • Close and re-run the report to get the changes.

🙂

2014 in review

December 30, 2014 Leave a comment

The WordPress.com stats helper monkeys prepared a 2014 annual report for this blog.

Here’s an excerpt:

The Louvre Museum has 8.5 million visitors per year. This blog was viewed about 170,000 times in 2014. If it were an exhibit at the Louvre Museum, it would take about 7 days for that many people to see it.

Click here to see the complete report.

Categories: Uncategorized

Custom Help Pages – CRM 2015

December 10, 2014 Leave a comment

Before CRM 2015 to get custom help pages, the only way is running unsupported PowerShell commands.

With CRM 2015, CRM administrators can configure Custom help pages for entire organization or for specific customizable entities.

Organization Level Custom Help

  • Go Settings -> Administration -> System Settings
  • Provide URL of the web page you want to configure as below
Custom Help - System Settings

Custom Help – System Settings

  • Append Parameters to URL
    • By enabling this, in the opened Help page along with URL you get below parameters
      • entrypoint – Valid values include form, hierarchychart, and formid. The formid parameter refers to the GUID of the form or hierarchy chart that help was opened from.
      • typename – schema name of the entities form where Help opened (Only available when you open Help from entity form)
      • userlcid – Logged in users language code.
Help Button - Account Form

Help Button – Account Form

Help Page with Parameters

Help Page with Parameters

Entity Level Custom Help

  • We can configure individual help pages for customizable entities.
Custom Help - Entity Level

Custom Help – Entity Level

Note

  • If custom help is turned off, the default help content will be displayed
  • Custom Help is not available currently for Tablet

Refer this video from CRM Team.

🙂

Categories: Uncategorized Tags: ,

The security timestamp is invalid because its creation time is in the future – Error CRM

September 24, 2014 Leave a comment

I was getting below exception when I try to create records from my console application using CRM Organization Service.

The security timestamp is invalid because its creation time (2014-09-24T08:51:00.583Z) is in the future. Current time is 2014-09-24T08:45:58.432Z and allowed clock skew is 00:05:00].

Reason :

  • There was difference in Time settings between CRM Front end server and CRM DB Server.

Fix :

  • In our case CRM Front end server and CRM DB Server time zones were different.
  • Also sometimes check if the “Windows Time” service is running on machines. (To check go to Run -> Services.msc)
  • FYI, “Windows Time” service maintains date and time synchronization on all client and servers on the network.

Same scenario would sometimes cause below exception too

Message security verification failed

🙂

Reflection with method overloading C#

July 16, 2014 1 comment

I have a class with 3 overloaded methods and when try to invoke method’s using Reflection, I was gettingAvoiding an ambiguous match exception” exception.

Below is the way to invoke overload methods using Reflection, which solved my exception.

Let’s take a class with 3 overload methods.

Class Structure

namespace MyNamespace{

public class CallMe{

public string MyName(){

return “You don’t have name”;

}

public string MyName(string firstName){

return “Your name is ” + firstName;

}

public string MyName(string firstName, string lastName){

return “Your name is ” + firstName + lastName;

}

}

Here is the way to invoke methods using Reflection

C# Code to call the Generic Method

// Load .dll

Assembly assembly = Assembly.LoadFile(“{Physical path of }MyNamespace.dll”);

// Set the Class type as “Namespace.Classname”

Type classType = assembly.GetType(“ReflectionClass.CallMe”);

// One of my methods expects 1 string hence creating MethodInfo object with 1 Type[] parameter

MethodInfo methodWithOneParameter = classType.GetMethod(“MyName”, new Type[] { typeof(string) });

// One of my methods expect 2 string parameters hence creating MethodInfo object with 2 Type[] parameters.

MethodInfo methodWithTwoParameter = classType.GetMethod(“MyName”, new Type[] { typeof(string), typeof(string) });

// To invoke overload with no parameters, provide an empty Type array to GetMethod’s second parameter

MethodInfo methodWithNoParameter = classType.GetMethod(“MyName”, new Type[0]);

// Invoke Methods

var resultMethodWithOneParameter = InvokeMethod(classType, methodWithOneParameter, new string[] { “Rajeev” });

var resultMethodWithTwoParameter = InvokeMethod(classType, methodWithTwoParameter, new string[] { “Rajeev”, “Pentyala” });

var resultMethodWithNoParameter = InvokeMethod(classType, methodWithNoParameter, null);

//  Display Results

Console.WriteLine(“ResultMethodWithOneParameter – ” + resultMethodWithOneParameter.ToString());

Console.WriteLine(“ResultMethodWithTwoParameter – ” + resultMethodWithTwoParameter.ToString());

Console.WriteLine(“ResultMethodWithNoParameter – ” + resultMethodWithNoParameter.ToString());

 C# Generic Method to Invoke methods

       // Generic method Invokes methods and return Result as Object

public static object InvokeMethod(Type classType, MethodInfo methodInfo, object[] parametersArray){

object result = null;

if (classType != null) {

if (methodInfo != null) {

ParameterInfo[] parameters = methodInfo.GetParameters();

object classInstance = Activator.CreateInstance(classType, null);

if (parameters.Length == 0) {

//This works fine

result = methodInfo.Invoke(classInstance, null);

}

else {

//The invoke does NOT work it throws “Object does not match target type”

result = methodInfo.Invoke(classInstance, parametersArray);

}

}

}

return result;

}

We get the response as below

Reflection Overload Result

Reflection Overload Result

🙂

Plug-in on related entities during ‘Cascade All’ actions

Assume the relationship behavior between ‘Contact’ and ‘Appointment’ is “Cascade All” on ‘Assign’ action.

Relationship Behavior

Relationship Behavior – Assign – Cascade All

By virtue of that, if a Contact has 2 Appointments, if I change the owner of ‘Contact’ the related 2 Appointment owner also changes.

In one of the requirement, we have to restrict the Cascade operation based on business logic on child record (i.e.,  Appointment)

So I registered a Plugin on ‘Assign’ of ‘Appointment’ and want to handle the Cascade operation, but the Plugin never get executed.

Reason & Solution

  • CRM treats Cascade Assign operation on Child records as an Update.
  • Register the Plug-in on ‘Update’ instead of ‘Assign’ message.
  • In the Update plug-in, the Target entity only contain ‘Owner’ field

🙂