Restrict users from selecting past date (Date Validation)

Let’s learn how to restrict user form selecting past date. We can do this through JavaScript.

Below we have a Lead form, where we have a Target Date field. The need is to restrict user from saving the lead form having passed data on Target date field.

Lead Form

Below is the code which can we used:

(function () { }(window.BankNotes = window.BankNotes || {}));
(function (BankNotesFilter) {
/* Function ValidateTargetDate: This would trigger on OnChange event of Target Date field. Which would restrict user from selecting past date under Target Date field.*/
BankNotesFilter.ValidateTargetDate = function (executionContext) {
var formContext = executionContext.getFormContext();
var dateFieldVal = formContext.getAttribute("blog_targetdate").getValue(); // TargetDate Field
var today = new Date();
var todaydate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0);

if (dateFieldVal < todaydate) {
formContext.getAttribute("blog_targetdate").setValue(null);
formContext.getControl("blog_targetdate").setNotification("Selected date should be greater or equal to today","101");
}
else {
formContext.getControl("blog_targetdate").clearNotification("101");
// alert("Selected Target date greater than today");
}
};
}(window.BankNotes.BankNotesFilter = window.BankNotes.BankNotesFilter || {}));

The code restrict user from selecting past date on Target Date field.
If, user select past date under Target Date field then the field value will be cleared out showing notification(“Selected date should be greater or equal to today”) on the field.

Just, we need to call the above code on OnChange event of Target Date field:

Call the Function: BankNotes.BankNotesFilter.ValidateTargetDate

The value will be cleared out, on selection of past date

When a user select today’s or any future date, system will allow user to select the date.

User able to select any future/current date.

Hope this helps!

Filter LookUp: Set Regarding Lookup Entities

Let’s learn how to set entities under lookup field.

Let’s take an example of Regarding lookup of Task activity.

In the below image we can see that the regarding lookup contains multiple entities associated with it where a user can go and select any entity records.

Task Entity: Regarding lookup

To restrict “Regarding” lookup entities, we can use java script which would help us in populating only the needed entities.

(function () { }(window.LearningRefresh = window.LearningRefresh || {}));
(function (LearningRefreshFilter) {
LearningRefreshFilter.FilterRegarding = function (executionContext) {
var formContext = executionContext.getFormContext();
formContext.getControl("regardingobjectid").setEntityTypes(["contact", "incident", "account"]); //Regarding Lookup Field
};
}(window.LearningRefresh.LearningRefreshFilter = window.LearningRefresh.LearningRefreshFilter || {}));

We will need to call the java script “OnLoad” event of the Task activity main form.

The calling function should be LearningRefresh.LearningRefreshFilter.FilterRegarding

Save and Publish the changes.

Filter Regarding Lookup

Hope this helps!

LEARNING POWER AUTOMATE – Handle Flow Trigger

As we all know that Microsoft Flow is also known as Power Automate.

So, it has some limitations as well. Like Request limit, Flow limits, etc. to know more about Limits and configuration in Power Automate,, click here.

Another important point about power automate is that it is priced based on the number of times the flow has been triggered.

So, today we will learn how can we restrict/filter our power automate trigger.

Here is the scenario, I have a custom entity(Blog Note) of activity type and I want my power automate to trigger on create of blog note record when it’s is created from the Contact entity.

Now, under the timeline section, I can see an extra activity entity named Blog Note under Account, Contact, Lead, and so on.

I have the power automate ready with me, which triggers whenever a record is created within the Blog Notes entity from any entity like account, contact, lead, and so on.

I want to restrict my flow run so that it triggers only when a user creates the blog notes from the Contact entity. If a blog notes is created from some other entity like account or lead then the flow should not trigger.

To handle this we need to go to the trigger step(Trigger on create of BlogNotes) setting.

Go to – trigger step Settings
Added the Trigger Condition

This is how we check if the regardingid is a contact entity then only the power automate trigger else it won’t.

I hope this helps!

Learning Power Automate – Check null for a variable

Today, we will learn how to check an empty value on a variable under Power Automate.

I had a requirement where I need to push my Lead record data from Dynamics CRM to another application.

To fulfill this requirement, I thought of going with power automate. Which would trigger whenever a record is created under the Lead entity and then push the data to another application.

Here I have a field Due Date which is an optional field on a form. So now it is a user who chooses to enter data or not.

I have a child flow where I need to pass the data of Due Data as well. Below is the JSON schema for Child Flow. We can see that the due date is of string type, therefore if we pass null value it would throw us an error: Invalid type. Expected String but got Null

JSON Schema

