Introduction
In certain implementations, we must restrict manual movement of Stages in BPF for a selected record as a business requirement. To achieve this functionality, we can use JavaScript to restrict movement of next and previous stage.
Step 1
Login to the required environment and go to flows and select Business process flows – Vaccination and observe whether BPF is active or not, if not then activate it as shown in the below figure.
Step 2
After Step 1, under contact customizations solution [my custom crm solution] create a web resource with name RestrictStages and publish all customizations as shown in the below figure.
Step 3
After Step 2, open RestrictStages webresource as we are working on contact entity, provide the required unique name for identification , under form events provide the following method code under form_load method get formcontext and register and call handleStage Movement method as an parameter to addOnPreStageChange method of formcontext and code looks like below
form_load: function (e)
{
var formContext = e.getFormContext();
// use the below code to remove a registered event handler.
//formContext.data.process.removeOnPreStageChange(Contact.formEvents.handleStageMovement);
formContext.data.process.addOnPreStageChange(Contact.formEvents.handleStageMovement);
}
as shown in the below figure.
Step 4
After Step 3, under handleStageMovement method, write down the logic to hold eventargs under a variable bpfArguments and write blocks to hold condition to fetch direction using getDirection() method with Previous and Next Strings as shown in the below code
handleStageMovement: function (e) {
debugger;
// get the event arguments
var bpfArguments = e.getEventArgs();
if (bpfArguments.getDirection() === "Previous")
{
// Write your custom logic like provide access to specific roles only.
}
if (bpfArguments.getDirection() === "Next")
{
// stop the stage movement
// Write your custom logic like provide access to specific roles only.
}
}
as shown in the below figure.
Step 5
After Step 4, under condition blocks of Previous and Next write the logic to undo the action with preventDefault() method and form a nice dialog to show user a meaningful information and stop process with the below code
if (bpfArguments.getDirection() === "Previous")
{
// Write your custom logic like provide access to specific roles only.
bpfArguments.preventDefault();
var alertStrings = { confirmButtonLabel: "OK", text: "Back stage movement is not allowed", title: "Cannot Move to Prev Stage" };
var alertOptions = { height: 200, width: 300 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions);
return;
}
if (bpfArguments.getDirection() === "Next")
{
// stop the stage movement
// Write your custom logic like provide access to specific roles only.
bpfArguments.preventDefault();
alertStrings = { confirmButtonLabel: "OK", text: "Next stage movement is not allowed", title: "Cannot Move to Next Stage" };
alertOptions = { height: 200, width: 300 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions);
return;
}
as shown in the below figure.
Step 6
After Step 5, the full code looks like below
var Contact;
Contact = {};
Contact.formEvents = {
form_load: function (e) {
var formContext = e.getFormContext();
// use the below code to remove a registered event handler.
//formContext.data.process.removeOnPreStageChange(Contact.formEvents.handleStageMovement);
formContext.data.process.addOnPreStageChange(Contact.formEvents.handleStageMovement);
},
handleStageMovement: function (e) {
debugger;
// get the event arguments
var bpfArguments = e.getEventArgs();
if (bpfArguments.getDirection() === "Previous")
{
// Write your custom logic like provide access to specific roles only.
bpfArguments.preventDefault();
var alertStrings = { confirmButtonLabel: "OK", text: "Back stage movement is not allowed", title: "Cannot Move to Prev Stage" };
var alertOptions = { height: 200, width: 300 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions);
return;
}
if (bpfArguments.getDirection() === "Next")
{
// stop the stage movement
// Write your custom logic like provide access to specific roles only.
bpfArguments.preventDefault();
alertStrings = { confirmButtonLabel: "OK", text: "Next stage movement is not allowed", title: "Cannot Move to Next Stage" };
alertOptions = { height: 200, width: 300 };
Xrm.Navigation.openAlertDialog(alertStrings, alertOptions);
return;
}
}
};
as shown in the below figure.
Step 7:
After Step 6, save and publish webresource and now navigate to contact form classic way and add this webresource- restrictstages javascript file and register under OnLoad Event and publish contact form and navigate back to Contact customizations solution and publish all customizations as shown in the below figure.
Step 8:
After Step 7, navigate back to contact entity and open contact record and try to manually try to change to next stage, user will encounter a popup as shown in the below figure
Note:
- In this article, I have concentrated on actual logic on javascript where placeholders are provided to get directions of BPF Stages moments.
- We can include in the logic like providing access to specific roles for movement of stages for others restriction, have not included role related logic was explained in earlier posts.
- Basic knowledge of registering and working with webresource is required to understand clearly.
- Even user cannot make previous stage as an active stage as shown in the below figure
- Auto save will also not happen if user clicks on any stage.
Conclusion: In this way, one can easily write JavaScript code to restrict direct Manual stage movement for a given business requirement with minimal code.