Delay vs Delay Until

Both of these are wait conditions used to delay processing in your flows. But what’s the difference? Let’s understand with an use case application.

Theoretically:
They come under the Schedule Action:


DELAY – Adds a fixed delay before the next step in a certain unit of measurement. Thus just tell the count in 1,2,3…… & choose the desired unit.

Power Tip 1: Here I would like to point out that I think Microsoft has just included the “Month” option for the sake of completion, but you should never use it. Flows have a 30 days max runtime, so after that time, regardless of what step you are, the Flow will timeout. So defining anything above that time will never be executed. Its like a complete NO NO to use.

DELAY UNTIL- adds the delay until a specific timestamp. Thus add the timestamp in ISO8601 format.

Power Tip 2:  The flow considers the Time in UTC timezone. Thus make sure to convert the Timezone to UTC before passing it in the delay until step. Below is the formula to help achieve this.

convertToUtc(‘timestamp’,’SourceTimeZone’,’yyyy-MM-ddTHH:mm:ssZ’)

Power Tip 3: The format of the date and time is very important here. If you use any different format, you will find that the Delay Until step fails with the following error.

Now lets see the application.

Business Scenario: Remember the example we took in my BLOG38 , where in a Lead we could dispose it off as “Call back required”. Well you may save the Call back Time in units of measurements like 10 mins, 30 mins, 1 hour etc as the Business Requirement is OR at a particular Time which the customer asks for.
Let’s explore both of these scenarios here.

Scenario 1: Say we give the Call back Time in a span of duration(the unit is predefined here).

Thus we see that the Delay Steps waits for 2 minutes before the next step.

Scenario 2: The Customer gives a proper timestamp to call them back.

Thus we see that the Delay Until Steps waits for till it is 10:38(IST-5 hours 30mins) before the next step. PS: The time is in UTC

So now you know how it works, but still it has certain improvisation to be done.

Problem 1: If the target date or duration is more than a month, then the flow fail would fail as the 30 day limit would be breached.

Problem 2: If the entry has been updated after the initial flow had been initiated (e.g. the Lead calls back and tells to call him back after 5 mins instead of 15), the initial flow would still be running and therefore continue to wait for the original target date/time & the new one will trigger a flow too. As the Callback time is not revised and 2 flows are running simultaneously to perform a single task, we should stop the initial flow somehow.

Well if there’s a problem, there’s a solution.

Solution for Problem 1: In such cases use a scheduled flow and run that at proper intervals suiting the Business Requirement.

Solution for Problem 2: Here use a flag field and change it on change of the Disposition.

Now check this field before and after the Delay Action. If its different, terminate the flow otherwise create a Phone Call .

Test Scenario: I am disposing the Lead twice now- first one with 5 min interval & another with 1 min.

Output: The flow with 5 min interval terminates because the flow with 1 min interval already ran before it.

The Flow with 1 min interval runs successfully.

Hope it helps!

& the Power Quote of the day is:

“The Mind is everything! What you think is what you become”

Closure of Opportunity when Work Order is created via Power Automate

Business Scenario: When an Opportunity is converted to “Work Order”, it should be closed.

Solution: Trigger would be on creation of Work Order

Take 1: I tried to change the Status of Opportunity directly by using “Update a row” action

It did not work!

Take 2: I tried to use the action “Perform an Unbound Action”-WinOpportunity.
Here I was presented with this gigantic amount of fields to be filled up which were not even clear.

Still I went ahead and tried to fill it with the values I needed for Opportunity Closure.

Still no Success!

Take 3: Finally I twisted this method and in the Action name, I selected the option of “Enter Custom Value”

Then I used the expression: trim(‘WinOpportunity’)

Please Note: The EntitySetName cannot be directly entered in the custom value textbox. The flow designer will render the step as the table-specific action with the parameters from the entity. If you use the expression builder and enter as a string literal (e.g. ‘WinOpportunity’), the flow designer will render the step as the table-specific step as in the previous case. To make sure that the step is rendered as a generic step, use a string function in the expression builder (e.g. trim(‘WinOpportunity’)  ) and the end result would be that the Action Parameters will become one single multiline textbox and populate it with a JSON object whose format is given below:

{
“OpportunityClose”: {
“opportunityid@odata.bind”: “opportunities(GUID)”,
“actualrevenue”: ,
“statuscode”: 2,
“actualend”: “”,
“description”: “Test Opportunity Close”
},
“Status”: 3
}

Let’s convert the Opportunity to Work Order now!

We see from the above image that the Work Order was created successfully.

Lets check the Flow now:

The Flow even ran successfully and we can see that the Opportunity is closed with the Status “Won”.

Hope it helps!

& the Power Quote of the Day is:

“If you get tired, Learn to Rest not to Quit”

Generate “Invoice” and change Work Order Status to “Posted” via Power Automate when the Booking Status is Completed

Business Scenario: When the Booking Status is Completed, first change the Work Order Status to “Posted” and then generate an Invoice via Power Automate. This should happen only in the case when the work order is generated from an Opportunity.

Solution: We are creating an automated cloud flow with the trigger as “When the Booking Status is modified for the Bookable Resource Bookings table”

Then we are checking if the Booking Status is “Completed”

If Yes, then we are changing the Work Order System Status to “Posted

I am terminating the flow if the Work Order is not generating from “Opportunity”

Then i am adding an Invoice record in “Invoices” table

Please note here the Price List field is referred to as: “pricelevels“.

Then we are listing all the “Work Order Products” related to that Work Order

Then we will apply to each work order product and get the Product Details

Then we will add it to “Invoice Products” with the given Invoice ID

Please note that the Units are referred as “uoms

Then we will list all “Work Order Services” related to the work order.

Get the Service Product details:

then add it to Invoice Products against the Invoice ID:

Let us now run the flow- The flow ran successfully:

Hope it helps!

& the Power Quote of the day is:

“The best way to predict your future is to create it” ~ Abraham Lincoln

Terminate a Flow

There are a lot of use cases when we have to terminate the Flow/Power Automate if the condition is not met OR when we have to test the flow and run just a part of it to see the results without going till the end of flow OR to end the flow correctly by declaring that it wasn’t successful instead of leaving the flow just like that.

Here the ‘Terminate’ control can be used to achieve all of this. It forces the flow to end wherever that action is placed and is executed in a branch.

The Terminate control gives us the option to set the status. We can set it to FailedSucceededCancelled, or even add a Custom Value.


If we select the Status as “Succeeded” or “Cancelled“, it will ask just for the Status Input simply.


Cancelled” status becomes useful to differentiate between successful flows and the flow which ran successfully without serving any purpose.

This also helps when we check the “Run History” of the flow – we get to know that the flow was Cancelled coz it faced certain conditions which didn’t meet the criteria.

If you select “Failed” , it gives you option to provide error code and error message.

If you choose “Enter custom value” for Status, It will throw an error while saving the flow. Hoping that Microsoft will fix this issue soon.

Thus you can just use the 3 OOB Statuses for the time being.

Note: Terminate control will terminate the entire flow and not any specific branch .

All things considered, the Terminate action control is indeed an essential element in Power Automate. There are times when user inputs don’t meet certain conditions and we tend to leave the flow like that. This is where the Terminate action control becomes useful. We can just use the Terminate control to properly end a flow run by declaring that it wasn’t successful.

There are a lot of cool things that we can do with this control!

Also, an important thing to note is that the control “Terminate” cannot be used inside an iterative control for example “Apply To Each”

Hope it helps!

& the Power quote of the day is:

“Never try to fit in, coz you are born to stand out”

Want to Save the form again after changing the field values to the same value in Dynamics CRM?

Business Scenario: Many a times the client asks for the scenario that whenever they are removing and then again saving the same value in a field, they should be able to save the form to do the activities which happens on save of that form. Say when we dispose off the same lead with the same disposition, how will CRM know?

