Author Archives: Alex Shlega

Good old validations, and why the plugins/workflows are still alive and kicking

 

Interesting how, with all the power Flows can offer these days (we can even customize Sharepoint integration with Flows), there is still one scenario which just cannot be covered without the classic plugins/workflows.

Namely, anything that requires synchronous (or real-time) processing, would need a plugin or a workflow.

For example, what if you wanted to intercept all create/update operations in such a way that nothing gets saved when the data does not validate?

The diagram below would not reveal anything new to the folks who have been working with Dynamics for a while, but, if you are just getting into the model-driven applications development, this may be something to keep in mind:

 

image

Although, what complicates this a little bit is licensing. Validations are great, but, if there are users utilizing your data in a Canvas Application on Plan 1, adding a plugin/real-time workflow to an entity exposed to such an app would require those users to go up to Plan 2.

Anyway, just to make this post “complete”.. how do you display server-side validation errors in the interface?

Here is how you can do it from a real-time workflow: https://survivingcrm.com/2013/11/using-real-time-workflows-to-show-error-messages/

And here is how you can do it from a synchronous plugin: https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/best-practices/business-logic/use-invalidpluginexecutionexception-plugin-workflow-activities

Creating custom folder structure for Sharepoint integration using Flows

We’ve come across an interesting problem recently. Imagine that you have a few different business units, and you want Sharepoint integration to work in such a way that all the documents within each business units would be shared, but there would be no sharing between the business units.

This is not how it normally works in Dynamics, though, so the options are:

 

The permissions replicator is great, and it would do the job, but, just to explore that custom implementation option a little more, what can we actually do?

If it were on-premise, or if it were a few years ago, we’d have to think about a plugin for this.

But, since we have Flows, I figured it would be interesting to give it a try. And it worked.. Not without a few quirks, but I did not have to write a single line of code. Which is unusual to say the least.

Here is how it happened, step-by-step.

1. Creating a solution

First, we need to create a solution..  I’ll be creating a flow in the next step, so I figured flow.microsoft.com would be just the right place to create this solution:

image

2. Creating a flow

I will add more details about the flow down below, but, at this point, here is a screenshot of what the flow will look like once it’s built:

image

3. Preventing default document location logic

There is a bit of a problem with this whole approach. What if somebody created a case and jumped to the “related documents” right away? The flow above is asynchronous, so it won’t create document location immediately. If a user navigates to the related documents too quickly, Dynamics will create default document location.. so we need to prevent that from happening somehow.

That’s what this real-time workflow will be doing:

image

It will run “on create” of the document location records, check if that record is regarding a case AND if it does not have a keyword in the Name field (which will be added to all locations created from the Flow above), and, then, will stop the workflow as cancelled.

Honestly, the error message is going to look somewhat nasty:

image

After a minute or so that grid will get back to normal, but, of course, the users will have to refresh that screen:

image

Besides, most of the time Dynamics users would not create a case just to start uploading documents right away, so there is a good chance that error would not be showing up in 90% of the cases. Still, there seem to be no way around it except the notorious “user training” (as in “yes, if you navigate to the related documents too fast, you will see an error message”)

Actually, the screenshot below shows exactly what’s happening in Dynamics as a result of the flow execution.

And, of course, a folder gets created in Sharepoint:

image

4. What about that flow, though?

Step one is a trigger. We need to create a document location for every new case.

Steps 2 will get case owner user record from Dynamics – this is to get to the business unit.

Which is what step 3 will do – it will query case owner’s business unit record from Dynamics.

image

In the next step, the flow will query document location record by name:

image

This is part of the setup, actually.

For every business unit, an administrator will have to do 2 things in advance:

  • Create a sharepoint library and setup permissions in such a way that only BU users will have access to that library
  • Create a document location record in Dynamics pointing to that sharepoint library (and having the same “name”)

 

Here is an example of the sharepoint library:

image

And here is a corresponding document location record:

image

So, basically, the flow will find that location by name (treecatsoftware is the business unit name), and, then, will use it as a parent location when creating document location for the cases in that business unit.

Finally, we need a foreach in the flow. Technically, there is supposed to be only one record that matches the condition (name = business unit name). I just don’t know how to reference exactly the first one in the record set, so I figured I’ll go with foreach:

image

This first action above will create a folder in Sharepoint for the new case. It’s an http request Sharepoint connector action, and here is the URI:

_api/web/GetFolderByServerRelativePath(decodedurl=’/sites/Dynamics/@{body(‘GetBU’)?[‘name’]}’)/AddSubFolderUsingPath(decodedurl=’@{triggerBody()?[‘incidentid’]}’)

And the second action will create a document location in Dynamics:

image

Here is a link to the exported solution (I did not try to import it anywhere yetSmile ): http://itaintboring.com/downloads/SharepointFolders_1_0_0_0.zip

