2022 June Release

app.ducx Business Process LanguagePermanent link for this heading

The app.ducx business process language allows you to define the process model for your software component. The process model is comprised of one or more template processes defining an ordered list of sequential or parallel activities and process control elements such as conditions or loops. Each activity definition consists of a list of steps that need to be carried out by a user responsible for completing a particular activity.

A process model block consists of import declarations and process blocks. The processes keyword denotes the process model block. It must be followed by the reference of your software component and curly braces.

Process model blocks can only be contained in files with a .ducx-bp extension.

Syntax

processes softwarecomponent
{
  // Import declarations
  import softwarecomponent;

  // Process blocks
  process reference {
    symbol = symbol;
    allowed {
      objectclass,
      ...
    }
    denied {
      objectclass,
      ...
    }
   ...
  }
}

Defining a ProcessPermanent link for this heading

A process definition is comprised of a sequence of serialized or parallel activities and control elements. Using such a process definition, a process instance can be instantiated by a user. A process instance is usually attached to exactly one business object.

The process keyword must be used to define a process. It must be followed by the reference and curly braces.

A process block may contain referenced processes (sub-processes), referenced activities, activity definitions and control elements. The following elements are supported within a process block:

  • activities defined using the activity keyword or referenced activities
  • referenced processes (sub-processes)
  • conditions defined using the if keyword
  • case statements defined using the switch keyword
  • loops defined using the repeat keyword
  • subprocesses also defined using the activity keyword
  • parallel blocks defined using the parallel keyword

In addition to activity definitions and control elements a process block also supports the following elements:

  • The symbol keyword can be used to assign a custom symbol to a process definition.
  • The allowed keyword can be used to define a list of allowed object classes. If you define a list of allowed object classes, the process definition may only be used for initializing processes on instances of the object classes in the allowed block.
  • The denied keyword can be used to define a list of excluded object classes. If you define a list of excluded object classes, the process definition may not be used for initializing processes on instances of the object classes in the denied block.
  • With common = true the process can be marked as commonly useable.

Defining an ActivityPermanent link for this heading

The activity keyword is used to define an activity. It can be nested directly within the processes block to define an activity used for ad hoc prescriptions or to define an activity that should be referenced in several process blocks. Within a process block you can define an activity that is part of a process.

When defining an activity within the processes block, the activity keyword may be followed by the reference and curly braces. If no reference is given, then a default reference is generated automatically. This is also valid for activities inside a condition, case statement, loop, or gateway.

The symbol keyword can be used to assign a custom symbol to an activity. By adding common = true activities can be marked as commonly useable.

Syntax

activity reference_opt {
  actor {
    meta = abstractactor;
    pos = position;
    orgunit = organizationalunit;
  }
  step stepidentifier stepmodifiers {
    precond = expression {
      ...
    }
    execute = ...
  }
}

The simplest process definition is a sequence of activity blocks that are processed one after the other.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  // Definition of an activity for ad hoc prescriptions
  activity AdHocProcessing {
    ...
  }
  // Definition of an activity that can be used within several processes
  activity CommonActivity {
    ...
  }

  // Definition of a process with three sequential activities
  process OrderWF {
    // Definition of the first activity of the process
    activity OrderWFActDef1 {
      ...
    }
    // Definition of the second activity of the process
    activity OrderWFActDef2 {
      ...
    }
    // Definition of the third activity of the process
    activity {
      ...
    }
    // Use of CommonActivity as the forth activity of the process
    CommonActivity;
  }
}

Defining the ActorPermanent link for this heading

Each activity must have an actor block defining the actor responsible for the completion of the activity.

The actor can either be an abstract entity – such as the process initiator or the process owner – or what is referred to as a role in Fabasoft terminology, which is combination of position and organizational unit.

Note: An actor can also be defined in referenced activities. In this case the predefined actor of the referenced activity definition is overridden.

The following keywords can be used to define an actor:

  • meta for referencing an abstract entity as listed in the following table
  • pos for referencing a position
  • orgunit for referencing an organizational unit

Abstract actor

Description

WFMP_INITIATOR

Process initiator

WFMP_RESPONSIBLE

Actor responsible for process

WFMP_PROCOWNER

Process owner

WFMP_PROCGROUP

Process group

WFMP_OBJOWNER

Object owner

WFMP_OBJGROUP

Object group

WFMP_CURRENTUSER