In Dynamics365, we see that if you choose the same value again, it doesn’t let’s you save only as there is no change for it. What if we wanted the option of saving it!?

Well here is one of the ways, & do let me know if any other way is possible.

Use Case: In Call centres, the agents dispose off the calls of leads with certain dispositions which may or may not be same in consecutive call tries. In case it would be same, we need a save trigger.

Solution: What I have done is created a new “Single line of Text” type of field named “dispositiontrigger” and placed it on the form but have hidden it.

Now on change of the Required field(Disposition) I am populating a random guid on the Hidden field & hence the form calls for a Save and we get our “On Save” trigger. Also this flag field can be utilized to get trigger columns for Power Automate.

Code: Write the following JScript and trigger it on Change of “Disposition” field

function DispositionChange(eContext)
{
var formContext = eContext.getFormContext();
var field = formContext.getAttribute(‘new_disposition’);
if (field != null)
{
if(field.getValue() != null)
{
var str=gen() + gen() + ‘-‘ + gen() + ‘-‘ + gen() + ‘-‘ + gen() + ‘-‘ + gen() + gen() + gen();
formContext.getAttribute(‘new_dispositiontrigger’).setValue(str);
}
}
}
function gen()
{
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}

Outcome: Let’s check out the results.

Thus we see that it is prompting as “unsaved” and is asking us to save the form again.

Hope it helps!

& the Power Quote of the day is:

“If its makes you happy, It doesn’t have to make sense to anyone else!”

Don’t want to Trigger Power Automate Flows unnecessarily to save the number of Flow Runs – Use Filtering Conditions

Well! we all write a lot of Flows in our project with triggers and then check for certain conditions, if it meets well and good, if not , we either terminate it or do nothing. But the fact is the flow still runs & is counted as an API call. When it goes to the actual Production with real-time number of runs, often we have seen that the flows are running and spending the quota very quickly. This is because of the unnecessary runs which are triggering without delivering any value . Trigger conditions protect us from that.

Trigger Conditions are basically like expressions to determine an outcome of TRUE or FALSE which will decide that whether the flow would be triggered or not !? 

For example, Remember the example we took of creating Email from Case record. Here we chose the Trigger as “When a row is added” and then checked whether the regarding type of entity is incident. Well in this case the flow is triggered every time an Email was created irrespective of whether it was created from an Account, Contact, Case , or any table or as a standalone Email. Thus the flow was triggered unnecessarily and was terminated eventually, adding no value and wasting the flow runs.

As a solution, what we will do is
Step 1: Go to the Trigger “When a row is added, modified or deleted” and click on the three dots, then click on the settings as shown below:

This image has an empty alt attribute; its file name is image.png


Step 2:Locate “Trigger Conditions” towards the end >> Click on “+Add”

This image has an empty alt attribute; its file name is image-33.png

Step 3:If you are an expert in writing Expressions, just go ahead and start writing if not then you can write it in the Expression provided in the Power Automate in any other step of the flow and copy it here. Just make sure you place the special character “@” in front of it always.

I have written the following Expression for comparing the RegardingType of Email to Entity Type ‘incident’ i.e. the Case:

@equals(triggerOutputs()?[‘body/_regardingobjectid_value@Microsoft.Dynamics.CRM.lookuplogicalname’],’incident’)

PS: I got the first parameter of Equals simply from the condition variable I used in the Condition Action- you may either hover on it to see the value or copy it directly.

This image has an empty alt attribute; its file name is image-35.png



Step 4:Click on Done and remove the condition step from beneath as you longer need to again check it and save the Flow.

This image has an empty alt attribute; its file name is image-34.png

Outcome: So now when we create an Email from case, we see that it runs successfully but when we create an Email from Contact, it doesn’t run at all. Thus saving us a mammoth amount of flow calls which are counted as API request. Thus saving us from reaching the API request limits faster.

We see that this is a much much more efficient way of writing Flows where the condition is checked at the onset rather than doing the check once the automation has started.

Additional Advantages:

1.Using trigger conditions, one can control the flow to execute or not. This also prevents generating unnecessary entries in RunHistory

2.If your Trigger Condition is not correct, the Flow will prompt you during Save.

3. You can also secure the trigger inputs/outputs in the run history of a cloud flow. To do this, you can turn on the secure input and/or secure output setting in the trigger.

This image has an empty alt attribute; its file name is image-37.png

Hope it helps! Explore other settings here too.

& the Power Quote of the day is:

“The world is full of obvious things which nobody by any chance ever observes” ~Sherlock Holmes

Connection vs Connection Reference in Power Automate

You would have noticed towards the right side of the flow that

Sometimes its written “Connections” &

Sometimes its written “Connection References” .

So what’s the difference and which one to use ?

Well!

A connection is a way for users to connect their logged in accounts and use a set of pre-built actions and triggers to build their flows. This is when we create our flows under the “My Flows” tab i.e. when a flow is not in a solution it uses connections. If that flow is then added into solution, it will continue to use connections initially But we can change it to Connection Reference anytime. How? You will get to know after reading this Blog.

A connection reference in turn is a solution component that contains information about a connector. You can import your connection reference into a target environment with no further configuration needed after the import completes and this is the main USP of it. These are particularly useful when moving flows across environments, updating flow definitions, automating deployment pipelines for secure, and having a healthy Application Lifecycle Management.

Flows created in a solution are known as solution-aware flows. You can add multiple flows in a single solution. The biggest difference between Connection and Connection reference usage is capability of Solution-aware working. The flows which include “Connection” will be turned off after the deployment via solution and the connections needs to be re-established. But any flow which use only “Connection Reference” will not cause any problem after the deployment. No manual step is needed after deploying the solution.

Ensure that the Connection Reference is inside the same solution as the flow and for this create or add a Connection Reference in the same solution. When an action is added to a solution flow, Power Automate will try to reuse existing Connection References from the current solution or other solutions before creating a new Connection Reference.

It is however important to understand how flows and connections are associated with each other.

Every action in your flow is bound to a specific instance of a connection that it will use to “execute” that action. This is why today, while moving flows across environments – users are required to rebind every operation to a connection.

[Connections contain secrets, and therefore can’t be moved across environments]

Let’s visualize it, here each dotted line indicates a link that requires rebinding after importing or updating a flow via a solution.

Flows without connection references

When you move these two-flow across environments – all the links shown by dotted lines are severed and have to be re-established and switched on after performing an update or import.

Connection references provides an abstraction layer between flows and the connections they use. As mentioned, these are solution-aware components that contain a reference which associates the connector used and the flow it resides in. When importing a solution, that contains a flow, from one environment to the other, it prevents you from needing to open the flow and re-establish connections.


Flows with Connection References

There are a lot of Benefits of Connection Reference and some of them are listed here:

  • Updating the value of a connection reference will automatically update the flows using the connection reference as opposed to updating every operation.
  • Connection references offer semantic value with editable display names and descriptions. Eg – A connection reference named “Service Account” can point to a connection named “svcaccount1@contoso.com”; this provides for improved discovery, selection and organization of connections.

Conclusion: Maintenance of unconsciously created flows will become more difficult as the number of flow increases. As a result, we need to know the exact difference between the two. If you are working with one of Dynamics 365 project and decide to use Cloud Flows, then keep all the Cloud Flows under one Solution with a Connection Reference as part of that solution pointing to only one Connection which is created with specific account only. (Make sure that all flows are run only with one user who is admin). Its easier to track it this way too as it will appear in the Audit History. Also as a good practice, remove Duplicate Connection and Connection References which is not necessary.

Next, we would learn How to convert a Connection to Connection reference?

Flows can be updated to use connections references instead of connections in one of two ways:

  1. If the flow is exported in an unmanaged solution and imported, the connections will be removed and replaced with connection references.
  2. When a solution flow is opened, the flow checker on the flow details page will show a warning to Use connection references. The warning message contains an action to Remove connections so connection references can be added. Clicking that action will remove connections from the trigger and actions in the flow and allow connection references to be selected and created.