Unexpected goodies just keep showing up!

I am not sure what’s been happening to the PowerApps product team recently, but, whatever it is, I think a “thank you” is in order.. it just seems they are really working on tiding up the UI these days.

Just today, I noticed a couple of new(?) things, and it feels like.. an unexpected gift. No, really.

I can scroll through all the records in the lookup control now. It will open up with some records loaded, and, then, it will load more data as I keep scrolling. This is it – dark days of the classic UI are over!

image

But there is one less reason to use optionsets in place of lookups now.

Actually, I don’t know when this change happened. Has it been there for a while and I just did not see it?

What I do know, though, is that only a week ago I made this post:

https://www.itaintboring.com/dynamics-crm/quick-tip-get-yourself-a-bit-more-space-when-enabling-dynamics-365-app-for-outlook/

And I‘m pretty sure the post itself does not have anything to do with the fact that it’s not an issue anymore and the grid is not truncated:

image

Well, it’s been a good day, it seemsSmile)

Using FetchXml in the Flows

 

Having established (for myself.. and not without the help from other folks) that CDS Connector is the way to go when working with Dynamics or CDS data, I quickly found that ListRecords action does not support fetchXml. Or, at least, I don’t see a parameter for that:

image

That said, WebAPI endpoint does support fetch execution:

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/web-api-query-data-sample#bkmk_fetchxml

So this seems to be current limitation of the CDS Connector(intentional or not).

Technically, fetchXml is more powerful  than OData when it comes to building complex queries, when traversing the relationships, etc. I am not sure what the future holds for FetchXml, since it’s a proprietary “query language” developed and maintained by Microsoft, but, for now at least, it’s a legitimate way of querying data from Dynamics and/or from CDS.

So, what if I wanted to use FetchXml to validate some advanced conditions in my Flow?

Not to go too far into the complexities of FetchXml, let’s try adding a condition that verifies if a primary contact on the account that’s just been created has associated cases. The query would look more or less like this:

image

And, if that query returns any cases at all for the account, I’d like my flow to add a note to the account description field.

So, to give you an idea of how my flow will look like, eventually, here is a screenshot:

image

The first step is straightforward – it’s a CDS Connector trigger which will kick in whenever an account record is created.

The second step is where I’ll actually run FetchXml.

The third and forth steps are all about parsing the results and verifying the condition.

For the second step, even though it’s probably possible to do the same with a pure HTTP connector, I figured I’d use an Http with Azure AD (Preview) connector instead. Turned out it does take care of the authentication already, so I don’t need to worry about that (with a note, though, that I am not exactly sure what’s going to happen when/if I add this flow to a solution and export/import to another Dynamics CE instance.. will try it later).

There seem to be two tricks about that connector, and it took me a little while to figure them out (I’ve almost given up to tell the truth). When you are adding it to the flow, you’ll be presented with this screen:

image

I used “Invoke an HTTP request” action in my flow(and you’ll see below how that action was set up), so, let’s say you’ve selected that action.

Depending on something in your environment (and I am not sure what it is exactly), you will see one of these two screens after that:

Screen a:

image

Screen b:

image

If you see screen a right away, that means your HTTP with Azure connector has picked up a connection, and it’s not necessarily the right connection. In my case, I quickly discovered (once I tried running the flow) that my action was permitted to access Sharepoint but not Dynamics – that must have something to do with Azure AD OAuth, although I am not 100% sure of what’s happening behind the scene yet.

So, if, somehow, you run into this issue, make sure to verify the connection your action has picked up, and, if it’s not the right one, create a new connection:

image

This will bring you back to Screen B from above. Once you are there, fill in the textboxes like this:

image

Do not put “.api.” in the url-s as you would normally do when accessing WebAPI endpoint. Just use root url for your dynamics instance.

After that, sign in, and you’ll be back to Screen A with the right connection this time.

The rest should be straightforward..

Set up the action like this:

image

  • Choose Get method
  • Make sure to use root instance url for the request (do not add “.api.” in the middle)
  • Add FetchXML to the url (download it form the advanced find, update as required, etc)
  • Don’t forget to update filter condition in the FetchXML so that the request is using correct account id

 

Next, add Parse JSON action like this:

image

You can just run the same url that you put into the Http action directly in the browser to generate sample data, and, then, you can feed that sample data to the “use sample payload to generate schema” tool of the “Parse JSON” action.

And the last step – just add a condition:

image

I used an expression to get the total # of records in the result set (length function) – you can see it in the tooltip on the screenshot. But, in retrospect, fetchXml aggregation might work even better for this scenario.

Do something when the condition evaluates to true (or false), and the flow is ready:

image

Time for a test drive? Here we go:

image

image

Using different connectors with Dynamics CE instances when creating a Flow

 

