System-Skriptsprache: Allgemeine Funktionen, Befehle zur Ereignisauslösung (Workflow event functions)

Mithilfe der Funktionen zur Ereignisauslösung können Workflow-Ereignisse in der aktiven Datenbank oder in der Repository-Datenbank ausgelöst werden. Zu den Funktionen zur Ereignisauslösung gehören:

Grundlegende Informationen zu den allgemeinen Funktionen der System-Skriptsprache erhalten Sie im Dokument System-Skriptsprache: Allgemeine Funktionen.

fireEvent

Name fireEvent
Beschreibung fireEvent löst ein generisches Ereignis in der aktuellen Datenbank aus.
Signaturen boolean fireEvent(String name, HashMap parameters)

boolean fireEvent(String database, String name, HashMap parameters)

boolean fireEvent(Number subtype, String name, HashMap parameters)

boolean fireEvent(String database, Number subtype, String name, HashMap parameters)

Parameter database ist der Name einer mit dem System verbundenen Datenbank, in der das generische Ereignis ausgelöst werden soll. Wird database nicht angegeben, dann wird das generische Ereignis in der aktuellen Datenbank ausgelöst.

subtype ist der Subtyp des generischen Ereignisses. Ist subtype kein zulässiger Subtyp, dann wird der Subtyp 0 verwendet. Der Subtyp 0 wird auch dann verwendet, wenn sie die Funktion ohne den Parameter subtype aufrufen.

name ist eine frei wählbare Identifikation des Ereignisses, mit dessen Hilfe Sie unterschiedliche Ereignisse unterscheiden können. Wenn Sie eine Aktivitätsdefinition erstellen, die auf ein generisches Ereignis reagiert, können Sie den Namen in der Übergangsbedingung abfragen, um die Bedeutung des Ereignisses zu prüfen. Um zwei Prozesse miteinander zu synchronisieren, wählen Sie einen eindeutigen Namen, wie z. B. die Guid der Aktivität, die das Ereignis auslöst, oder eine mithilfe der Funktion newGuid erzeugte Guid. Der darauf folgende Prozessschritt vom Typ Zwischenereignis wartet solange, bis die aufgerufene Aktivität oder der Prozess das generische Ereignis auslöst, diesmal mit der übergebenen Guid (Promise) als neuer Name.

parameters ist eine Hash-Tabelle, die beliebige Parameterwerte für die aufgerufene Aktivität oder den Prozess enthalten kann.

Ergebnis Die Funktion fireEvent löst bei einer Aktivität in einer OLTP-Datenbank das Ereignis com.cisag.pgm.workflow.GenericOLTPEvent und bei einer Aktivität in der Repository-Datenbank das Ereignis com.cisag.pgm.workflow.GenericRepositoryEvent aus.
Fehlerquellen database muss eine gültige, dem System angeschlossene OLTP-Datenbank sein. Um ein Ereignis in der Repository-Datenbank auszulösen, verwenden Sie die Funktion fireRepositoryEvent.
Beispiele fireEvent(activity:code, hashMap(user:=userName(parameters.userGuid), order:=parameters.object:guid)) löst das generische Ereignis in einer Aktivitätsdefinition mit einer Ereignisdefinition vom Typ Business Entity aus und übergibt die Identifikation der Aktivität als Name und den Namen des auslösenden Benutzers sowie den Primary Key des veränderten Business Objects als Parameter.

fireEvent(7, "", hashMap()) löst das generische Ereignis mit dem Subtyp 7 und ohne Identifikation und Parameter aus.

fireEvent(db, 7, "", hashMap()) löst das generische Ereignis mit dem Subtyp 7 in der Datenbank mit dem im Variablen db gespeicherten Namen aus.