Current user

WFMP_PARTICIPANT

Current actor

Note: In addition to the abstract actors listed in the previous table, software component developers can also define custom abstract actors.

Defining the Steps to Be ExecutedPermanent link for this heading

An activity consists of a list of steps that can either be optional or required. Required steps must be executed before the actor is allowed to complete the activity.

For each step, a step block must be defined within the activity block. The step keyword can be followed by an optional identifier for the step, and curly braces.

The caption keyword should be used to define the name of the step, using a string object.

The execute keyword allows you to define the “implementation” for a step. Put simply, execute is used to define which action is carried out when the step is executed by the user.

A step can be implemented inline using app.ducx expression language. Alternatively, you can also reference a use case or a virtual application.

Note: The use case or virtual application is invoked on the business object attached to the process. If the step is implemented in app.ducx expression language, the business object can be accessed using the cooobj variable.

If you do not provide an implementation for a step by omitting the execute keyword, a dialog box is presented to the user upon execution asking whether the step has been carried out successfully.

Transaction Variables Holding the ContextPermanent link for this heading

When executing a step of an activity, the workflow engine makes available several transaction variables holding context information.

The following example demonstrates how to access the transaction variables provided by the workflow engine from a virtual application that is used to implement a step of an activity.

Example

app.ducx Use Case Language

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  usecase EditOrderWF() {
    variant Order {
      impl = application {
        expression {
          Object obj = #TV.WFVAR_THIS;
          ProcessInstance process = #TV.WFVAR_PROCESS;
          ActivityInstance activity = #TV.WFVAR_ACTIVITY;
          integer workitemidx = #TV.WFVAR_WORKITEM;
          process->COODESK@1.1:OpenObject();
        }
      }
    }
  }
}

app.ducx Business Process Language

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process OrderWF {
    symbol = SymbolOrderWF;
    allowed {
      Order
    }
    activity {
      actor {
        meta = WFMP_INITIATOR;
      }
      step AssignOrder {
        execute = EditOrderWF;
      }
    }
  }
}

Using an Expression to Implement a StepPermanent link for this heading

When implementing a step using app.ducx expression language, the local scope this is populated with a dictionary. The entries are listed in. Hence, you do not need to read the transaction variables listed in the following table. Instead, you can also obtain the values from the dictionary.

Key

Description

object

Business object attached to the current process

process

Process instance

activity

Activity instance

workitem

Zero-based index of the step executed

Defining a Precondition for a StepPermanent link for this heading

The precond keyword is used to define a precondition that must evaluate to true for the step to be enabled in the user interface. If you do not define a precondition for a step, it is enabled by default.

The precondition must be implemented using app.ducx expression language. The previous table lists the entries available in the local scope this when the expression is evaluated. If the expression returns true, the step is enabled in the user interface, otherwise it is disabled.

In the following example, the second step of the activity is enabled only after the first step has been executed successfully. This is achieved by defining a precondition expression that checks whether the completion date property (COOWF@1.1:wfwcompletedat) has been populated for the first step (COOWF@1.1:actinstwork[0]) of the activity.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process OrderWF {
    // Activity for checking the order
    activity {
      actor {
        meta = WFMP_INITIATOR;
      }
      step ViewOrder {
        execute = ViewOrder;
      }
      step ReleaseOrder {
        precond = expression {
          activity.actinstwork[0].wfwcompletedat != null
        }
        execute = ReleaseOrder;
      }
    }
  }
}

Defining Additional Settings for a StepPermanent link for this heading

For each step of an activity, you can define whether it should be required, repeatable and whether the current activity should be completed automatically after the step has been executed successfully.

These settings are referred to as step modifier suffixes, which are denoted following the step identifier or the step keyword if the step identifier was omitted. Multiple step modifier suffixes must be separated by whitespaces.

Defining a Required Step

For defining a required step, the required keyword must be appended as a step modifier suffix.

All required steps must be executed before an activity can be completed by the user.

Defining a Repeatable Step

By default, steps can only be executed once. Once executed successfully, a step cannot be executed again except if the multiple keyword is appended as a step modifier suffix.

Defining an Auto-Completing Step

If the leave step modifier suffix is added to a step, the activity is completed automatically after the concerned step has been executed successfully.

If an activity does not have any auto-completing steps, it must be completed manually for the workflow to proceed with the next activity in the process.

