Dynamics 365-CE Approval Dialogues Using Canvas-apps

There are scenarios where we need to configure approvals in Dynamics 365, for example, mark an account as a premium customer after approval or qualify leads after approval etc. We used dialog control to capture approval request and comments but, now dialog controls are depreciated and not advised to use for new projects.

As per Microsoft’s initial announcement

Dialogs are deprecated and are replaced by mobile task flows (available as of the December 2016 update), and business process flows. Both task flows and business process flows will continue to evolve to make the transition easier.

But either tasks flow or business process flow was not a perfect replacement for Dialog. Knowing this pain from users, Microsoft has now modified the announcement.

Dialogs are deprecated, and should be replaced by business process flows or canvas apps

Even though I knew canvas apps can be now embedded in model-driven apps, I hadn’t thought of this option until I came across this new announcement, so tried replicating my approval dialogues with a canvas app and it works fine. Pheww!!!! ?

For testing purpose, I replicated the dialogue for creating approval request for the Account entity.

  1. created a canvas app to create an approval request.
This sample app changes account status to pending verification and captures the comments in one custom field.

2. Now we need to call this app from account form, obtain the app ID from app details section.

select app details to get the App GUID

3. I need to call this canvas app as a popup when the user clicks a button. I created a custom button for account entity-> added a JavaScript as button action to call an HTML web-resource and embedded my canvas app in this HTML I-frame.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html><head>
<title>Approval</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style="padding: 0px; font-family: arial; overflow-wrap: break-word;" onload="LoadPowerApp()">
<center>
<iframe id="Approval" width="800" height="600"></iframe>
</center>
<script id="myScript">
function LoadPowerApp()
{
var AccountID = window.parent.opener.Xrm.Page.data.entity.getId().slice(1, -1);
document.getElementById("Approval").src=url;
}
</script>
</body>
</html>

I know you have many questions now. "https://web.powerapps.com/webplayer/iframeapp?source=iframe&appId=/providers/Microsoft.PowerApps/apps/56123673-f45c-4b96-b9e6-ece1b0a8069a&ID="+AccountID;

This is the key and I will breakdown it into parts “https://web.powerapps.com/webplayer/iframeapp?source=iframe&appId=/providers/Microsoft.PowerApps/apps/APP GUID&CUSTOM PARAMETER NAME=”+PARAMETER VALUE

App GUID I explained in step 2, now regarding a custom parameter, I deliberately didn’t mention it when we discussed the app creation and kept for this section. When we open this canvas from an account form(like we start a dialogue) the app needs the record GUID to update the account status

I have used form control in the canvas app and filtered the item using the ID Parameter.

4. Now try your button and you can see the magic.

You can download the sample APP from TDG Power Apps bank.

Please note this is a basic app I tried for testing purpose and needs many improvements to use in a live project. you are always welcome to discuss with on this app.

Hope this helps….. ?

Implementing Enterprise Search In Power Platform

Photo by Anthony Martino on Unsplash
Photo by Anthony Martino on Unsplash
Providing good search capabilities is a key feature in modern business applications to support usability and end user satisfaction. We have seen how the search capabilities of the Dynamics platform has evolved from providing “Quick Search” and “Advanced File” to “Relevance Search”. The goal of the platform search features has been to support users to find the relevant information they need in the quickest and easiest form. These search features are out-of-the-box and easy to enable/configure/use. As the platform progresses to offer richer features to users and enable them to search better, the demand for richer and better search techniques grow, and we see instances where the platform capabilities cannot meet user demands with its out-of-the-box capabilities. Before going further about advanced search scenarios, you can read about the platform out-of-the-box search capabilities in this official documentation. In this article I share why we may decide to implement a search solution of our Dynamics solution using Azure Search Service.
In enterprise implementations, business applications are not the only systems used in the organization. We often see call center agents and sales representatives need to obtain their required information from various systems to service customers. Searching users in every system is a cumbersome job which may cause setbacks in end-user adaption. Integrating Dynamics with Azure search offers consolidation of search operations in one specialized search service with ability to connecting to various data sources and apply modern search techniques to find the most relevant data. A practical example of this scenario can be seen in one my recent experiences where the organization users had to search for user information in CRM, SharePoint, Sybase and a pool of CSV files.

