Using Flow to notify solution imports

EDIT (03/04/2019): I made further changes to display the solution URL, so that you can click and find out the details about the solution that was imported.

EDIT (20/12/2018): I updated my Flow and made some improvements. You simply have to set the Timezone on the triggering action and you are all set. The Flow will email the solution list, to the user running the Flow. The download link has been updated to point to the updated solution.

I would not call it sneaky, but sometimes when I find the Dynamics 365 CE UI or behaviour has changed slightly, I can attribute it to some update that was applied to the environment. There are email notifications for major updates, but none for minor updates or patches that can happen frequently. So, I decided to solve this problem using Flow.

Every solution import into the system causes an Import Job record to be created. If a Flow can be scheduled to run everyday, and query the Import Job records that were started the previous day, we can easily keep track of what is happening in the environment.

The first step is to trigger the Flow on a preset schedule, and read the Import Job records.

Import Job Flow.png

Below are the expressions that I use for the boundary dates:

  • addDays(convertFromUtc(utcNow(),’AUS Eastern Standard Time’), -1, ‘yyyy-MM-dd’)
  • convertFromUtc(utcNow(),’AUS Eastern Standard Time’,’yyyy-MM-dd’)

The next step is to pick up only the information we need from the returned result, and project it to a form that is conducive for email.

Import Job Compose