There are at least 3 different connectors we can use with Dynamics CE instances when creating a Flow:

  • CDS Connector
  • Dynamics 365 Connector
  • Http Connector

They are not identical, though, and, from what I have gathered so far, we may need to keep a few things in mind when choosing between the 3:

1. When using a CDS connector, make sure your environment has been upgraded

Otherwise, you won’t be able to see your Dynamics CE database from that environment. For example, here is what showed up when I tried creating a flow in the old Default environment which was never upgraded:

image

And here is what shows up when I’m working with a flow in my Dynamics CE environment:

image

 

2. There are rumors that Microsoft has stopped working on the Dynamics 365 Connector

That said, most of the Dynamics 365 connector functionality seems to be available in the CDS connector. Although, there is no “Create or Update” trigger in the CDS connector, and it’s not unusual when we need the same processing to happen in response to either of those events.

If you are using a CDS connector, you may, then, consider starting to use nested flows:

https://flow.microsoft.com/en-us/blog/build-nested-flows/

Which would, basically, look like this:

image

And yes, personally I think that’s quite a complication for somebody used to the native Dynamics workflows. Which is beyond the point, though, since those are different “technologies”.

However, unlike Dynamics connector, CDS connector has “Current” environment option which is why it can be packaged into solutions. You move it to another environment, and it’s still “Current”, so it just works.

3. HttpConnector is a low-level approach, and, just like any other low-level approach, it’s more complicated to implement, but, of course, it gives you most of the control

Mostly, it seems, we’ll be dealing with these two problems:

  • There is no seamless authentication – here is how you can try working around it: https://community.dynamics.com/crm/b/mscrmshop/archive/2018/02/18/calling-d365-apis-from-logic-apps
  • Forming the requests and parsing the responses – both CDS and Dynamics connectors have a rather good idea of what the environment looks like (entities, types, etc). Http Connector, on the other hand, will make no assumptions at all, so you’ll need to know the entity names, you’ll need to know how to write Web API queries, etc.

 

But, in return, you’ll be able to do everything(?) that can possibly be done with Web API

Updated Advanced condition builder and the importance of the social media

You would think those two things in the subject line don’t have much in common, but I just had a eureka moment, which, I believe, had a lot to do with the following three facts:

  • I am very new to Flow
  • There are things in Flow which are very new to Flow as well
  • And there are people which are exploring all those new things and letting us know of their findings on the social media

Imagine.. I am looking at how to create advanced conditions in Flow so I can do some filtering when an update/create (Dynamics) trigger kicks in, and there is this great video by Elaiza Benitez where she explains those things for the newbies like me:

https://www.youtube.com/watch?v=mBS9bS1Tmls

Great, eh?

Well, of course, except that there is no advanced mode anymore:

image

So I am rewinding her video to see if I missed anything, and it just so happens that Andrew Ly makes a post on Linkedin where he is praising updated condition builder, and I see it in my LinkdeIn feed just when I am trying to figure it all out:

image 

This is where it hits me. Aha.. Maybe some things have changed?!

So, I am hoping you know by now that there were some changes and they are described here:

https://flow.microsoft.com/en-us/blog/build-more-powerful-conditions-in-flows-and-more/?WT.mc_id=azurebg_email_NL_All_Microsoft%20Flow%20Mar2019%20Update_EN-ROW

In my particular scenario, turned out it really was not that difficult to create a condition I was looking for – I just had to use pretty much the same expression that you’d see in the video above to convert my original field value to 1 or 0 depending on whether that value was empty or not:

image

if(empty(triggerBody()?[‘_parentcustomerid_value’]), 1, 0)

And, then, I used computed value in a simple “equals to” condition:

image

Simple indeed, but I am still thinking of the mysterious events of the last hour or so which involved:

  • A youtube video by Elaiza Benitez
  • A linkedin post by Andrew Ly
  • A blog post by Stephen Secilliano

All of which took me from “how the hell am I going to do this” to “it was not that bad at all”.

PowerApps / Dynamics Application designer: don’t just open the sitemap. Open the application, then the sitemap

 

Remember the old days when all developers (and not only developers) had to also develop an habit of using CTRL+S to save their changes so not to lose them?

There is a bit of that in the PowerApps / Dynamics Application designer right now. Depending on how you add entities to the sitemap in your application, you may or may not get them added to the application. You may also have to remember to hit the “Save” button.

1. When adding an entity to the site map from within the model-driven app, you’ll see that entity added to the application as well

Here is a new app:

image

I’ve opened the sitemap editor and added Account entity to the sitemap:

image

Saved and closed the sitemap – notice how account entity has been added to the app, too. I still have to hit save/publish there, but the entity has been added already (not sure how comes “Save” is required at that point, but it is. Even though I can close the app at this point without saving, then open it.. then hit “Save”):

image