Customized Search experience

To facilitate more user adoption, using customized search techniques are highly favorable. In all modern search engines, we see use of “Auto complete”, “Suggestions” and “highlighting” features which can be added to the Dynamics solutions search experience. Displaying search results by support of “Document Preview”, “Document Opening in a customized containers”, “Facets”, “Filter” and “Sorting” are examples that enhance your Dynamics solution’s capabilities.

Customized Search Behavior

The true power of search is demonstrated with different pieces of information are linked together to make sense of a bigger picture. Extracting words and sentences from documents including images and pdf files, extracting key phrases, people names, location names, languages and other custom entities with the help of AI is another unique feature that you can add to your Dynamics’s search capabilities. Another amazing search capability you can have in your Dynamics implementation is the ability to search based on geolocation information, i.e. you can search for all your partner network from CRM or get the location of your field service force. The beauty of implementing your own enterprise search lies in the fact that you can search information in your data stores and link them using AI to generate knowledge and better insight to your data.

Customized Search Result

Another need for customized search in your Dynamics solution to the ability to refine your search result profile. When you use AI in your search, the system gives you the power to see how relevant search results are to your search keywords. And by knowing this you can refine your search profiles to generate a different result for the same keywords. This way you train the AI engine to work better for you and enable users to get more accurate search results.
Architecture

Dynamics integration with Azure Search service can be integrated in the following pattern:

 

  1. Integration through web resources: These web resources will host a web application acting as a client to the search service. The web resource can be a HTML file or an iFrame hosted on forms. The important point in this approach to ensure cross-origin settings in the client application and writing your html in a secure way and according to the best practices.
  2. Integration through custom power platform controls. You may build your own custom control which sends REST requests to the Azure Search and display results by consumes REST responses. The custom control can call Azure Search services using Actions or direct REST calls to Azure Service.
  3. Azure Search works based on indexes and your first step is to push your CRM searchable data to Azure Search indexes. This can be done using Microsoft Flow, Microsoft App Logics, custom solutions or Azure Data Factory. I have used all these tools in my implementations, and you can opt to any of these tools based on your requirements.
  4. Once the data is in your data store, you can create your indexes in the Azure Search. You can go for separate indexes for each data source or combine multiple data sources in one index. Each approach has its own requirements which will need to be met either in your client web application or a separate azure compute resource. Once indexing is done, you can make use Azure Search Rest API directly or using Azure API management to expose your search service to your Dynamics solution.
Summing these all up, you see as business application products get more sophisticated and organizations move from data to big data, engineers now must look for innovative approaches to implement Dynamics Solutions. Microsoft Azure along with Dynamics platform offers necessary tools to solution architects to design such solutions.

PowerApps – Running Functions in Parallel using Timers

In a previous post I used PowerApps to query Dynamics to check if a list of email addresses exists in my instance as contacts. I used the ForAll function to lookup Dynamics for each email in my collection sequentially. This worked  fine until I had to check if 500  emails exist in  my instance containing just over 300,000 contacts.

After doing some performance bench-marking ( Beginning the search and starting a stop watch on my phone) this query took 12 mins 53 seconds to run. Would be great if multiple lookups could run in parallel. I used timers to run the exact same ForAll statements three extra times , similar to separate threads which greatly improved the speed. Although I had to make sure each email wasn’t processed multiple times.

My original statement was:

ForAll(SearchEmails,Collect(Matches,LookUp(Contacts,emailaddress1 = Result))))

SearchEmails has a column called Results which contains the emails I want to find. For every email in SearchEmails , check if it matches the email address 1 field of a contact record in Dynamics. If one is found add it to a collection called Matches.

ClearCollect(ProcessedEmails,{email:” “});

I created a collection ,ProcessedEmails, this will store emails that have already been searched for.

Edited the original ForAll statement to only lookup emails that do not exist in the processed emails collection. Before the email is looked up, it is added to the processed list so another thread/Timer doesn’t pick it up but moves onto the next email.