Lastly, there is a Power Tip here: Recently you might be facing the issue where if you open the output of a certain action step, the screen starts flickering. If you are facing the same, just zoom out and zoom in few times, it will become stable.

Hope it helps!

& the Power Quote of the day is:

“A genius is a man who can do the average thing when everyone else around him is losing their mind.”

How to send Email to a recipient which is not stored in Dynamics365 via Power Automate?

Business Scenario: In a lot of cases, we have a requirement where we have to send Email to a person who is not stored as a Contact,Account,User, etc in the system. They are called “unresolved recipients”.
So how to send to send them Emails?

Solution: Well, Dynamics365 offers a change in System Settings which makes it possible.
Step 1: Navigate to System Settings

Click on the gear icon and select Advanced Settings:

Change the area to Administration:

Select “System Settings”

Move to the “Email” tab and change “Allow messages with unresolved email recipients to be sent” to “Yes” >> OK

To know more about Email System Settings- go to this link:
https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/admin/system-settings-dialog-box-email-tab?view=op-9-1

Step 2: Now let’s start writing our flow.

The scenario which we have chosen is there is a custom field in Case Table known as “Requestor Email” and is filled with an Email ID which is not stored as any Contact/Account or User email but the customer wants the communication for this case to be sent in that Email Id only.

Here in the flow step of creating the email record, we will populate the email address as an Activity Party instead of referencing any table like contact or user. Though I’ll also show you how to set a party list by referencing a table also here.

Here is a snapshot of the entire flow.

Trigger: When an Email is created
Action 1: We are initializing an object variable which will store the Json.
Action 2: We are checking that whether the regarding of Email is of type Case.
Action 3: If yes, we are getting the linked case else we are Terminating
Action 4: Once we have the case, we are checking that whether the field Requestor Email is having any email id or not.
Action 5: If Yes, then we are setting the Party List variable as follows, else we are terminating it.

Since we cannot choose from a list of values like To, From, etc we will use “participationtypemask” value which will decide the attribute value. It is an integer and the main ones are as follows:

Activity party type Value
Sender 1
 ToRecipient 2
 CCRecipient 3
 BccRecipient 4

For other value of Activity Party Types, refer to https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/activityparty-entity?view=op-9-1

Further, the email address needs to be populated in “addressused” attribute.


Action 6: Finally we are updating the same Email record which was triggered and replacing the “To” i.e the recipient from the oob behaviour to our desired one.

To enter the JSON string as an Activity Party, click on “Switch to input entire array” at the right top corner of Activity Party section.

Then select the variable as the Activity Party.

Also please note once we are overriding the OOB behaviour, we also have to update the value of “From”. Over here, I’ll show you how to fill up a Party List in a different way.

Click on “+Add new item” and then select the attribute as shown below:

Then in the value section write, /entityname(<guid>) which you want to refer.

Save and Run the flow and then create an Email from the Case Timeline. We see that the flow has run successfully.

& there is an email created as follows:

You may see it in the Timeline too.

This is also useful when we have to send email to emailaddress2 or 3 and not the primary email.

Hope it helps!

& the Power Quote of the day is:

“The worst enemy to creativity is self-doubt.”
—The Unabridged Journals of Sylvia Plath by Sylvia Plath

Null Checks in Power Automate-Empty() vs Equals()

Hello everyone! I am back with another tiny Power Mantra which we should follow while making Power Automate Flows.
Say, we have a scenario where we are updating a row in Dataverse with certain dynamic values but what if those Dynamic Values are not present during the Flow Run. Thus we should always have Null or Empty check while we are updating a value. But which one to use when and what is the difference? Let’s explore it here!

Scenario: I have 3 tables storing the city, state and country respectively. Then I have a table called as locations storing the combination of the above three tables. Here I have kept 2 records as follow:

Record 1
Here I have the all the 3 fields filled-up

Record 2
In this record, I have the Country data missing