With the exception of Solution Name, all the other properties are retrieved from the XML on the Data property. Below are the formula’s for those:

  1. Publisherxpath(xml(items(‘Parse_Import_Job_XML_and_re-map’)?[‘data’]),’string(//Publisher/Descriptions/Description[1]/@description)’)
  2. Started OnconvertFromUtc(items(‘Parse_Import_Job_XML_and_re-map’)?[‘startedon’],’AUS Eastern Standard Time’,’dd-MM-yyyy HH:mm:ss’)
  3. Old Versionxpath(xml(items(‘Parse_Import_Job_XML_and_re-map’)?[‘data’]),’string(//upgradeSolutionPackageInformation/fileVersion)’)
  4. New Versionxpath(xml(items(‘Parse_Import_Job_XML_and_re-map’)?[‘data’]),’string(//upgradeSolutionPackageInformation/currentVersion)’)

The last few steps are to email out the results, if any solutions were imported the previous day.

Email Solution.png

Email Step.png

The result is a barely formatted table, with the list of solutions that were imported the previous day.

Solution Import Email

With this approach, no one can sneak up a solution import on you. You have visibility over what is going on in the system.

You can download and install the Flow solution using these links:

Unmanaged: https://1drv.ms/u/s!AvzjERKFC6gOwlMIAzgRSXWhtXth

Managed: https://1drv.ms/u/s!AvzjERKFC6gOwlKvIWhW-Pb_vHiT

Hope this is helpful to stay on top of imports.

Advertisements

Role based Canvas Apps

The inspiration for this post is this post from Geetha -> https://svaghub.wordpress.com/2018/11/03/role-based-security-in-powerapps-using-spgroups/. The idea is to basically use Flow to check what kind of permission the current user has, so that some functionalities can either be lit up or hidden in the canvas app. In her post, Geetha was using SharePoint user group to get this information. Being from a CRM background, I want this to be retrieved from CDS + I am not a big fan of SharePoint.

Attempt 1: Use DataSourceInfo(‘Users’, DataSourceInfo.CreatePermission), to check if the current user can create Users, which means they are Sys Admin. But, there seems to be a limitation on DataSourceInfo, which means it does not return the correct permissions for CDS entities. It always returns true, which is not correct. So, this attempt was not successful. This would have so much easier if it had worked, as all the logic would be entirely in the canvas app.

Attempt 2: Flow magic. I didn’t want to head this route, but since DataSourceInfo did not work, I had to use Flow to solve the problem. Solution is one of the restricted CDS entities. Only certain roles have access to read this entity OOB. Below are those roles.

Privileges.png

So, I am using this as the flag to show or hide canvas apps controls. Below is my Flow.

Flow.png

There are two parallel branches, one if there is an exception while retrieving Solution records, which means that the user cannot read “Solution” entity and another branch if they have read privilege on “Solution” entity. Depending on which branch the Flow takes, “canread” can be true or false. I can use the result to show or hide controls on the canvas app. The two branches have the appropriate “configure run after” set.

configure run after.png

Branches.png

The clunky bit about this, which I don’t like is that fact that Flow will report that the execution has failed, when Flow takes the “Cannot read Solutions” branch.

Flow result.png

In the programming world, handling an exception appropriately and continuing like nothing happened, is not considered a failure, but it looks like Flow has a different opinion on this.

Potential improvement to the design: Create a new CDS entity called “Canvas App Permission” and create attributes on this entity, to manage which areas in Canvas App should be shown or hidden. Create multiple records of this new entity and assign this to teams or individual users, depending on how you want the permissions to be applied in canvas apps. The Flow can then retrieve this entity, and PowerApps can use this result of the Flow to hide/show areas or functionality.

Hope this is useful. Credit to Geetha for coming up with the original idea.

Building Spirograph using PowerApps

Over the past few weeks, people have been demonstrating some cool games, built entirely using PowerApps. The reason being, that there was a contest from ThoseDynamicsGuys. If you are interested in finding out about some interesting games from this contest, watch this video from Mr.Dang himself -> https://www.youtube.com/watch?v=0-ZWqs_emQA where he reviews the games.

There were some apps that caught my eye during this period:

  1. Power Flappy by Scott Durow
  2. Power Roulette by Geetha Sivasailam
  3. Coin Dog by Makato Maeda
  4. Air Resistance by Nagao Hiroaki

I was especially fascinated by what Scott and Makato accomplished with the side scrolling nature of the games, how Geetha managed to rotate the roulette as there is no rotate angle property on images and how Nagao managed to calculate the trajectory and resistance of the ball. The first step to learning is to understand how other people do it, so I spend 4-5 days to understand how these apps have been developed.

I then wanted to develop something of my own, using the concepts that I had learnt. Spirograph was the first thing that I thought of. The easiest part was to get the equations to calculate x and y. I had to then learn the basics of starting and stopping a timer, and how to create a sense that the pattern was being “drawn”.

Since image control can render SVG, I decided to try this approach. My first challenge was how do I calculate the x and y on every tick of the timer. So, I decided to follow the approach demonstrated by Brian Dang, that involve checking and un-checking a toggle control.

Every time the toggle is checked, I can increment the iterator variable and calculate x and y for the line to be drawn and the string for the SVG path with all the lines. In SVG you can draw a line, by moving to a location specifying Mxy and then drawing the line using Lxy. Below is the formula in the OnCheckĀ event of the slider

Set(VarI, VarI+1);
UpdateContext({x:
(((RSlider.Value-rSlider.Value) * (Cos(rSlider.Value*VarI/RSlider.Value))) + (aSlider.Value * Cos(VarI*(1-(rSlider.Value/RSlider.Value))))),
y:
(((RSlider.Value-rSlider.Value) * (Sin(rSlider.Value*VarI/RSlider.Value))) - ((aSlider.Value * Sin(VarI*(1-(rSlider.Value/RSlider.Value))))))
});
Collect(Lines, {Row: VarI,
X: x,
Y: y});
Set(PathVar, PathVar & If(PathVar="", "M", "L") & x & "," & y);
true

I can then simply set the SVG path’s d property from the PathVar variable, that has all the line co-ordinates. Below is the value for the Image property of the Image control that renders the Spirograph.

SVG Path.png

Below a video of the app in action. You can play around with the sliders and be fascinated by the patterns that it generates.

Spirograph.gif

Here are some interesting patterns the app generated.

You can download the app from the PowerApps Community Gallery -> https://powerusers.microsoft.com/t5/Community-Apps-Gallery/Spirograph/m-p/175447

References:

SVG Paths – https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Line_commands

Math behind Spirograph – http://www.mathematische-basteleien.de/spirographs.htm