Note: An activity can only be completed after all required steps have been executed by the user even if the leave step modifier suffix was added for the executed step.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process OrderWF {
    // Activity for checking the order
    activity {
      actor {
        meta = WFMP_INITIATOR;
      }
      step ViewOrder multiple {
        execute = ViewOrder;
      }
      step ReleaseOrder required leave {
        execute = ReleaseOrder;
      }
    }
    // Activity for shipping the order
    activity {
      actor {
        pos = Clerk;
        orgunit = OrderProcessing;
      }
      step ViewOrder multiple {
        execute = ViewOrder;
      }
      step MarkOrderAsShipped required leave {
        execute = MarkOrderAsShipped;
      }
    }
    // Activity for billing the order
    activity {
      actor {
        pos = Clerk;
        orgunit = Accounting;
      }
      step ViewOrder multiple {
        execute = ViewOrder;
      }
      step SendInvoice required leave {
        execute = SendInvoice;
      }
    }
  }
}

Predefined StepsPermanent link for this heading

Most activities contain a step to open the object of the process. Therefore, Fabasoft app.ducx provides special keywords for these common steps:

  • openstep
    A step to open the object with its native tool. This step is implicitly assigned the caption string COOWF@1.1:StrWFOpenObject,  the application FSCFOLIO@1.1001:WFOpenObjectApp and the symbol COODESK@1.1:OpenObject. Moreover, the multiple step modifier is assigned to an openstep.
  • propertiesstep
    A step to open the properties dialog of the object. This step is implicitly assigned the caption string COOWF@1.1:StrWFOpenProperties,  the application FSCFOLIO@1.1001:WFOpenObjectPropertiesApp and the symbol COODESK@1.1:OpenObject. Moreover, the multiple step modifier is assigned to an openstep.

These predefined steps just set some default values to a step, it can be customized like any other step, even overriding the default values of cation, execute, or symbol.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process OrderWF {
    // Activity for checking the order
    activity {
      actor {
        meta = WFMP_INITIATOR;
      }

      openstep {

        execute = ViewOrder;
      }
      propertiesstep;
      step ReleaseOrder required leave {
        caption = StrReleaseOrder;

        execute = ReleaseOrder;
      }
    }
  }
}

Extending an ActivityPermanent link for this heading

The extend keyword followed by the keyword activity allows you to extend own activities and activities of other software components.

Syntax

extend activity reference {
  ...
}

Note: The extension of activities that belong to another non-friend software component is not allowed.

In the following example an activity is extended by a step.

Example

extend activity CreateNotification {
  step FinalizeDocument {
    precond = expression {
      activity.actinstwork[2].wfwcompletedat != null;
    }
    execute = expression {
      object.casestate = 4;
    }
  }
}

Defining Conditions, Case Statements, and LoopsPermanent link for this heading

A process can include several types of control elements that allow you to define which path should be taken in a process depending on the result of a predefined expression.

Defining a ConditionPermanent link for this heading

Syntax

if reference_opt (condition) {
  // Activity definitions or control elements
  ...
}
else {
  // Activity definitions or control elements
  ...
}

The if and else keywords denote a condition in a process. A conditional statement embedded into a process allows you to control which path should be taken in a process depending on whether the expression defined in the condition evaluates to true or false. In addition, an optional reference may be given.

If the condition evaluates to true, the block following the if statement is executed. Otherwise, the execution continues in the else block. The else block, however, is optional.

When the condition is evaluated, a dictionary is made available in the local scope this that contains the entries listed in chapter “Using an Expression to Implement a Step” – except for workitem, which is not available in this context.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process OrderWF {
    // Activity for approving an order
    activity {
      actor {
        pos = DeptManager;
        orgunit = OrderProcessing;
      }
      step ViewOrder multiple {
        execute = ViewOrder;
      }
      step ApproveOrder required leave {
        execute = expression {
          object.ObjectLock(true, true);
          object.orderstate = OrderState(OS_APPROVED);
        }
      }
      step DenyApproval required leave {
        execute = expression {
          object.ObjectLock(true, true);
          object.orderstate = OrderState(OS_DISCARDED);
        }
      }
    }
    if (object.orderstate == OrderState(OS_APPROVED)) {
      // Activity for shipping the order
      activity ShippingAct {
        ...
      }
      // Activity for billing the order
      activity {
        ...
      }
    }
    else {
      // Activity for handling discarded orders
      activity {
        ...
      }
    }
  }
}

