Sunday, June 12, 2016

Programatically change the Business Process Flow/Stage - CRM 2015

With the automatic Form Refresh upon Save being unavailable in CRM 2015, the setting of the Active Stage of the Business Prcoess Flow bar through a Plugin/Workflow will result in 2/more flags to appear on the BPF bar, unless the form is refreshed after setting(The Active Stage setting through a JScript runs into issues, as the timing of Flag setting and then the Save Completion may not be Synced).
Which is not possible through a straightforward method, as we need to trigger a JScript on completion of our Plugin/Custom WF.
To combat this drawback, we need to programmatically refresh the form after the Active flag is set, which can be done through a few tricks.

We will need:
 2 Workflows-
-One for Create(If Stage needs to be set on Create)
-The other On update of the fields On which we need to set the Active Stage

3 JScript methods-
-One for refresh of form on Create(If needs to be set on Create)
-The Other 2 for refresh of form on trigger of the  Update WF mentioned above.

Step 1.If the setting of the Active stage flag is needed on create of a record, then, create a hidden text field to store the record Guid.
Step 2.If the setting of the Active stage flag is needed on Update of any field, then, create a hidden two Options field , this would be used to confirm that our Update WF has triggered.
Step 3.Custom WF to set the Active Stage
The source-code is available here:


Step 4.Design the  WF to trigger on Create(If wish to set the Active Stage flag on Create of Record)
Run this as a Real Time WF









The Update Step above is used to update the GUID of the record
(Field created in Step 1), Expanded as below:

 




 The Set BPF Step above calls the Custome WF, and Parameters are passed as below:


Step 5.Design the Update WF(If wish to set the Active Stage flag on update of Record)


 The Update Step as above is used to set the Refresh Flag(The field create in Step 2)





 To the Custom WF Call step, pass the parameters as menioned below:



Step 6.JScript to refresh form on Create(If wish to set the Active Stage flag on Create of Record)

function onChangerecordUrl() {
    Xrm.Page.data.setFormDirty(false);
    var recordUrl = Xrm.Page.getAttribute("<<recordUrlFieldLogicalName>>").getValue();
    var guid = recordUrl.split("&id=")[1];
    guid = guid.split("&histKey")[0];
    Xrm.Utility.openEntityForm("<<EntityLogicalName>>", guid);
}
 Replace the <<recordUrlFieldLogicalName>> with the Field name created in Step 1, replace <<EntityLogicalName>> as relevant.
Add this method to the Entity Library and register this as the OnChange Event Handler for the Fielkd created in step 1.Make sure this field is available on the form(Hidden field)

Step 7.JSript to refresh form on Update (If wish to set the Active Stage flag on Create of Record)

function onChangeModifiedOn() {
    var Id = Xrm.Page.data.entity.getId();
    if (Id != null && Id != "") {
        refreshFlagQuery = "<<entitySchemaName>>Set?$select=<<refreshFlagTwoOptionSchemaName>>&$filter=<<primaryKey>> eq (guid'" + Id + "')";
        var retrieved_refresh = makeOdataRequest(refreshFlagQuery);
        if (retrieved_refresh[0]["refreshFlagTwoOptionSchemaName"]) {
            Xrm.Page.data.setFormDirty(false);
            Xrm.Utility.openEntityForm("<<EntityLogicalName>>", Id);
        }
    }
}

function makeOdataRequest(query) {
    var serverUrl = Xrm.Page.context.getClientUrl();

    var oDataEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc/";
    oDataEndpointUrl += query;

    var service = GetRequestObject();

    if (service != null) {
        service.open("GET", oDataEndpointUrl, false);
        service.setRequestHeader("X-Requested-With", "XMLHttpRequest");
        service.setRequestHeader("Accept", "application/json, text/javascript, */*");
        service.send(null);

        var retrieved = JSON.parse(service.responseText).d;
        //debugger;
        var results = new Array();
        for (var i = 0; i < retrieved.results.length; i++) {
            results.push(retrieved.results[i]);
        }

        return results;
    }
    return null;
}
In the onChangeModifiedOn, do not forget to replace
 <<entitySchemaName>>
<<refreshFlagTwoOptionSchemaName>>
<<EntityLogicalName>>
<<primaryKey>>
As relevant.

Add these functions in the Entity's Library(Also add the required Libraries- JSon2, Jquery and
Add the Modified On Field to the Form)
 Register onChangeModifiedOn method as the OnChange Event Handler of the Modified On Field.

Step 8. Have an On Save function defined as below, and add it as the OnSave Event Handler.

function onSave(){
Xrm.Page.getAttribute("<<refreshFlagTwoOptionLogicalName>>").setValue(false);
Xrm.Page.getAttribute("<<refreshFlagTwoOptionLogicalName>>").setSubmitMode("always");
}

By Use of the Refresh Flag Setting and resetting, we make sure that the Form Refresh happens when the BPF Workflow executes, hence avoiding Unnecessary form refresh after every Form Save.

No comments:

Post a Comment