Then finally I have a map table, where my requirement is if I select the city, the state and country should auto-populate.
Let’s see how can we do it.

This flow triggers as soon as a Map record is added. Then we are matching the city of this newly created record with the metadata entity “Locations”. We are listing down all such rows but are limiting the result to 1. These 2 steps will remain the same throughout.


Then we are updating the Maps record with the matching state and country.

Way 1: Here we will use Equals() function and I am writing the following expression:

For Countries -> if(equals(items(‘Apply_to_each’)?[‘_new_country_value’],null),null,concat(‘/new_countries(‘,items(‘Apply_to_each’)?[‘_new_country_value’],’)’))

For States -> if(equals(items(‘Apply_to_each’)?[‘_new_state_value’],null),null,concat(‘/new_states(‘,items(‘Apply_to_each’)?[‘_new_state_value’],’)’))

When we run this flow by selecting the above two cities, we see its a success in both the scenarios.

Thus we can use Equals() for dynamic elements from dataverse.

But we see that in case of complicated flows, where we have to save the data in a string variable, Equals() doesn’t work.
Wanna have a look ?

First look at the flow:

I am initializing 2 string variables at the onset.

Then I am testing with just country here, so I am doing a compose on the country value to show you the result and then using the following expression, I am filling up the country:

if(equals(variables(‘Country’),null),null,concat(‘/new_countries(‘,variables(‘Country’),’)’))

We see that the flow fails:


Even though we see the output of the variable as “null” but still it throws an error and equals() doesn’t work.
Way 2: But instead when we write:

if(empty(variables(‘Country’)),null,concat(‘/new_countries(‘, variables(‘Country’),’)’))

This works well, as also when we directly use empty with the fields it works, So what is the conundrum here ? Why is it working for one & not for the other !?

Well Well Well! Whenever the string variable is set to a null, Power Automate tries to convert it to an empty string and stores it as “” in the backend. That’s why the if(equals()) condition didn’t produce the expected output when we trying to compare it with null value. But when we used empty() it produces the expected result as the string is clearly empty.

Thus we should use the null compare for dynamic field values and empty comparison for string variable values .

This is also helpful while we are putting Condition actions with these expressions in the flow itself.

I hope “When should we use ‘null’ check and when should we use ’empty’ check? ” this is clear to you now.
For any queries, do ping me. Hope it cleared certain concepts!

Find the Functions() guide here: https://docs.microsoft.com/en-us/azure/logic-apps/workflow-definition-language-functions-reference#logical-comparison-functions

& the Power Quote of the day is:

“It’s the possibility of having a dream come true that makes life interesting.”
—The Alchemist by Paulo Coelho

Date Time Format in Power Automate – Simplified for you

Business Scenario: There are a lot of scenarios where we need specific formats for DateTime – say the case when you have to send a JSON where the receiver just accepts DateTime in a particular format or you want to display it to the user in a particular style or maybe you just want to extract some particular part from the Datetime or what day it is, which month, etc etc.

For all of the above scenarios, there is just one solution – formatDateTime()

The datetime by default comes like this: 2022-01-04T12:55:02.9280661Z which is NOT AT ALL convenient to read. Hence lets format it!

Here is an example from a simple flow:

When we run it:

Use this image to get the desired results: [Download this image to keep it handy]

Put the required date in DateTimeStamp and the required format within single quotes after the comma.

To know more about abbreviations, go to this link:
https://docs.microsoft.com/en-us/system-center/orchestrator/standard-activities/format-date-time?view=sc-orch-2019

You may also use some other separator other than ‘hyphen’ like ‘front-slash’ [/], etc.

Example: formatDateTime(utcNow(),’dd/MM/yyyy’)

Also you may explore other options of predefined patterns:

Example: formatDateTime(utcNow(),’D’)

To explore more pre-defined patterns, use this link:
https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings

Hope it helps!

& the Power Quote of the day is:
“If you fell down yesterday, stand up today” – H.G. Wells

Happy New Year!
May the year be opalescent in particular. May Life be iridescent in general’