Defining a Case StatementPermanent link for this heading

Syntax

switch reference_opt (enumerationproperty) {
case enumerationitem:
  // Activity definitions or control elements
  ...
default:
  // Activity definitions or control elements
  ...
}

A case statement allows you to define different process paths depending on the value of an enumeration property of the business object the process is attached to.

The switch keyword is used to define a case statement. It must be followed by parentheses and curly braces, and the reference of the enumeration property to be evaluated must be enclosed in the parentheses. In addition, an optional reference may be given.

The switch block may contain case sections for each enumeration item. The case keyword must be followed by the reference of the enumeration item and a colon. You can also define a single case section for multiple enumeration items by separating the enumeration items by a comma. The default keyword can be used to define a default section applying to all enumeration values that are not handled in an appropriate case section.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process CustomerWF {
    switch (customertype) {
    case CT_ENDUSER:
      activity {
        step AssignOrderToEndUser {
          ...
        }
      }
    case CT_RETAILER, CT_WHOLESALER:
      activity {
        step AssignOrderToReseller {
          ...
        }
      }
    default:
      activity {
        step AssignOrder {
          ...
        }
      }
    }
  }
}

Defining a LoopPermanent link for this heading

Syntax

repeat reference_opt {
  // Activity definitions or control elements
  ...
} until (terminationcondition);

do reference_opt {
  // Activity definitions or control elements
  ...
} while (whilecondition);

while reference_opt (whilecondition) {
  // Activity definitions or control elements
  ...
};

The repeat, until, do and while keywords can be used to define a loop in a process. The repeat until loop is executed until the termination condition evaluates to false. The do while and the while loops are executed as long as the while condition is true.

In addition, an optional reference may be given.

When the conditions are evaluated, a dictionary is made available in the local scope this that contains the entries listed in chapter “Using an Expression to Implement a Step” – except for workitem, which is not available in this context.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process CustomerWF {
    repeat reference_opt {
      // Activities and control elements for processing an order
      activity {
        ...
      }
      activity {
        ...
      }
    } until (object.orderstate == OrderState(OS_COMPLETED));
  }
}

Defining a GatewayPermanent link for this heading

Syntax

gateway reference_opt {
  type = gatewaytype;
  // Path definitions
  path (pathcondition) {
    reference = "reference1";
    // Activity definitions or control elements
    end;
  }
  path (pathcondition) {
    reference = "reference2";
    // Activity definitions or control elements
    end;
  }
  default {
   reference = "reference3";
    // Activity definitions or control elements
  }
}

The gateway keyword can be used to define exclusive and inclusive gateways in a process. In addition, an optional reference may be given.

If the type equals GWT_EXCLUSIVE, the conditions of the paths are evaluated and only the first path, where the condition evaluated to true, will be executed. Choosing the type GWT_INCLUSIVE leads to the result that all paths with a condition evaluated to true will be executed.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process CustomerWF {
    gateway {
      type = GWT_EXCLUSIVE;
      path (cooobj.objname contains "Default") {
        reference = "reference1";
        sequence {
          activity {
            ...
          }
        }
        end;
      }
      default {
        reference = "reference1";
        sequence {
          activity {
            ...
          }
        }
      }
    }
  }
}

Paths of gateways can lead to the explicit termination of the current process. This can be denoted by the keywords end, terminate or error. end ends the current process, terminate terminates the execution of the current process and error indicates that the process needs to be terminated due to an error.

Defining Parallel ActivitiesPermanent link for this heading

The workflow engine allows you to define processes that are comprised of parallel activities and control elements.

Defining a Block of Parallel ActivitiesPermanent link for this heading

Syntax

parallel {
  // Activity definitions or control elements
  ...
}

The parallel keyword is used to define blocks of parallel activities. parallel blocks can be nested within a process block, within control element blocks or within other parallel blocks.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process ApproveOrderWF {
    parallel {
      activity {
        actor {
          pos = Clerk;
          orgunit = OrderProcessing;
        }
        step ApproveOrder required leave {
          execute = ApproveOrder;
        }
        step DenyApproval required leave {
          execute = DenyOrderApproval;
        }
      }
      activity {
        actor {
          pos = DeptManager;
          orgunit = OrderProcessing;
        }
        step ApproveOrder required leave {
          execute = ApproveOrder;
        }
        step DenyApproval required leave {
          execute = DenyOrderApproval;
        }
      }
    }
  }
}