2. Let’s add another entity, but let’s try opening the sitemap directly from the solution this time (not from the application designer as we did above)

image

Just added Opportunities to the sitemap:

image

Hit “Save and close”, then opened my application from the solution:

image

There is still only one entity (account) in the application:

image

And, if I clicked Site Map to have a look at the sitemap, I would see “Opportunities” and “Accounts” in the sitemap.

Why does it matter?

What you have in the sitemap is only one part of the puzzle when working with the unified interface. There are other pieces which are affected by whether an entity has been added to the app or not. Two important ones I’ve noticed so far are:

  • Unless the entity is added to the app, you can’t add entity other components. So, for example, quick create for that entity won’t work in the unified interface since you would not have quick create form added to the application
  • You won’t be able to create activities regarding such entities in the Unified Interface. Only those entities which have been added to the app will be available for selection. Although, you’ll still be able to add a task, for example, directly to such entity (when you open the entity through the sitemap navigation). Problem is, if you create a task outside of the entity screen, you won’t be able to link it to an entity that’s not in the app

 

So you really have two options: never open sitemap designer directly from the solution – always do it from the app. Or remember to add your entities to the app every time you add them to the corresponding sitemap.

Wrapping my head around the licensing for Dynamics / PowerApps

 

There have been a number of really good posts on the licensing so far, but, I think, the main problem for me used to be that I just could not consume all that information till I left the familiar space of the On-Premise implementations and started working in the online environment.

So, in this post, I’m just going to emphasize a few things about licensing that seemed important to me.

1. What is the difference between a CDS instance and a Customer Engagement instance?

Really they are both CDS, but there are different actions you can take on them:

https://docs.microsoft.com/en-us/power-platform/admin/wp-cds-for-apps

Also, Customer Engagement instances will have those extra solutions which, I believe, you can’t just get added to the regular CDS instances.

I would say that any CE instance is still a CDS instance, but the opposite is not true.

2. What is the difference between a model-driven app and Dynamics CE?

“Dynamics” is nothing but a set of so-called first-party model-driven applications now. Basically, those are model-driven applications built by Microsoft on top of the Power Platform.

In this context, the concept of restricted entities starts making sense – there are certain entities introduced through those first-party applications which Microsoft wants to license through Dynamics plans rather than through Power Apps plans:

https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/data-platform-restricted-entities

It’s as if you created a model-driven app, allowed others to install it, but still wanted to collect licensing fees from somebody willing to use that app in their environments. You’d create a license plan etc.

3. How do you decide which license your users need?

Price. is the obvious factor here. And a PowerApps P2 license would cost you about one third of the Customer Engagement licence.

However, depending on the license assigned to them your users will have different rights.

The diagram below is copied directly from the Dynamics 365 licensing guide:

image

And there is, also, Power Apps pricing which suggests that, as soon as you have a PowerApps user and you want that user to access a model-driven app (or as soon as you want that user to access any entities relying on the plugins and/or real-time workflows), you need Power Apps P2 plan:

https://powerapps.microsoft.com/en-us/pricing/

image

Keep in mind that Power Apps licensing is possible in either type of CDS (“regular” or “customer engagement”). Full Dynamics licensing is only possible in the “customer engagement” CDS where you have those Dynamics applications.

Here is the list of so-called “complex” entities (out of the box entities which require a P2 plan):

https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/data-platform-complex-entities

Word of caution: apparently, your license requirements may change as you keep developing different solutions. A P1 user working with the Canvas Apps only might suddenly require a P2 license if a plugin gets added by a developer.

4. Can you create custom entities that replicate restricted entities?

Again, looking at he licensing guide:

image

So yes, now you can.

BUT it does not apply to the Team Member licenses. Although, it’s not so much about replicating the entities – it’s more about the fact that Team Member licenses are given in the context of the main application scenario (Sales, Customer Service, etc), and you are not allowed to use custom entities which are changing the core purpose of the specified Team Members scenario:

image

Apparently, if you create a custom Case entity, you will be changing the core purpose.

5. So, just to confirm, how would a pure CDS model-driven app look like?

Actually, if you are a seasoned Dynamics user, that model-driven app would look very familiar:

clip_image002

As a system customizer, you will also have access to the solutions, solution designer, etc. Basically, you’ll feel pretty much at home:

image

6. And what are the gotchas?

Some of the features which are outside of the “restricted entities” don’t seem to be available in the regular CDS instances yet. For example, that applies to the SharePoint integration and to the Outlook App.

However.. based on the diagram above it seems to be possible to add a P2-licenses user to a CE instance, and such a user will get access to those features.

PS. If you are in the mood for more reading, have a look at these two posts:

Demystifying Dynamics 365 & Power Platform Licensing by Jukka Niiranen

Comparison of Dynamics 365 and Model-Driven PowerApp features by Hamish Sheild