How to achieve Delay in State Machine Workflow - workflow-foundation-4

Windows Workflow State Machine
has a state (AwaitingFeedbackState) with two transitions.
Transition 1) awaiting receive message from client within "Trigger" body, email activity within "Action"
Transition 2) CheckReminderEnabledActivity within "Trigger" body, delay and email reminder activity within "Action"
when CheckReminderEnabledActivity is true, the behaviour works fine, the work flow goes into delay but if it is
set to false, the workflow infinity loops in AwaitingFeedbackState, keeps hitting CheckReminderEnabledActivity.
Is there a way to disable this transition if CheckReminderEnabledActivity is set to false when process enters CheckReminderEnabledActivity for
the first time ?

I have fixed this by bringing in the delay and send reminder activity within the trigger body and have now also added if else as well. In the else body I have added a custom bookmark as per example here
https://code.msdn.microsoft.com/Windows-Workflow-50c3fba5

Related

How to catch click to dial events in Unified Service Desk?

The event raised by clicking on a phone number will either be of the form "tel:" or "skype:". Here are the steps I've followed so far to enable a window navigation rule to capture the event, and I've attached events to the rule to actually see the action get fired in the Debugger. Still, even with navigation rules set to capture tel: and skype:, the action will never fire in USD Debugger. Here is the general approach I've used so far (From another post):
Create a Windownavigation rule.
Don't put anything into the entity Settings but put "tel:" or "skype:" into the URL TextBox.
Routetype will be Popup
Target will be Tab (or registercard, at least I think that's the name for it in english - I'm using a german one)
Define None as Action in result for your Windownavigationrule
Create your own Action to resolve when the Navigation rule is triggered
Set your own hosted control (In this case I use the CTIConnector class.)
Define an Actionname for your Action that will be exectued (I named it "MakeCall" in CRM)
Set Data to [[SUBJECTURL]] so the URL ist given to the Action als Parameter.
Override the method DoAction from your hosted control
Just 2 -3 points to verify.
Do you have a UII action with the name "MakeCall"? If that is there then only your code will be triggered from DoAction.
In case, if you have above in place please check whether your action calls and other records are added to the respective configuration reocrd?

How to Persist Previous Events in Google Tag Manager