ForAll(SearchEmails,If(!(Result in ProcessedEmails.email), Collect(ProcessedEmails,{email:Result}); Collect(Matches,LookUp(Contacts,emailaddress1 = Result))))

The above ForAll runs  on visible of my search page, I also then created  3 timer controls  each with the same for all statement in their on timer end functions.

Timer Properties

Auto-start : true , Repeat = false.

Durations

Timer 1 4000

Timer 2 8000

Timer 3  12000

When the search page is visible,

  • The original search will run on the OnVisible function
  • Timer 1 will start searching  four seconds later
  • Timer 2 four seconds after timer 1
  • Timer 3 four  seconds after  timer 2

This was to stop all my timers starting the search at the exact same time and processing the same emails.

With the For All lookup running 4 times the search went down from 12:53 mins to 3:21

Im sure additional timers could be added to possibly improve performance even further

Full formulas used
Search Page on visible

(can be applied to a button instead but make sure you start the timers)

Clear(Matches);ClearCollect(ProcessedEmails,{email:”something”}); Set(vSearching,true);ForAll(SearchEmails,If(!(Result in ProcessedEmails.email), Collect(ProcessedEmails,{email:Result}); Collect(Matches,LookUp(Contacts,emailaddress1 = Result)))); Set(vSearching,false)

Timers OnTimerEnd

ForAll(SearchEmails,If(!(Result in ProcessedEmails.email), Collect(ProcessedEmails,{email:Result}); Collect(Matches,LookUp(Contacts,emailaddress1 = Result))))

My Quest to D365 Saturday Stockholm

Recently I attended the Dynamics 365 Saturday event in Stockholm and I have to say, what an excellent event. I have never been to Stockholm, so I was already massively excited about this. I also got to meet a load of new people for the first time which was AMAZING!

These events are so important for the community because they are often the only opportunities some of the community members really have to interact with other customers, partners ISVs and Microsoft employees. I love running into people that have encountered the same issues as I have, that way I know I’m not going bonkers and we can work on a solution together.

The crowd was great! There were many enthusiastic people in the audience who were really getting involved in the sessions, looking for information and really testing all of the speakers knowledge. You can find the list of sessions and speakers HERE.

I big reason I really enjoyed this event was the different layers and levels of content being shared across the sessions. The sessions were split into three tracks, these being:

Applications (Dynamics 365 CE), Dev (Dynamics 365 CE) and Business & Project Management. This gave participants the opportunity to stick to a single, themed, track or weave between tracks. This is pretty much how my experience went. I went to at least 1 session from each track. I wanted to get a flavour for everything. I also got to see some wizardry from folks like Julie Yack, Gus Gonzalez, Nick Doelman and Gustaf Westerlund.

Other presenters and panellists included Sara Lagerquist, Jonas Rapp, Fredrik Niederud, Katherine Hogseth, Mark Smith and Antti Pajunen. Each delivering some amazing content based on their experiences with Dynamics 365 and Power Platform.

There was a plethora of information and content being shared between speakers and passionate attendees. Everything from Microsoft Portals and Social Engagement to developing your own XrmToolBox tools (Careful with the spelling here….HAHA) was being talked about. I personally got involved in a number of Power Platform conversations, which suited me just fine because that’s kinda what I’m doing at the moment.

I had the pleasure of running 2 sessions. One in the Application track and one in the Dev track (I am no developer… Don’t judge me). The 2 sessions were:

  1. Power Platform – How it all fits together (Download Here)
  2. Building your first Canvas App with CDS, and Azure (Download Here)

Apparently people don’t like the first 2 rows.. great crowd though! Thanks to everyone that attended. Try work out what Mark is doing in the background there! HAHA!

The first presentation focused on the different elements of the Power Platform and the way it all works together. Many Dynamics 365 users often worry a bit about this because it seems so large and complicated, but it really isn’t once you have wrapped your head around the different technologies. To highlight the way the different elements of the technology worked together I included a Roadside Assist demonstration that was created during the PowerApps & CDS Hackathon Those Dynamics Guys and Hitachi Solutions Europe hosted together.