fireEvent("NotifyByMail", hashMap(recipient:=process.Initiator, textModule:="PROCDONE", process:=process.Code) löst das generische Ereignis aus, um eine E-Mail-Nachricht an den Prozessauslöser zu versenden. Die Identifikation der Aktivitätsdefinition wird als Name übergeben. Die aufgerufene Aktivitätsdefinition verwendet die Übergangsbedingung parameters.name = definition:code.

Kontext ALL
Hinweise Sie können fireEvent auch in individuellen Prüfungen verwenden, z. B. um bei bestimmten Datenkonstellationen eine Benachrichtigung zu versenden oder bei einer versuchten Freigabe ohne Genehmigung einen Genehmigungsprozess zu starten.

Ist ein Subtyp angeben, wird die Übergangsbedingung nur dann ausgewertet, wenn in der Aktivitätsdefinition der gleiche Subtyp ausgewählt ist. Verwenden Sie Subtypen, um die Anzahl der auszuwertenden Übergangsbedingungen zu reduzieren. Sind z. B. zehn Aktivitätsdefinitionen für das generische Ereignis registriert, aber nur eine davon soll beim Auflösen des Ereignisses eine Aktivität erzeugen, dann kann die Verwendung von Subtypen die Anzahl der ausgewerteten Übergangsbedingungen um 90 % reduzieren.

Siehe auch fireRepositoryEvent

Folgendes Beispiel aus der Aktivitätsdefinition help.fireEvent löst das generische Ereignis com.cisag.pgm.workflow.GenericOLTPEvent in der aktuellen Datenbank aus.

function create()
{
var p_message := parameters.MESSAGE;
if (p_message = "")
p_message := "Is there anybody out there?";

var params := new(HashMap);
params.sender := "SETI"; /* Searching for Event Trigger Interceptors */
params.message := p_message;

fireEvent(definition:code, params);
}

 

Beispiel: Generisches Ereignis auswerten

Folgendes Beispiel aus der Aktivitätsdefinition help.fireEvent.catch beschreibt, wie eine Aktivitätsdefinition das generische Ereignis im vorherigen Beispiel abfangen und auswerten kann. In der Übergangsbedingung wird der Name des Ereignisses abgefragt. Nur wenn die Identifikation der Aktivitätsdefinition (hier: help.fireEvent.catch mit dem Namen des Ereignisses (hier: help.fireEvent) anfängt, wird eine Aktivität erzeugt.

startsWith(definition:code, parameters.name)

In den Deklarationen werden die weiteren Parameter des Ereignisses ausgewertet und die Betreffzeile der Aktivität formatiert:

function create()
{
var p_params := parameters.parameters;

formatSubject("sender", cast(String, p_params.sender));
formatSubject("message", cast(String, p_params.message));
}

 

Beispiel: Unterprozess starten

Folgendes Beispiel aus einer Prozessdefinition löst das generische Ereignis com.cisag.pgm.workflow.GenericOLTPEvent in der aktuellen Datenbank aus, um den Unterprozess ApproveGenericRequest zu starten. Als Ereignisname wird die Identifikation der Aktivitätsdefinition verwendet, für die das Ereignis ausgelöst wird. Auch die Identifikation der Aktivität wird als Ereignisparameter übergeben, damit der aufgerufene Unterprozess bei der Rückgabe der Ergebnisse die Identifikation als Ereignisnamen verwenden kann. Da die Identifikation der Aktivität in der Funktion create()nicht zur Verfügung steht, löst der übergeordnete Prozess das Ereignis erst in der Funktion close()aus.

function close(state as Number)
{
/* Save activity code to process (not available in create) */
process.activityCode := activity:code;

/* Build parameter HashMap */
var params := new(HashMap);
params.caller := activity:code;
params.requester := process.Initiator;
params.beneficiary := process.employee->Partner:number;
params.superior := process.superior->Partner:number;
params.resourceType := process.resourceType;
params.requestedResources := process.requestedResources;
params.comment := process.comment;
params.notificationRecipients := list(process.Initiator);
params.activityWorkDuration := 3600 * 24 * 7;
params.activityPriority := 5;

/* Start subprocess */
fireEvent("ApproveGenericRequest", params);
}

Nach dem Aufruf wartet ein Zwischenereignis im übergeordneten Prozess auf die Rückgabe der Ergebnisse aus dem Unterprozess mithilfe des generischen Ereignisses com.cisag.pgm.workflow.GenericOLTPEvent. Die Übergangsbedingung im Zwischenknoten prüft, dass das Ereignis den vorher übergebenen Parameter caller als Name verwendet:

parameters.name = process.activityCode

Unterprozesse haben nicht nur den Vorteil, dass allgemeine Prozessschritte, die in mehreren Prozessen vorkommen, zusammengefasst werden können, um die Implementierung und Wartung zu vereinfachen. Ein Unterprozess kann auch von der übergeordneten Prozessdefinition abweichende Berechtigungseinstellungen besitzen. Somit lässt sich z. B. ein „Onboarding“-Prozess für neue Mitarbeiter vor Einsicht besser schützen. Aktivitäten in der Personalabteilung und in der IT-Abteilung, die oft personenbezogene und geheime Daten umfassen, können als Unterprozesse abgebildet werden, um sie vor weiteren Mitarbeitern im Onboarding-Prozess geheim zu halten. Um die Sicherheit zu erhöhen, können die beiden Prozesse die ausgetauschten Daten mithilfe der Funktionen encrypt und decrypt verschlüsseln.

Beispiel: Prozessvariablen eines anderen Prozesses auswerten

Mithilfe folgender in JavaScript erfasster Aktivitätsdefinition help.js.getProcessParameter vom Typ Funktionsaufruf kann der aufrufende, übergeordnete Prozess beliebige Prozessvariablen des aufgerufenen, untergeordneten Prozesses auswerten.

/* Returns the value of a process variable
*
* Parameters:
* PROCESS: Guid or code of a process instance
* PARAMETER: name of the process variable
*
* Results:
* DATATYPE: datatype of result:
*   1 = String (use result.STRING)
*   2 = Number (use result.NUMBER)
*   3 = Boolean (use result.STRING or result.NUMBER)
*   4 = Guid, Bytes (use result.STRING)
*   5 = CisObject, CisObjectReference (use instance
*      string in result.STRING)
*   7 = List, (use result.STRING)
*   8 = Timestamp (use result.TIMESTAMP)
*   9 = HashMap (use result.STRING)
*   10 = CisObjectReference (not used)
*   11 = CisDate (use result.TIMESTAMP)
*   103 = Unknown
* STRING: result for datatypes:
*   String, Guid, Bytes, CisObject, CisObjectReference,
*   List, HashMap
* NUMBER: result for datatypes: Number, Boolean
* TIMESTAMP: result for datatypes: Timestamp, CisDate
*/

function create() {

var p_process = parameters.PROCESS; /* process Guid or code */
var p_parameter = parameters.PARAMETER; /* parameter name */

var env = Java.type(„com.cisag.pgm.appserver.CisEnvironment“).getInstance();
var om = env.getObjectManager();

var processGuid = p_process.length() == 32 ? Java.type(„com.cisag.pgm.datatype.Guid“).fromHexString(p_process) : null;
var Process = Java.type(„com.cisag.sys.workflow.obj.Process“);
if (processGuid == null) {
var oProcess = om.getObject(Process.buildByCodeKey(p_process));
if (oProcess != null)
processGuid = oProcess.getGuid();
}
if (processGuid == null)
return;

var proc = om.getObject(Process.buildPrimaryKey(processGuid));
var parserLogic = Java.type(„com.cisag.pgm.util.ParserLogic“).getInstance(10, 1);
var parserEnvironment = parserLogic.deserialzeEnvironment(proc.getParameters().getBinaryStream());
var data = parserEnvironment.get("process").getHashMap();
var obj = data.get(p_parameter);
if (obj != null) {
result.DATATYPE = obj.getDatatype();
result.STRING = obj.getString();
result.TIMESTAMP = obj.getTimestamp();
result.NUMBER = obj.getNumber();
if (obj.getDatatype() == 5 || obj.getDatatype() == 10) /* BO or BO-REFERENCE */
result.STRING = obj.getCisObject().get_instanceString();
if (obj.getDatatype() == 3) /* Boolean */
result.NUMBER = obj.getString() == „true“ ? 1 : 0;
}
}

 

Beispiel: Asynchrone Unterprozesse

Dadurch sind auch asynchrone Unterprozesse möglich. Der Unterprozess gibt in der Funktion close()des Startknotens die Guid oder Identifikation (s. g. Promise) an den übergeordneten Prozess synchron zurück. Danach können beide Prozesse asynchron weiterlaufen. Der Übergeordnete Prozess prüft den Status des Unterprozesses. Ist der Unterprozess erledigt, dann fragt der übergordnete Prozess dessen Ergebnisse ab.

Folgende in der System-Skriptsprache erfasste Aktivitätsdefinition help.js.getProcessParameter.call gibt ein Beispiel dafür, wie die in JavaScript erfasste Aktivitätsdefinition help.js.getProcessParameter aufgerufen werden kann:

function create()
{
var p_process := parameters.PROCESS;
var p_parameter := parameters.PARAMETER;
var r_datatype := 0;
var r_string := "";
var r_number := 0;
var r_timestamp := UNDEFINED_DATE;

var params := new(HashMap);
params.PROCESS := p_process;
params.PARAMETER := p_parameter;

var parameterValue := call("help.js.getProcessParameter", params);
result.DATATYPE := cast(Number, parameterValue.DATATYPE);
result.STRING := cast(String, parameterValue.STRING);
result.NUMBER := cast(Number, parameterValue.NUMBER);
result.TIMESTAMP := cast(Timestamp, parameterValue.TIMESTAMP);
}

 

fireRepositoryEvent

Name fireRepositoryEvent
Beschreibung fireRepositoryEvent löst ein generisches Ereignis in der Repository-Datenbank aus.
Signaturen boolean fireRepositoryEvent(String name, HashMap parameters)

boolean fireRepositoryEvent(Number subtype, String name, HashMap parameters)

Parameter subtype ist der Subtyp des generischen Ereignisses. Ist subtype kein zulässiger Subtyp, dann wird der Subtyp 0 verwendet. Der Subtyp 0 wird auch dann verwendet, wenn sie die Funktion ohne den Parameter subtype aufrufen.

name ist eine frei wählbare Identifikation des Ereignisses, mit dessen Hilfe Sie unterschiedliche Ereignisse unterscheiden können. Wenn Sie eine Aktivitätsdefinition erstellen, die auf ein generisches Ereignis reagiert, können Sie den Namen in der Übergangsbedingung abfragen, um die Bedeutung des Ereignisses zu prüfen.

parameters ist eine Hash-Tabelle, die beliebige Parameterwerte enthalten kann.

Ergebnis Die Funktion fireRepositoryEvent löst bei einer Aktivität in sowohl der Repository- als auch in einer OLTP-Datenbank das Ereignis com.cisag.pgm.workflow.GenericRepositoryEvent in der Repository-Datenbank aus.
Fehlerquellen Keine.
Beispiele fireRepositoryEvent("NotifyTrainer", hashMap(student:=userName(parameters.userGuid), exercise:=results.EXERCISE, status:="DONE", comment:=results.COMMENT) löst das generische Ereignis aus, um den Trainer in der CEE Academy darüber zu informieren, dass ein Schulungsteilnehmer eine Übung erledigt hat.

fireRepositoryEvent(7, "", hashMap()) löst das generische Ereignis mit dem Subtyp 7 und ohne Identifikation und Parameter aus.

Kontext ALL
Hinweise Ist ein Subtyp angeben, wird die Übergangsbedingung nur dann ausgewertet, wenn in der Aktivitätsdefinition der gleiche Subtyp ausgewählt ist. Verwenden Sie Subtypen, um die Anzahl der auszuwertenden Übergangsbedingungen zu reduzieren. Sind z. B. zehn Aktivitätsdefinitionen für das generische Ereignis registriert, aber nur eine davon soll beim Auflösen des Ereignisses eine Aktivität erzeugen, dann kann die Verwendung von Subtypen die Anzahl der ausgewerteten Übergangsbedingungen um 90 % reduzieren.
Siehe auch fireEvent

Folgendes Beispiel aus der Aktivitätsdefinition help.fireRepositoryEvent löst das generische Ereignis com.cisag.pgm.workflow.GenericRepositoryEvent in der Repository-Datenbank aus:

function create()
{
var p_message := parameters.MESSAGE;
if (p_message = "")
p_message := "Is there anybody out there?";

var params := new(HashMap);
params.sender := "SETI"; /* Searching for Event Trigger Interceptors */
params.message := p_message;

fireRepositoryEvent(definition:code, params);
}

Czy ten artykuł był pomocny?