Skip to Content
Author's profile photo Bogdan Toma

A better approach to Scripting Workflows

Workflows tend to be part of the core business in SAP Sourcing and business requirements will most often transform a ‘simple’ workflow process into a very complex one.

Since the introduction of WF in Sourcing (and the TWE ‘era’) a specific pattern to script workflows has emerged and it has been carried forward into all projects. Today we are going to change that.


  • Implementing recommendations in this blog post might make your life easier
  • Throughout this blog post it will be assumed that consultants have following knowledge
    • Workflows definition / update / scripting
    • Java EE/BeanShell


The typology used throughout projects is fairly similar:

  • Workflow definition with X number of Approval Steps (total maximum possible steps)
  • Approval Matrix Definition maintained *somewhere*
  • Specific Approval Sequence picked up in PRE-PHASE-CHANGE script and added to the document into an Extension Collection
  • Workflow scripting handles the ‘next approver’ from the document Extension Collection


For each approval step the script is required to

  • Check if approval status is APPROVED or REJECTED
      • Approval Sequence is complete -> move document to ‘Approved’ phase
      • If not complete, add next approver
      • move document to ‘Draft’ (or previous phase)

Pattern in case of APPROVED for above is:

  • for WF STEP 1:

if(approvalMatrix.size() == 1) {
  //move to Approved
if(approvalMatrix.size() >= 1) {
  //add next approver

  • for WF STEP 2:

if(approvalMatrix.size() == 2) {
  //move to Approved
if(approvalMatrix.size() >= 2) {
  //add next approver

  • etc … for all steps

WHY IS THAT A PROBLEM? And why is it complicating our lives?

The pattern above implies that:

  • there is one distinct version of PRESCRIPT for EACH workflow step
  • similarly, there will be one distinct version of POSTSCRIPT for EACH workflow step

To maintain such a workflow, an IT consultant will have to:

  • save/maintain each prescript/postscript version individually
  • do a lot of repetitive work for any minor update
  • be VERY careful when doing updates not to disturb the process


The solution is to make scripting GENERIC.

  • Single version of PRESCRIPT for ALL steps
    • the script should be able to ‘know’ from which step it was executed
  • Single version of POSTSCRIPT for ALL steps
    • the script should be able to ‘know’ from which step it was executed


  • Step 1: Make sure you have a gate identifier. Solution is to ‘decode’ the current step from the Activity ID (last digit/digits)

Screen Shot 2015-07-30 at 4.41.19 PM.png

  • Step 2: Use following code to identify gate -> ‘current approval step’
    • Script will get ending digit(s) from identifier:
      • ‘approval_gate_1’ = 1
      • ‘approval_gate_12’ = 12
      • ‘approval_gate_1485’ = 1485 😀

import java.util.regex.Matcher;
import java.util.regex.Pattern;
private Integer gate = null;
// btoma - Get the step No. from gate NativeID - last digit(s)
// btoma - to facilitate PRESCRIPT on all steps
void getGate() {
  Pattern p = Pattern.compile("\\d+");
  Matcher m = p.matcher(nativeName);
  while(m.find()) {
  gate = Integer.valueOf(;

  • Step 3: Update WF script code, to use gate instead of hardcoded numbers

if(approvalMatrix.size() == gate) {
  //move to Approved
if(approvalMatrix.size() >= gate) {
  //add next approver

  • Step 4: Copy-Paste your PRESCRIPT on rest of WF steps
  • Step 5: Repeat 1-4 for POSTSCRIPT


  • Maintain scripts locally, in a source control sistem (SVN, GIT).
  • Perform changes locally, and copy-paste your script to all WF steps in one go.
  • Don’t forget about logging and error reporting

The end.

Bogdan Toma

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Great post, Bogdan.

      Although in my recent projects I have been dealing mostly with single step approvals, I do remember implementing a 15-step workflow for a client. And yes, I had to go through the repetitive task of updating each pre-script for even a small change. This will come handy the next time I face a similar situation.



      PS: Good programmers are lazy programmers. Hence proved. 😉

      Author's profile photo Former Member
      Former Member

      Hi Bogdan,

      Currently I'm working with CLM Workflow definition, I do not know anything about SAP/SCN/CLM, I'm a Java Developer, so far I had created a 4 approval steps, the problem is that I don't understand how the sequence works, because I got the order of approvers from the collaborator's list, it seems that just the first activity is always executed and never goes to the next step for the next approver. In the code I check for the Name of the collaborator on each step, here is my code, the question is how can I achieve the next step for the next approver?

      Thanks in advance.

















      import java.math.*;

      // Variable for Approver

      ObjectReferenceIfc principal = null;

      // Logger Instance for logging messages

      private LogMessageIfc log = Logger.createLogMessage(session);

      // Starting Workflow

      log.setLogMessage("MAWF-Prescript-Inicio-Request Approval 1");;

      // Instance of the Document

      contractBean = doc.getParentIBean();

      // Name in Contract Documents Tab (Creating a Contract/DocumentType)

      docName = doc.getDisplayName();

      log.setLogMessage("MAWF-Prescript-DocumentName: " + docName);;

      // Get the user who creates the document

      String userName = doc.getCreatedByUser().getDisplayName();

      log.setLogMessage("MAWF-Prescript-Created by User: " + userName);;

      // List of Collaborators of a Document

      collaboratorsCollection = doc.getCollaborators();

      collaboratorsIterator = collaboratorsCollection.iterator();

      // Check if collaborators collection's size is greater than zero.

      if (collaboratorsCollection.size() > 0) {

      // Iterate over the collection.

      for (int i = collaboratorsCollection.size() - 1; i >= 0; --i) {

        // Get collection member

          collaboratorsCollection_member = collaboratorsCollection.get(i);

          // Check if member has value.

          if (hasValue(collaboratorsCollection_member)) {

          // Get the collaboration role of the collection member.

              collaboratorRole = collaboratorsCollection_member.getCollaboratorRole().getDisplayName();


              // Get approver of Role "DIRECTOR PUBLICIDAD".

              if(collaboratorsCollection_member.getDisplayName().equalsIgnoreCase("DIRECTOR PUBLICIDAD")) {

              log.setLogMessage("MAWF-Prescript-Principal: " + collaboratorsCollection_member.getPrincipal());


              log.setLogMessage("MAWF-Prescript-Principal: " + collaboratorsCollection_member.getPrincipal());


              principal = collaboratorsCollection_member.getPrincipal();





      if (hasValue(principal)) {

        // Add the user account as the approver


          // log details

          log.setLogMessage("Added user: " + principal.getDisplayName() + " as approver");



      // Ending Workflow

      log.setLogMessage("MAWF-Prescript-Fin-Request Approval");;

      Author's profile photo Bogdan Toma
      Bogdan Toma
      Blog Post Author


      At first glance, the script should work fine, if you have copied it on all steps as PreScript. But it looks as if you are picking the same approver for every step ... so it's a bit unclear.

      The transition should be made automatically by the system.