My second presentation consisted some of the “Do’s and Don’ts” around building your first Canvas App with your customer. I followed the presentation with the following:

  1. Adding several fields to a custom entity in the Common Data Service (CDS)
  2. Importing some data
  3. Creating a new canvas app
  4. Connecting the Canvas app to the CDS
  5. Adding in the Azure translation service to the app
  6. Publishing the app

The actual canvas app I created with the little model driven app solution, including data is available HERE.

The below pic gives of the impression that I am about to start having a conversation with my own hand, like an invisible Muppet. May be a great trick for my next demo 😀

One of the BEST sessions that I have been in was the “CAGE MATCH” moderated by the one and only Julie Yack,  This was EPIC fun! We were split into teams of 5 and given problems by the audience to resolve. It was a little daunting being in the presence of some of these long time MVPs, BUT, THE SHOW MUST GO ON, so we got stuck right in. Unfortunately, the team I was in didn’t take the win 🙁 Its cool, I am preparing my battle cards for the next one!

All in All, it was a fantastic event and a great opportunity to network with this amazing Dynamics and power Platform community that we all have grown to know and learn from. A MASSIVE thank you to the sponsors of the event!

Also, a big thanks to all of the folks that hung out after the event and enjoyed several beverages with me. Was a great time and I’d love to do it again 🙂

Here are some more delightful images from the day 🙂 My camera skills aren’t great so i had to grab a few from social. Thanks to those that grabbed pics in my session! I hope that this encourages more people to attend these events because I genuinely gain so much from being there.

Nick Doelman Smashing his Portals Presentation

One of my favourite Finns – Antti

Julie Yack doing her presentation on Social Engagement

MORE of the awesome Julie Yack

WHAT?? ANOTHER ONE of my favourite Finns – KIMMO!

JOOONNNAASS RAPP!!! The Legend!

We were all so excited! mark, Jonas and me 🙂

 

 

How to embed a Canvas app into a CE form, pass the record id and update the CE record.

The requirement: Allow a CE user to update marketing consent and to provide guidance and logic around the process, this app is the basis for the latter.

Solution: This could be achieved using a custom webpage, or possibly a Dialog (deprecated soon), but the latest recommended approach is to use a canvas app embedded within CE, so here are the steps to achieve this;

Note: this screenshot/app was to prove the process works so has some random fields in it, ultimately there would be a lot more to it with extra logic.

  1. Create the connection to D365
  2. Browse to Apps and Create a new blank Canvas app
  3. Insert a new Form (Edit)
  4. Select [Data Source] and Add new, select your connection to D365 from earlier
  5. Choose the appropriate D365 environment
  6. Select the [Accounts] table and [Connect]
    • This will add some fields to the Form for you and is where you can select the ones you want/don’t want, format them/rename them, change the colours etc.
    • The blue header/footers in my example is a [Label], white text, blue background, the colour code is #3B79B7 which matches the CE UI theme
    • Rename the Form in the left panel from Form1 to [AccountForm]

  1. Next, you need to update Form to take an input parameter with the ID of the CE record which we will pass in further on, on the Form, select [Advanced], then [Item] and enter
    • LookUp(Accounts, accountid= Param(“ID”))
  2. Next insert an Icon – [Check] so that we can Submit the changed data back to CE, go into Advanced on the Icon and Update the OnSelect to;
    • SubmitForm(AccountForm)
  3. Save and Publish the app
  4. It should now look something like this, depending on the field types you select, I added a footer with the CE ID value displayed to check what was passed through.

  1. Browse to https://web.powerapps.com/environments/ then Select [Apps] from the left menu

  1. Click on the ellipsis of the App, and make a note of the Web Link from the [Details] Tab. It will look like this – https://web.powerapps.com/apps/<AppID> make a note of this APPID for the steps below.
  2. Next is the CE components, add a new HTML Webresource and paste in the following code replacing the <AppId> with the one you recorded previously.
    • Set the width and height to your App sizes, taken from the App settings page.

  1. Open the [Account] entity form, Add a new Tab, Insert a new Web Resource onto it, select the web resource that you created in the previous step and set the following parameters;
    • Display Label on Form= false
    • Number of rows = adjust depending on the size of the App
    • Scrolling = As necessary
    • Display Border = false
  2. Save and Publish
  3. It should look like this once it’s finished