A process can be split at any time using a parallel block. The default behavior when joining parallel process paths is that all parallel activities must be completed before the workflow continues with the next non-parallel activity in the process.

Defining Activity Sequences Within a Parallel BlockPermanent link for this heading

Syntax

parallel {
  // Activity definitions or control elements
   ...
  sequence {
    // Activity definitions or control elements
    ...
  }
  // Activity definitions or control elements
  ...
}

The sequence keyword is used to define a sequence of activities within a parallel block. It must be followed by a block defining the sequence of activity definitions and control elements within a path of a parallel block. A sequence block can also contain another parallel block for splitting the current process path.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  process ApproveOrderWF {
    parallel {
      activity {
        actor {
          pos = Clerk;
          orgunit = OrderProcessing;
        }
        step ApproveOrder required leave {
          execute = ApproveOrder;
        }
        step DenyApproval required leave {
          execute = DenyOrderApproval;
        }
      }
      sequence {
        activity {
          actor {
            pos = DeptSecretary;
            orgunit = OrderProcessing;
          }
          step ApproveOrder required leave {
            execute = ApproveOrder;
          }
          step DenyApproval required leave {
            execute = DenyOrderApproval;
          }
        }
        if (object.preapproved) {
          activity {
            actor {
              pos = DeptManager;
              orgunit = OrderProcessing;
            }
            step ApproveOrder required leave {
              execute = ApproveOrder;
            }
            step DenyApproval required leave {
              execute = DenyOrderApproval;
            }
          }
        }
      }
    }
  }
}

Defining SubprocessesPermanent link for this heading

The workflow engine allows you to invoke a subprocess from within a process. An activity is used as a container to embed a subprocess within a process. The subprocess is expanded on demand when the workflow reaches the activity acting as a container for the subprocess.

A subprocess is defined just like an ordinary process using the process keyword.

Syntax

activity {
  subproc = subprocess;
}

The activity keyword is used to embed a subprocess within a process, but instead of defining actor and steps for the activity you just need to reference the subprocess using the subproc keyword.

Example

processes APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import COOWF@1.1;

  // Definition of subprocess APPDUCXSAMPLE@200.200:DeptMgrApprovalWF
  process DeptMgrApprovalWF {
    activity {
      actor {
        pos = DeptSecretary;
        orgunit = OrderProcessing;
      }
      step ApproveOrder required leave {
        execute = ApproveOrder;
        }
        step DenyApproval required leave {
          execute = DenyOrderApproval;
        }
      }
    }
    if (object.preapproved) {
      activity {
        actor {
          pos = DeptManager;
          orgunit = OrderProcessing;
        }
        step ApproveOrder required leave {
          execute = ApproveOrder;
        }
        step DenyApproval required leave {
          execute = DenyOrderApproval;
        }
      }
    }
    // This process may only be used as a subprocess, and may not be
    // instantiated directly on an object

    procdefstate = PROCDEF_SUBPROCESS;
  }

  process ApproveOrderWF {
    parallel {
      activity {
        actor {
          pos = Clerk;
          orgunit = OrderProcessing;
        }
        step ApproveOrder required leave {
          execute = ApproveOrder;
        }
        step DenyApproval required leave {
          execute = DenyOrderApproval;
        }
      }
      // Embedding subprocess APPDUCXSAMPLE@200.200:DeptMgrApprovalWF
      activity {
        subproc = DeptMgrApprovalWF;
      }
    }
  }
}

BPMN 2.0 Modeling With app.ducxPermanent link for this heading

Fabasoft app.ducx allows you to import a BPMN 2.0 process definition into your Fabasoft app.ducx Project via an import wizard using “File” > “Import”. In the category “Fabasoft app.ducx” you will find an item called “BPMN 2.0 Process Definition into Fabasoft app.ducx Project”.

On the next page, you can either select a process definition form your local file system or a process definition from the installation or from your “Default Web Service”.

By finishing this dialog, the process definition will be transformed to a Fabasoft app.ducx compatible business process which you can afterwards customize or use.

Note: If your BPMN 2.0 process model uses references to predefined activity definitions it is necessary that the software components of these references are already added to the “Software Component References” of your Fabasoft app.ducx Project.