I need it to build a specific Events Flow - for certain buy-buttons that refer to corresponding paywalls and success-pages in order to find out what buttons/paywalls are more efficient.
My website is an SPA. I use History Change triggers instead of Page View triggers (Old/New History State is what changes when surfing web pages).
There is a chain of actions:
Paywall-button click from a /page-1 to /subscription;
Paywall view (History) on a /subscription;
Authorisation (eg. on a Form Subscription event) on a /subscription;
Subscription-button click on a /subscription;
Subscription success on a /subscription/success (let's name it "Subscription Success 1").
However, there are other ways to reach /subscription/success (let's call it "Subscription Success 2"). For example, when step-1's click occurs on a big set of other pages (not /page-1)).
On the step-5, I made a special Tag that tracks "Subscription Success 1". It is based on a Trigger-group-1 that tracks success page's URL and a Paywall-button click from step-1.
So, in order to track "Subscription Success 2", I need to set up a Trigger exception on either Trigger-group-1 or on a Trigger that is responsible for Paywall-button click on the step-1. But it doesn't work like this: "Subscription Success 2" Tag fires anyway.
How to solve it? How to persist that 1st step's event and use it as an exception?
You could create a cookie that will save a value for the first event and then use the value as a trigger/exception for your tag.

Anywhere re-orders the sequence of the transactions

We noticed that Anywhere is grouping and ordering the transactions such that the transactions for the parent [i.e.: Work Order] were sent first and then the transaction for the child records [e.g.: Specifications]
Scenario:
Step 1. Alter the description on the WO
Step 2. Enter Specification values
Step 3. Change the WO Status to COMP
The resulting transactions are sent as follows
Step1 and Step3 are grouped and sent to Maximo
On success
Step 2 is sent to Maximo
We want the messages to be sent in the same order that they happened and the reason for this is the validations we have in place in Maximo
e.g.: We validate if the child table has records [in our case, we check if the specifications are populated] before we Complete a WO
Due to the re-order of the events\transactions we are unable to COMP a WO from the device as the child transaction never gets to Maximo because the Parent transaction failing due to missing child data [catch 22]
We found the piece of code in the [/MaximoAnywhere/apps/WorkExecution/common/js/platform/model/PushingCoordinatorService.js] JS file that does this re-order and we commented out the reorder
//if (!transaction.json[PlatformConstants.TRANSACTION_LOCK_FORUPDATE])
//{
// Logger.trace("[PUSHING] Trying to shrink/merge transactions and lock transactions");
// var self = this;
// var promise = this._shrinkSubTransactions(metadata, transaction);
//
// Logger.trace("[PUSHING] going to perform async operations");
// promise.then(function() {
// self._pushSubTransactions(transaction, deferred);
// });
//}
//else
//{
Logger.trace("[PUSHING] going to perform async operations");
this._pushSubTransactions(transaction, deferred);
//}
Once this was done we were able to COMP the WO from the device as the events/transaction are now sent in the same order as they occurred
However, we have noticed that this has created another undesirable problem where on an error the device ends up with two Work Orders the one with the error and the one it refetched from Maximo
Scenario: We have an active timer running on the WO and we click on the clock. This will bring up the Stop Timer View and we select [Complete Work]
So there are two things that should happen the timer should be stopped and the status should be changed.
Due to some validation error from Maximo this transaction fails. The result is that we end up with the same wok order twice one with the new status and the error message and one it re-fetched from Maximo
Once we go into the record with the error and undo the change we end up with two identical WOs on the device
Apart from the above issue, there needs to be a way to clear the local data from the device without having to delete the app
You could try putting some Model.save()'s in, or in the app.xml you can force a save when you show/hide a view.
Without the saves I think that everything gets put into one change ... sent as one message ... and you lose control over how it gets unpicked.
Diggging this one up from the grave, but you can create something called a "priority transaction" that will capture all changes and package them in an isolated request and send it back to the server.
westarAssignmentStatusChange:function(workOrder){
workOrder.openPriorityChangeTransaction();
workOrder.set(ATTRIBUTE,VALUE);
workOrder.closePriorityChangeTransaction();
};
This will send an update to the server to change the ATTRIBUTE of the WORKORDER to VALUE.
We used this to isolate changes of specific items and made sure they processed in the appropriate order.

how to check if page finished loading in RSelenium

Imagine that you click on an element using RSelenium on a page and would like to retrieve the results from the resulting page. How does one check to make sure that the resulting page has loaded? I can insert Sys.sleep() in between processing the page and clicking the element but this seems like a very ugly and slow way to do things.
Set ImplicitWaitTimeout and then search for an element on the page. From ?remoteDriver
setImplicitWaitTimeout(milliseconds = 10000)
Set the amount of time
the driver should wait when searching for elements. When searching for
a single element, the driver will poll the page until an element is
found or the timeout expires, whichever occurs first. When searching
for multiple elements, the driver should poll the page until at least
one element is found or the timeout expires, at which point it will
return an empty list. If this method is never called, the driver will
default to an implicit wait of 0ms.
In the RSelenium reference manual (http://cran.r-project.org/web/packages/RSelenium/RSelenium.pdf), you will find the method setTimeout() for the remoteDriver class:
setTimeout(type = "page load", milliseconds = 10000)
Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client.
type: The type of operation to set the timeout for. Valid values are: "script" for script timeouts, "implicit" for modifying the implicit wait timeout and "page load" for setting a page load timeout. Defaults to "page load"
milliseconds: The amount of time, in milliseconds, that time-limited commands are permitted to run. Defaults to 10000 milliseconds.
This seems to suggests that remDr$setTimeout() after remDr$navigate("...") would actually wait for the page to load, or return a timeout error after 10 seconds.
you can also try out this code that waits for the browser to provide whether page loaded or not.
objExecutor = (JavascriptExecutor) objDriver;
if (!objExecutor.executeScript("return document.readyState").toString()
.equalsIgnoreCase("complete")){
Thread.sleep(1000);
}
You can simply put it in your base page so you wont need to write it down in every pageobjects. I have never tried it out with any AJAX enabled sites, but this might help you and your scenario dependency will also get away.

Get ASP.NET Session Last Access Time (or Time-to-Timeout)

I'm trying to determine how much time is left in a given ASP.NET session until it times out.
If there is no readily available time-to-timeout value, I could also calculate it from its last access time (but I didn't find this either). Any idea how to do this?
If you are at the server, processing the request, then the timeout has just been reset so the full 20 minutes (or whatever you configured) remain.
If you want a client-side warning, you will need to create some javascript code that will fire about 20 minutes from "now". See the setTimeout method.
I have used that to display a warning, 15 minutes after the page was requested. It pops up an alert like "your session will expire on {HH:mm}, please save your work". The exact time was used instead of "in 5 minutes" as you never know when the user will see that message (did he return to his computer 10 minutes after the alert fired?).
For multi-page solution one could save last request time in cookie, and javascript could consider this last access time for handling warning message or login out action.
I have just implemented a solution like the one asked about here and it seems to work. I have an MVC application and have this code in my _Layout.chtml page but it could work in an asp.net app by placing it in the master page I would think. I am using local session storage via the amplify.js plugin. I use local session storage because as Mr Grieves says there could be a situation where a user is accessing the application in a way that does not cause a page refresh or redirect but still resets the session timeout on the server.
$(document).ready(function () {
var sessionTimeout = '#(Session.Timeout)'; //from server at startup
amplify.store.sessionStorage("sessionTimeout", sessionTimeout);
amplify.store.sessionStorage("timeLeft", sessionTimeout);
setInterval(checkSession, 60000); // run checkSession this every 1 minute
function checkSession() {
var timeLeft = amplify.store.sessionStorage("timeLeft");
timeLeft--; // decrement by 1 minute
amplify.store.sessionStorage("timeLeft", timeLeft);
if (timeLeft <= 10) {
alert("You have " + timeLeft + " minutes before session timeout. ");
}
}
});
Then in a page where users never cause a page refresh but still hit the server thereby causing a reset of their session I put this on a button click event:
$('#MyButton').click(function (e) {
//Some Code that causes session reset but not page refresh here
amplify.store.sessionStorage("sessionTimeout", 60); //default session timeout
amplify.store.sessionStorage("timeLeft", 60);
});
Using local session storage allows my _Layout.chtml code to see that the session has been reset here even though a page never got refreshed or redirected.
You can get the timeout in minutes from:
Session.Timeout
Isn't this enough to provide the information, as the timeout is reset every request? Don't know how you want to display this without doing a request?
Anyhow, best way is on every request setting some Session variable with the last access time. That should provide the info on remote.

Resources