Workflow activation UI

If "Siebel Workflow Process" (WF) is your primary tool for business process automation as they are for me, it might be a useful topic for you.

Familiar with the error "The value entered in field Process Business Object of buscomp Workflow Process Deployment does not match any value in the bounded pick list FOW SRF Business Object." (SBL-DAT-00225) when activating a custom BO-based workflow process in Siebel Tools? The usual way to solve it is to activate a process through [Administration - Business Process] screen. It is still annoying, as you will lose your current context, and extremely annoying when you don't have BP screen or access to it in the test application. In this topic, I offer you another, effortless way to activate a WF process. On the same view/session where you are testing it, and with just a couple clicks.

Ok, let's get down to implementation.

1. Publishing the service.

As you might have guessed, we will be using the "Workflow Admin Service". Out of many ways to run the BS, I'll cover OUI scripts.

So, let's make the BS accessible from a browser script. Here, I recommend using a service runner - straight forward concept when you publish one to run any other service in the system. If you are not comfortable with granting access to all services in production, use a client-side business service for service runner. So, it wouldn't be automatically migrated to higher environments along with a repository.

Here is how your service runner method can look like:

function InvokeServiceMethod(Inputs, Outputs) {
    var bs;
    var sBS = Inputs.GetProperty("Service");
    Inputs.RemoveProperty("Service");
    var sMethod = Inputs.GetProperty("Method");
    Inputs.RemoveProperty("Method");
    
    try {
        bs = TheApplication().GetService(sBS);
        bs.InvokeMethod(sMethod, Inputs, Outputs);
    } catch(e) {
        throw e;
    } finally {
        bs = null;
    }
}

Here is a full version of my client-side Business Service - FWK Runtime. Simply, download and import it on Administration - Business Service screen.

And finally, granting access to run a service runner from browser scripts:

2. JS code with UI and service call.

We will need a UI to enter a WF process name and a button to run the BS. We will be using JQuery dialog with just a couple of elements. It is going to look like this:

Source code and installation links are below.

  • Front-end: Snippet
  • /* 
    @desc bookmarklet UI to activate Siebel Workflow Process
    @author VB (xapuk.com)
    @version 1
    */
    if ("undefined" == typeof SiebelApp) {
        alert("It works only in Siebel OUI session!");
    } else {
    
        // snippet id
        var id = "SiebelWFDeploy";
    
        // localStorage to store the history
        var aHist = window.localStorage[id]?JSON.parse(window.localStorage[id]):[];
    
        // just in case (experimental)
        $("#" + id).parent().remove();
    
        // constructing dialog content
        var s = '<div title="Activate workflow">';
        s += '<input id = "' + id + '" type="text" list="' + id + 'List" style="width:100%" value="' + (aHist.length?aHist[0]:"") + '">'; // most recent
        s += '<label class="pt-3">Recent workflows:</label><ul>';
        for (var i =0; i < aHist.length && i < 5; i++){ // five recent values as links
            s += '<li><a href="#">' + aHist[i] + '</a></li>';
        }
        s += '</ul></div>';
    
        // open dialog
        var $d = $(s).dialog({
            modal: true,
            width: 640,
            open: function() {
                $('#' + id).autocomplete({source: aHist});
                $('#' + id).focus().select(); // autofocus
            },
            close: function() {
                $(this).dialog('destroy').remove();
            },
            buttons: [{
                text: 'Activate (Enter/Click)',
                click: function(){
                    go($d.find('#' + id).val());
                }
            }, {
                text: 'Close (Esc)',
                click: function() {
                    $(this).dialog('close');
                }
            }]
        });
    
        // key bindings
        $d.keyup(function(event) {
            // enter
            if (event.keyCode === 13) { 
                go($d.find('#' + id).val());
            }
        });
    
        // running function on anchor link click
        $d.find("a").click(function(event) {
            go($(this).html());
        });
    }
    
    // Activate
    function go(name) {
        if (name){
            // moving recent view to the top
            if (aHist.indexOf(name) > -1){
               aHist.splice(aHist.indexOf(name),1);
            }
            aHist.unshift(name);
            window.localStorage[id] = JSON.stringify(aHist); 
            $d.dialog('close');
    
            // invoke BS
            var service = SiebelApp.S_App.GetService("FWK Runtime");
            var ps = SiebelApp.S_App.NewPropertySet();
            ps.SetProperty("Service", "Workflow Admin Service");
            ps.SetProperty("Method", "Activate");
            ps.SetProperty("FlowSearchSpec", "[Process Name] = '" + name + "'");
            var outputSet = service.InvokeMethod("InvokeServiceMethod", ps);
            if (console){
                console.log(outputSet);
            }
            if (outputSet.GetProperty("Status") == "Error"){
                alert(outputSet.GetChildByType("Errors").GetChild(0).GetProperty("ErrMsg"));    
            }else{
                if (outputSet.GetChildByType("ResultSet").GetProperty("NumFlowActivated") === "0"){
                    alert("Process definition [" + name + "] not found");
                }else{
                    alert("Done!");
                }
            }
        }
    }
  • Bookmarklet code: Snippet
  • javascript:function go(e){if(e){aHist.indexOf(e)>-1&&aHist.splice(aHist.indexOf(e),1),aHist.unshift(e),window.localStorage[id]=JSON.stringify(aHist),$d.dialog("close");var i=SiebelApp.S_App.GetService("FWK Runtime"),t=SiebelApp.S_App.NewPropertySet();t.SetProperty("Service","Workflow Admin Service"),t.SetProperty("Method","Activate"),t.SetProperty("FlowSearchSpec","[Process Name] = '"+e+"'");var o=i.InvokeMethod("InvokeServiceMethod",t);console&&console.log(o),alert("Error"==o.GetProperty("Status")?o.GetChildByType("Errors").GetChild(0).GetProperty("ErrMsg"):"0"===o.GetChildByType("ResultSet").GetProperty("NumFlowActivated")?"Process definition ["+e+"] not found":"Done!")}}if("undefined"==typeof SiebelApp)alert("It works only in Siebel OUI session!");else{var id="SiebelWFDeploy",aHist=window.localStorage[id]?JSON.parse(window.localStorage[id]):[];$("#"+id).parent().remove();var s='<div title="Activate workflow">';s+='<input id = "'+id+'" type="text" list="'+id+'List" style="width:100%" value="'+(aHist.length?aHist[0]:"")+'">',s+='<label class="pt-3">Recent workflows:</label><ul>';for(var i=0;i<aHist.length&&5>i;i++)s+='<li><a href="#">'+aHist[i]+"</a></li>";s+="</ul></div>";var $d=$(s).dialog({modal:!0,width:640,open:function(){$("#"+id).autocomplete({source:aHist}),$("#"+id).focus().select()},close:function(){$(this).dialog("destroy").remove()},buttons:[{text:"Activate (Enter/Click)",click:function(){go($d.find("#"+id).val())}},{text:"Close (Esc)",click:function(){$(this).dialog("close")}}]});$d.keyup(function(e){13===e.keyCode&&go($d.find("#"+id).val())}),$d.find("a").click(function(e){go($(this).html())})}
  • Bookmarklet link: Activate WF