To handle this scenario, we can use an empty expression:

Expression:
syntax: if (empty(duedate), ”, duedate)

expression used to check field(duedate) was empty:

if (empty(string(triggerOutputs() ? ['body/duedate'])), '', triggerOutputs() ? [' body/duedate'])

How the expression work is it checks whether the field is empty or not, which means if the value is null or empty then it returns true which will pass not null. This is accepted as a string. Else, if the field contains a value then it would pass the field value.

Hope this help!

Learning PowerAutomate – Get Option set label

Let’s learn how to get option set label, without query to string map table for retrieving the labels.

As, we know that querying to an entity option set field will give us the option set value not the label. So if we want to get the option set label against any value

Note*: we can use an expression to get option set labels.

I have an option set attribute named as Loan type, which is present on Lead entity.
Querying on Lead entity, for attribute Loan type. I get the option set value not the label.

Therefore, to get the label against the retrieved value. I went using replace expression:

replace(replace(replace(string(triggerOutputs() ? ['body/new_loantype']), '43260000', 'HomeLoan'), '43260001', 'BusinessLoan'), '43260002', 'PersonalLoan')

The expression replaces the option set value with the given label.
Example, whenever we get the loan type as ‘43260000’, using the expression I will get the result as “HomeLoan”.

Moving ahead, we can use the set variable step under our flow. Where we can use the expression based on the output we receive for the above steps.

Additionally on top of the above requirement handling process, I went into another scenario where the option set field was coming null.
Reason, the field was marked as optional field. So, now its a user choice to enter data for option set field or leave it as null.

So, whenever I was getting the null value for the option set field records, I was getting an error as: Invalid type. Expected String but got Null.

Therefore for handling the null value exception, I went using empty expression:

if(empty(string(triggerOutputs()?['body/new_loantype'])),'',replace(replace(replace(replace(string(triggerOutputs() ? ['body/ new_loantype']), '43260000', 'HomeLoan'), '43260001', 'BusinessLoan'), '43260002', 'PersonalLoan')

The above expression helps us in handling null value. When we are passing loan type value to another variable of string type or to a child flow when the expected schema is of type “string”.

I hope this helps anyone! 😊

Filter Lookup Based on Option Set value

Today, I met with a requirement where we need to achieve filtering of lookup values based on option set value selection.

The requirement was to filter Loan Category(lookup field), based on Loan Type(optionset field).
There were three different types of Loan Types in the system (optionset field).

  • Home Loan
  • Business Loan
  • Personal Loan

I had to provide the required filter on “Lead” entity. So, below are the steps which I followed.

  • Created a Global OptionSet, having Loan Types.
  • Created a field Lead Loan Type(blog_leadloantype) of option set type on Lead entity and called the Global Option Set
  • Created a field Lead Category(blog_leadcategory) of lookup type on Lead entity. Which have a relationship with one of our custom entity name Bank Code.
  • Created a field Loan Type(blog_loantypes) of option set type under Bank Code entity. (required for filtering values)

Below is the screenshot of Bank Code entity, from advanced find which show the data to be filtered in the below desired format.

Advance Find on Bank Code entity

Create a new webresource of Javascript type and paste the below the code in the editor:

(function () { }(window.BankNotes = window.BankNotes || {}));
(function (BankNotesFilter) {
BankNotesFilter.onCategoryChange = function (executionContext) {
var formContext = executionContext.getFormContext();                                  
 
//Check if the field is not null
if (formContext.getAttribute("blog_leadloantype").getValue() != null) {

//Apply Search on lookup field OnClick 
formContext.getControl("blog_leadcategory").addPreSearch(function(){
var loancode = formContext.getAttribute("blog_leadloantype").getValue();        

//Apply the filter condition
var filter = "<filter type='and'><condition attribute='blog_loantypes' operator='eq' value='" + loancode + "' /></filter>";

//Populate the filter values into lookup field
formContext.getControl("blog_leadcategory").addCustomFilter(filter);
});
}
};
}(window.BankNotes.BankNotesFilter = window.BankNotes.BankNotesFilter || {}));

The above script will triggered on the onChange event for Lead Loan Type(blog_leadloantype). Function which needs to be called – BankNotes.BankNotesFilter.onCategoryChange

I hope this helps you. 👍

Omnichannel for Customer Service – Part 4

Let’s learn how to test authenticating our portal user via Omnichannel chat.

Follow the below steps for providing our Contact access to the portal.

Initiating the chat from the portal. Sign-in as Contact(Avinash Verma).
Also, check that the agent status on the omnichannel agent screen is available. If the agent does not have the capacity then the call won’t come to the agent screen.

Below we can see that the contact name appears on the chat notification which appears on the agent screen. Rather than Visitor 1 which would appear for an anonymous user.

Hope this helps!!!

Microsoft Power Virtual Agent(AI chatbot)

Working on Omnichannel for Customer Service, I came across Microsoft Power Virtual Agent which is an AI chatbot.

Power Virtual Agent helps us to create a bot with the no-code interface. Where it minimizes the effort required to deploy and maintain custom solutions. Also, Power Virtual Agent can answer many major issues using the bot service.

Advantages:

  • Allow a person to build a bot without any coding or AI experience
  • Common inquiries can be answered by the bot with any user intervention. This reduces the human agent’s effort and time.
  • Customers can self-help themselves 24/7 using a power virtual agent. This improves customer satisfaction experience.

Now, let’s dive into Power Virtual Agent, click here.

Sign In and follow the below steps:

There are multiple topic already present we can use system and sample topics.

User Topics and System Topics
Hit new topic for creating a new topic
For updating the topic flow click on Go to authoring canvas.

I tried with creating a sample bot for me.

Click here to check the video.

I hope this gives you and idea about Power Virtual Agent.

Omnichannel for Customer Service – Masking Chat Conversation

Omnichannel for Customer Service offers us the capability to mask chat data.

Why use data masking?

Data masking helps the organization to protect the customer sensitive data like Credit card details, SSN number, Account Number, etc.

How does it help any use case?

Any text that’s masked in a conversation will also be masked in the conversation transcript.

Masking rules can be implemented for customers, agents, or both.

Let’s start with setting up a masking rule, follow the below steps:

  • Go to Omnichannel Administration App
  • Under site map go to Settings –> Data Masking Settings
  • Enable Mask private customer data from the agent
  • Create a masking rule
Omnichannel Administration: Masking rule page
  • Mask private agent data from the customer: Data the agent sends is masked for both the customer and agent for live chat and async channel messages.
  • Mask private customer data from the agent: Data the customer sends is masked for both the customer and agent for live chat, but only for the user interface of the agent when using async channels.

For the masking rule to work, we need to Activate the desired rule.

Create New Masking Rule
Masking rule needed Regular Expression for masking the data.

Only 10 data-masking rules, including the rules provided out of the box, can exist in Omnichannel for Customer Service.

Let’s create a simple masking rule where the rule would mask(#) any incorrect word send via customer chat to our agent.
I have entered the few incorrect words inside the regular expression field. Now, if the customer enters any words(shit|donkey|fool|useless|angry|sue) which lies within this Regular Expression the word would be masked by “#”

Create Masking Rule

Name: Enter the masking rule name
Description: Provide the description of the created rule
Regular Expression: Regular Expression is required for masking data

Going to the portal, User-initiated the chat and type the incorrect word on the chat window.

Following the same chat, refer to the below slide.

I hope this helps!!!

Omnichannel for Customer Service – Part 3

This is part 3 of Omnichannel for Customer Service. Where we will be exploring on Omnichannel Insight for Dynamics 365.

For the previous parts of Omnichannel you can refer the below links:

Omnichannel Insight for Dynamics 365 provides us an insight into the customer service omnichannel delivery and it also provides the information about the customer sentiments.

This allow the Supervisors to perform the following tasks from the dashboard:

  • Monitor Omnichannel operational metrics across Channel, Queues and Agents.
  • Monitor support quality via sentiment analysis across Channels, Queues and Agents.
  • Monitor Bot operational metrics

Click here to access the Omnichannel Insight for Dynamics 365 from Microsoft App Source.

Omnichannel Insight for Dynamics 365

Click on GET IT NOW button.

For accessing the Omnichannel Insight under CRM Dashboard we will need to perform a few steps as shown below:

Go to Settings under Developer Resource, we have the Service Root URL of the instance

While connecting to the instance it asks for selecting the Authentication method and Privacy level setting for this data source.
There are 4 types of authentication provide for establishing the connection:

  • Anonymous
  • Basic
  • Key
  • OAuth2

Similarly, we have 4 types of privacy level settings:

  • None
  • Private
  • Organizational
  • Public
Values provided for establishing the connection

Here is our Omnichannel Insights for Dynamics 365, it’s a Power BI Dashboard.

Now, let’s do some setting for accessing the Omnichannel Insights dashboards inside our CRM instance.
For that we need to allow the user to embed Power BI reports under CRM by enabling Allow Power BI visualization embedding to Yes under the System Settings Reporting tab as shown below:

Allow Power BI visualization embedding to Yes

I hope this helps!!!