3. Disable cache.

Workflow Process cache is controlled by VerCheckTime (Workflow Version Checking Interval) server parameter .

If the parameter is on, a new WF version wouldn't take in action in existing session right away after activating it. It makes sense to have it on production, but I recommend to turn it off on DEV environment.

Also, turn it off on your dedicated client in .cfg file:

...
[Workflow]
VerCheckTime = -1

Bonus

Same story with TBUI. Simply run [Task Activation Automation] service from JavaScript. Service runner is paying off already, by the way.

  • Bookmarklet code: Snippet
  • javascript:function go(e){if(e){aHist.indexOf(e)>-1&&aHist.splice(aHist.indexOf(e),1),aHist.unshift(e),window.localStorage[id]=JSON.stringify(aHist),$d.dialog("close");var t=SiebelApp.S_App.GetService("FWK Runtime"),i=SiebelApp.S_App.NewPropertySet();i.SetProperty("Service","Task Activation Automation"),i.SetProperty("Method","Activate Task"),i.SetProperty("TaskName",e);var o=t.InvokeMethod("InvokeServiceMethod",i);console&&console.log(o),alert("Error"==o.GetProperty("Status")?o.GetChildByType("Errors").GetChild(0).GetProperty("ErrMsg"):"0"===o.GetChildByType("ResultSet").GetProperty("NumFlowActivated")?"Process definition ["+e+"] not found":"Done!")}}if("undefined"==typeof SiebelApp)alert("It works only in Siebel OUI session!");else{var id="SiebelTaskDeploy",aHist=window.localStorage[id]?JSON.parse(window.localStorage[id]):[];$("#"+id).parent().remove();var s='<div title="Activate task">';s+='<input id = "'+id+'" type="text" list="'+id+'List" style="width:100%" value="'+(aHist.length?aHist[0]:"")+'">',s+='<label class="pt-3">Recent tasks:</label><ul>';for(var i=0;i<aHist.length&&5>i;i++)s+='<li><a href="#">'+aHist[i]+"</a></li>";s+="</ul></div>";var $d=$(s).dialog({modal:!0,width:640,open:function(){$("#"+id).autocomplete({source:aHist}),$("#"+id).focus().select()},close:function(){$(this).dialog("destroy").remove()},buttons:[{text:"Activate (Enter/Click)",click:function(){go($d.find("#"+id).val())}},{text:"Close (Esc)",click:function(){$(this).dialog("close")}}]});$d.keyup(function(e){13===e.keyCode&&go($d.find("#"+id).val())}),$d.find("a").click(function(e){go($(this).html())})}
  • Bookmarklet: Activate Task