BPM Server-Side Scripting

Deprecated starting with yuuvis® RAD 8.16 LTS

The page is valid for versions of yuuvis® RAD up to 8.14.

For yuuvis® RAD 8.16 LTS and later, please use the in-server documentation which is available on the rest-ws pages.


This page describes how to use API variables, functions and attributes in a server-side event script. The script executes after a process has fired an event.

Our process models library uses the scripting examples described here to implement several representative use-cases.

Event Types

Scripts are implemented for BPM server-side events. The script API described here should only be used in these event scripts.

The two main types of BPM server-side events are condition events and common events. For conditions, each event script must return a Boolean value. Common events need no return value.

Standard Event Types for all Activities

Every activity has an ActivityCreateCondition event. The corresponding script must return a Boolean value. When the returned value is true, the process engine creates the task for the process instance. When the value is false, the activity is not created, and no subsequent transitions and activities are created on this process path.

After a task is created, the BeforeStartActivity event is fired and the corresponding script is executed. If the activity is of type work item, no user interaction has happened yet. If the activity is a container, no container content has been executed yet.

After a task has been successfully processed, the BeforeEndActivity event is fired. For work item activities, this means all user interaction is done. For container activities, all container content is completed.

It makes no sense to implement these two events in route activities, since they would be fired successively, with no activity in between.

Work Item Activity Event Types

The work item activity additionally has the PersonalizeWorkitemCancelWorkitem and SaveWorkitem event types.

User interaction begins after the ActivityCreateCondition script returns true and after BeforeStartActivity is fired. A work item in this state produces inbox items, depending on performer configuration. If a user begins working on an inbox item, the item is personalized for the current user. All other inbox items of other assigned users are removed. The PersonalizeWorkitem event is fired during personalization. 

When the user returns the task, the CancelWorkitem event is fired. The SaveWorkitem event is fired when the task data changes are saved or the task is forwarded by the user.

Depending on the user's actions, these events can be fired multiple times. For example, if a user saves a form ten times, the SaveWorkitem event is fired ten times.

Work item activity events always run in the context of the user's permissions.

Container Activity Event Types

After the start condition script returns true and after the BeforeStartActivity event is fired, the container content is executed. When entering the container, a so-called scope is created. If all contained and created activities are finished, this scope is completed, and the SubscopeCompleted event is fired. For a loop container, the event is fired at each loop iteration. For a multi-instance container, the SubscopeCompleted event is fired each time an instance of container content is created.

Loop container event types

The loop container is special. After the start condition script returns true and after the BeforeStartActivity event is fired, the loop condition script is verified. The contained items are executed until the loop condition returns true. The loop condition event is fired at each iteration. It depends on the type of loop, at what point in time the event is fired. If you configured a pre-execution checking loop condition, the event is fired before entering the container. If you configured a post-execution checking loop condition, the container content is executed first. Once the subscope is completed, the event is fired.

Transition Events

A transition is a sequence flow between two activities. You can create a condition that determines whether a transition is executed. If an activity is successfully finished and has an outgoing transition, the Transition event is fired, for each transition. Since the Transition event is a conditional event, it must return a Boolean value. If true, this path is executed and the activity at the end of the transition is created.

Duration Events

If you defined durations in the process model, four additional events are possible. When the duration is completed, the event is fired and the script is executed. 

Because yuuvis® RAD differentiates between deadline durations and blocking durations, as well as between durations configured in the process model and dynamically-created durations, the four events are DeadlineFiredBlockingPeriodFiredDynamicDeadlineFired and DynamicBlockingPeriodFired. These events are completely detached from process execution.

Process Events

If an administrator stops the execution of a process and rolls it back, a ProcessRollBack event is fired. The process execution then restarts automatically.

Logging

To find programming errors on the client side, you can use a browser's debugging features. To debug on the server side, you can log information about processed script code into files.

Beginning with version 3.22.0

Debug log is on by default. Log level of the 'com.os.ecm.workflow.server.engine.scripting' package can be changed in the rest-ws console of yuuvis® RAD server or in the JBOSS-Management console, depending on the user's preferences. 

The following example shows how to log information, such as discrepancies, about variables and values.

$.log.info('performer: ' + p.performers[0].name)

The available log levels are debug (least serious), info, warn, and error (most serious).

By default, log files are stored in %JBOSS_HOME%/logs.

User Context

The CancelWorkitemSaveWorkitem, and PersonalizeWorkitem events run in the context of the logged-on user and the user's settings. The user triggers these events with a mouse click. The events run synchronously.

All other server scripts run without user context and without checking user permissions.

The $ Object

To prevent namespace clashes with custom or third-party libraries, all BPM objects and functions are encapsulated.

Process 

Use the variable 'process' to access a process object and its attributes running in the context of the current script.

var p = $.process;
// attributes of the 'process' variable are:
$.log.info('processId: ' + p.id);		
$.log.info('processName: ' + p.name); 	// technical name of the process			
$.log.info('creator: ' + p.creator); 	// user who started the process
$.log.info('creationTime: ' + p.creationTime); // time when the creator started the process
var creator = p.creator; 				// 'creator' is the organization object which started the process
var performers = p.performers; 			// array of all roles with which users can start the process
var responsible = p.responsible;     	// array of organization objects with which users can control the process

Time Period Attributes

If time periods are defined in the process model and if they are running ("ticking") they can be accessed using the process object '$.process'. The periods object '$.process.periods' is an array of all existing periods of the current process. A specific period can be accessed by its name.

Note that periods can be initiated multiple times, for example when added to a loop activity. In this case, the event script can only access the period instance with the newest start date. Furthermore, you have to be careful with the case-sensitive names of periods.

Reading Attributes

var period = $.process.periods.myPeriod;				// the periods map on the process object contains all periods. 
														// a period can be accessed either by iterating the map (until the desired period is found by desired search criteria) or by period name as defined in designer. 
														// in this example the name definded in designer is "myPeriod"
$.log.info('name: ' + period.name);					    // the period name as defined in the designer
$.log.info('id: ' + period.id);						    // the id of this period instance
$.log.info('startDate: ' + period.startDate);			// the start date of this period in ISO Format
$.log.info('fireDate: ' + period.fireDate);			    // the fire date of this period in ISO Format
$.log.info('state: ' + period.state);					// the state of this period, for example CREATED, TICKING, FIRED, STOPPED, ROLLEDBACK
$.log.info('type: ' + period.type);					    // the type of this period, for example DEADLINE, BLOCKINGPERIOD (= delay), DEADLINE_DYNAMIC, BLOCKINGPERIOD_DYNAMIC
$.done();

Updating the Fire Date of a Time Period

The fire date of a time period is the date and time at which the time period was started, plus its defined duration. You can use a script to change the fire date to a specific date, earlier or later than what was calculated at the time period start. The duration of the time period then depends on the new fire date.

As with other date variables, you have to use an ISO8601 date string.

var myPeriod = $.process.periods.['myPeriod'];	// this works as well, assuming that name of the period in designer is "myPeriod"
var newValue = new Date();						// using Oracle´s Date class to generate a new date object
newValue.setFullYear(2022);
newValue.setDate(5);
newValue.setMonth(4);
newValue.setHours(12);
newValue.setMinutes(0);
myPeriod.fireDate = newValue.toISOString();		// date values should always be saved as an ISO8601 String value
$.done();										// call the 'done' function to save changed values

Stopping a Running Time Period

You can change the state of a time period. For example, you can stop a running time period if a deadline is no longer necessary.

var myPeriod = $.process.periods.myPeriod;		// the periods array on the process object contains all periods
myPeriod.state = 'STOPPED';				
$.done();										// call the 'done' function to save changed values

Organization Object

The process creator has the following readable attributes:

var p = $.process;
var creator = p.creator;
creator.id;
creator.email;
creator.name;
creator.firstName;
creator.lastName;
creator.type = 'USER';

Process Creators, Performers and Persons Responsible

The process creator ("Initiator" in the UI) is the person who creates the process. A performer is a person, or organizations with members, who can start the process. Performers can be of type USER, GROUP, or ROLE. The person responsible ("Process Owner" in the UI) manages the process. 

var p = $.process;
for (var i in p.performers) {
    $.log.info('performer: ' + p.performers[i].name); // technical name of the org object
}
 
for (var i in p.responsible) {
    $.log.info('responsible: ' + p.responsible[i].name); // technical name of the org object
}
// set the process creator as process responsible

p.responsible.push($.process.creator);

Process Activities

Use the function "activity(name)" to access an activity. You can access all existing activities in a process. Load the activity's context with the name 'this'. The container of the event context loads with 'container', while the root or main activity loads with 'root'. You can also load an activity using its technical name.

Note: If you call an activity with its name in a loop, you only get the last activity processed.

var thisActivity = $.activity('this');          // 'this' is the activity of the current context in which the script (events: beforeStart, beforeEnd, personalize, cancel) runs
var thisContainer = $.activity('container');    // 'container' is the parent container of the current context in which the script runs
var mainActivity = $.activity('root');          // 'root' activity is the outmost container of the process
var myActivity = $.activity('invoiceCheck');     // load an activity by its name

The following example lists the attributes of process activities.

mainActivity.id;
mainActivity.name;
mainActivity.type;  // ROUTE, CONTAINER, LOOP, WORKITEM, MI_BY_NUMBER, MI_BY_DATA, MI_BY_PERFORMER, SUBPROCESS, NOTIFICATION, ADHOCCONTAINER
mainActivity.periods; // existing periods that start at this activity

Work Items

Performer and personalizer

All users forwarded a work item are performers. Once the work item is assigned to a single user, that user is the personalizer, and the remaining performers can no longer process the work item.

An activity of type 'workitem' needs to be processed by a user. In this case, the following attributes are available. All assigned potential performers of the work item can be read. Performers are of the 'OrgObject' type.

var workitem = $.activity('this');
 
for (var i in workitem.performers) {
    $.log.info('performer ' + i + ': ' + workitem.performers[i].firstName + ' ' + workitem.performers[i].lastName + ' ' + workitem.performers[i].locale);
}
 
// The performers can be manipulated by using all JavaScript Array Methods, for example:
 
var performers = workitem.performers;
performers.splice(0, performers.length); // deletes all performers
 
performers.push($.process.creator);       // assigning the process creator as performer
$.done() // save changes
 
// If a work item has been personalized, the following attributes can be read in the event WorkitemPersonalized
workitem.personalizer.id;
workitem.personalizer.name;         // login name
workitem.personalizer.firstName;
workitem.personalizer.lastName;
workitem.personalizer.title; // format is the same as in the client side form script: lastName, firstName
workitem.personalizer.email; 
workitem.clientLink;  // URL to open the task state in the client
// read the action code for activities which were forwarded within e.g. transition conditions to control the entry to the connected activity
$.activity('ativity name').resultCode;     
// in the BeforeEndActivity event script of the outgoing transition condition for the just forwarded activity
$.activity('this').resultCode; 

ResultCode of a forward action

In an activity with the type 'WORKITEM', the resultCode attribute is available in the event BeforeEndActivity. The resultCode is the code of the forward action the performer selected.

if ($.activity('this').type == 'WORKITEM') {
    var resultCode = $.activity('this').resultCode;
 
    if (resultCode == 100) {
        // do the magical stuff
    } else if (resultCode == 200) {
        // do the boring stuff  
    }
}

$.done(); // save changes

Performer: change and save

You can change the current performers of a work item.

$.activity('this').performers = []; // delete all
  
var newPerformer = new $.OrgObject();
newPerformer.id = '909EDB0B48D5430F987E49183B0E531E';   // only the id of the user is important, the user object will not be changed

$.activity('this').performers.push(newPerformer);   // adds a new performer

$.done(); // call this function at the end of the script to save the changes

Process Variables

When a process variable is visible in the scope, you can access it by its technical name, using the function 'variable(name)'.

var firstName = $.variable('firstname');
var lastName = $.variable('lastName');
 
// The variables have the following attributes:
firstName.value;
firstName.type;             // STRING, NUMBER, DATETIME, BOOLEAN, (LIST, CODESYSTEM, RECORD), see following descriptions
firstName.name;
 
// Changing a value:
firstName.value = 'Peter';
lastName.value = 'Fox';

// allocate the process creator to a process variable

var applicant = $.variable('applicant');
applicant.value = $.process.creator.id;
 
$.done();                      // call this function at the end of the script to save the changed values


As always in Javascript, set values without type. Be careful with field types to avoid a value not being stored. 

Following are some examples for different variable types.

Boolean

var field_boolean = $.variable('field_boolean');
var oldValue = field_boolean.value;
var newValue = true;
field_boolean.value = newValue;


String

var field_string_without_classifier = $.variable('field_string_without_classifier');
var oldValue = field_string_without_classifier.value;
var newValue = 'this is a string without classifier';
field_string_without_classifier.value = newValue;


String with Classifier

Classifiers are ignored by the script and handled like a normal string. The validation is then done by the server.

var field_string_classifier_web = $.variable('field_string_classifier_web');
var oldValue = field_string_classifier_web.value;
var newValue = 'www.google.de';
field_string_classifier_web.value = newValue;
  
var field_string_email = $.variable('field_string_email');
var oldValue = field_string_email.value;
var newValue = 'siegmund@freud.de';
field_string_email.value = newValue;


Number

During process modelling, numbers are differentiated by 'LONG' and 'DECIMAL' types. This is not necessary within the script. With decimals, be careful with 'Precision' and 'Scale' settings.

var field_long = $.variable('field_long');
var oldValue = field_long.value;
var newValue = 100250;
field_long.value = newValue;
  
var field_decimal = $.variable('field_decimal');
var oldValue = field_decimal.value;
var newValue = 1.456;
field_decimal.value = newValue;


Date and DateTime

During process modelling, 'Date' and 'DateTime' are handled differently. The script does not differentiate this.

Note: You must convert the assigned value to an ISO string. This transforms the date value to UTC timezone. The process engine converts it to the correct default timezone. To work directly with UTC time, use setUTCFullYear(...), setUTCDate(...) and so on. 

var field_date = $.variable('field_date');
var oldValue = field_date.value;
var newValue = new Date();
newValue.setFullYear(2018);
newValue.setDate(1);
newValue.setMonth(1);
field_date.value = newValue.toISOString();
  
var field_datetime = $.variable('field_datetime');
var oldValue = field_datetime;
var newValue = new Date();
newValue.setFullYear(2022);
newValue.setDate(5);
newValue.setMonth(4);
newValue.setHours(12);
newValue.setMinutes(0);
field_datetime.value = newValue.toISOString();


Codesystem (Catalog)

Set the value of a variable with the data value of the selected codesystem entry.

var field_catalog = $.variable('field_catalog');
var oldValue = field_catalog.value;
var newValue = 'Mr.';
field_catalog.value = newValue;

Record

The value of a record variable is an object of key/value pairs. The key is the member name.

var record = $.variable('myRecord');
record.value = {                                        // this record contains three fields: col_bool:BOOLEAN, col_string:STRING, col_datetime:DATE
    col_bool: true,
    col_string: 'Martin Fowler',
    col_datetime: new Date().toISOString()
};
 
$.done();        // call at the end of script to save the changes

List<Record>; Tables

Create new table row

Tables are based on records. The following example shows how to create a new table row.

var field_list_of_record = $.variable('field_list_of_record');
var item = field_list_of_record.createItem();         // creates an entry according to the variable type
item.value = {                                        // this record contains three fields: col_bool:BOOLEAN, col_string:STRING, col_datetime:DATE
    col_bool: true,
    col_string: 'Martin Fowler',
    col_datetime: new Date().toISOString()
};
 
field_list_of_record.value.push(item);
 
$.done();        // call at the end of script to save the changes

List and Set

The behavior of list and set is the same. You can add multiple entries during the script execution. The constraints of a set type are applied in the done() method (During script execution it is possible to have the same entries multiple times in a set field).

Set values

var field_list_of_string = $.variable('field_list_of_string');
var item = field_list_of_string.createItem();         // creates an entry according to the variable type
item.value = 'earth';
field_list_of_string.value.push(item);

var myArray = ['earth', 'mars', 'mars', 'jupiter', 'jupiter'];
field_list_of_string.addArray(myArray);

var field_set_of_string = $.variable('field_set_of_string');
var item = field_set_of_string.createItem();         // creates an entry according to the variable type
item.value = 'earth';
field_set_of_string.value.push(item);

field_set_of_string.addArray(myArray);

$.done();        // call at the end of script to save the changes

Read values

var field_list_of_string = $.variable('field_list_of_string');
var field_set_of_string = $.variable('field_set_of_string');

var list = field_list_of_string.toArray();  // ['earth','earth', 'mars', 'mars', 'jupiter', 'jupiter']
var set = field_set_of_string.toArray(); // ['earth', 'mars', 'jupiter']

$.done();        // call at the end of script to save the changes

Read Table Data

var positions = $.variable("table").value;
for(var i = 0; i < positions.length; i++){
  var curPos = positions[i].value;
  result += "No='"+doFormat(curPos.field1)+"' "; // doFormat helps in case of empty values
  result += "bpos='"+doFormat(curPos.field2)+"' ";
}


Process History

The process object 'history' is an array and contains all protocolled events (history entries).

Reading Entries

for (var i in $.history.entries) {
    $.history.entries[i].isPublic;          // entry can be read by any user
    $.history.entries[i].date;              // date the entry was written
    $.history.entries[i].type;              // type of event as shown in the 'designer'
    $.history.entries[i].userId;            // the ID of the user who was working in the context of the event
    $.history.entries[i].message;           // individual notification to inform about the context
}


Appending Individual Entries

var historyEntry = $.history.createEntry();                     // create a new entry
historyEntry.message = 'The invoice has been approved.';        // notification 
$.history.entries.push(historyEntry);                             // append to history object
 
$.done();        // call at the end of the script to save the changes

Getting a Process History and Create a DMS Object with its Content

You can use this sample code snippet to store the process history as the content of a DMS object. You do this by defining a process history object with some important data, and storing the history of the process as content of this object. Call this script in the before activity at the end of the main activity. In this case you should get all the information about the process.

// Get the process history from my currently running process
var response = $.http
    .get()
    .path('/service/bpm/process/{pid}/history')
    .param('pid', $.process.id)						// my process id
    .query('publish', false)						// false = more information
    .execute();

var protocol = response.data;			// the history of this process is a data block in json format

response = $.http						// the next call will create a DMS object of type protocol (protocol is a object type you have to create)
    .post()
    .path('/service/dms/create/protocol')
    .execute();

var objectId = response.data.id;		// we get the id of the new object instance

response = $.http						// at last we add the content to the new created object
    .post()
    .path('/service/dms/{id}/content')
    .param('id', objectId)				// the id of the previously created object
    .query('type', 'qdoc')
    .query('filename', 'process-' + objectId + '-history.json')	// you have to specify a filename
    .body(protocol)
    .execute();

Process Files

Reading Objects

Each process contains a process 'file' as an array of objects. This file is loaded on demand and contains all DMS objects that are associated with the process, without any further filters with regards to document visibility of the user in whose context the call is being executed.

Up to yuuvis 6.2, the 'isMainObject' property specifies the main object of the file (the object that was shown in the client in case that process is linked with multiple objects). As of yuuvis RAD 6.2, the client shows the first item in the array and the property was removed. 

var processFile = $.file.get();                   // load the process file (array of objects)
for (var i = 0 in processFile) {
    var dmsobject = processFile[i];
  
    dmsobject.id;
    dmsobject.title;
    dmsobject.description;
    dmsobject.version;
    dmsobject.finalized;
    dmsobject.type;
    dmsobject.created.on;
    dmsobject.created.by; // see OrgObject
    dmsobject.isFolder;
    dmsobject.isContextFolder;
    dmsobject.lock;
    dmsobject.data;
	dmsobject.clientLink;  // URL to open the dms object state in the client
    dmsobject.isMainObject;
}


Changing Object Data and Saving

A process file can contain any object.

var processFile = $.file.get();                 // load the process file
var dmsObject = processFile[0];                 // locate the first object of the file
dmsObject.data.format = '16:9';                 // 'format' is the name of an index data field and is set with that value '16:9'
processFile[0].save('this is a custom comment about the things which changed'); ´   // You must save the object explicitly. The custom comment is written into the object history. 
																					// But only if the object index data actually changes.

Adding a DMS Object to the Process File

Usually, you can add a DMS object during the process start or during user task interaction. But in some cases it is necessary to add a DMS object to the process file if an event occurs. You cannot add an object via bpm-script-api but you can call the bpm-service and post an new object to the process file without user interaction.

var dmsObjectId = '04055C7DE47C40F489C95F590E5BB340';  // the id of the dms object to be added
var dmsObjectType = 'bild';   // the type of the dms object
var http;

if ($.file.get().length > 0) {   // if any objects in the process file exist
    http = $.http.put();
} else {   // if not
    http = $.http.post();
}

var response = http
    .service('bpm') 
	.path('/api/bpm/process/'+$.process.id+'/file/'+dmsObjectId)
    .param('processId', $.process.id) 
    .param('dmsObjectId', dmsObjectId)
    .query('type', dmsObjectType)
    .execute();

HTTP Requests

During setup, you define the host address and a port for the services. This address is used for HTTP calls. The service infrastructure automatically routes each service call to the specific service and port. 

In event scripts, you can use the 'http' object to call endpoints according to the documented services APIs.

$.http; // an http object exists in each event script

HTTP Method

For the HTTP object, you have to prepare the http call with a function with the same name as the method you will call. The system automatically clears fields from earlier calls.

// the http object functions to prepare the call
$.http.get();                                       // prepare for http GET
$.http.post();                                      // prepare for http POST
$.http.put();                                       // prepare for http PUT
$.http.delete();                                    // prepare for http DELETE
$.http.patch();                                     // prepare for http PATCH

Services 

HTTP calls are no longer limited to the dms-service (REST-WS). Each service in the service landscape behind the gateway can be called (see Overview of Microservices). The http object handles these with the new 'services' function.

$.http.get().service('search');   // e.g. call the search service

Services include ADMIN, AGENT, ARGUS, BPM, CLIENT, DISCOVERY, DMS, EES, EXTRACTION, FAVORITE, INBOX, INDEX, MESSAGING, RENDITION, ROUTING, SEARCH, and TEMPLATE. For more information about APIs, refer to the microservices install and admin documentation.

The DMS service (REST-WS) is called by default.

It is important that http calls from an event script are routed via dmssidecar. This is why the path replacement of the gateway does not work here. Instead, you must write the whole path to your requested endpoint. A possible http call from Postman via Gateway is http://<gateway>/bpm/process/{pId}/file/{elemId} and in the event script you have to write the whole path http://<gateway>/bpm/api/bpm/process/{pId}/file/{elemId}.

You can use custom services developed in the service infrastructure in BPM scripts.

HTTP Path and Path Parameters

The path begins with a '/' and defines the path of the given service. Parameters in curly braces are replaced with the corresponding values when the path is executed.

$.http
	.get()
	.service('vacation')
	.path('/statistic/{year}/{month}');	// set the path of the request. You can also set parameter keys, which are replaced by the given parameters

$.http.param('year', '2017');
$.http.param('month', '10');			// these are the path parameters and replace the placeholders in the path

Query Parameters

Similar to the path parameter, you include key value pairs with the query function. All values are resolved when the call is executed. The API handles the delimiters '&' and '?' automatically.

$.http.query('key', 'value');                       // query parameter 
$.http.query('organisation', 'os-berlin');
$.http.query('department', 'development');			
// after execute() call, you get this resolution: http://<service>/<path>?organisation=os-berlin&department=development

Header Parameter

With the header function on the http object, you can set any key value pairs for the http header. The code sample below sets the content-type as a header parameter.

$.http.header('content-type', 'text/xml; charset=UTF-8');

HTTP Body

The body has to be a JSON object. Call the body function with this object.

$.http.body({a:'value1', b:'value2'});

This body accepts an object that will always be stringified as JSON. To create a body without stringification, you have to call the raw method, as shown in the example below. Note that you must also set a content-type in this case. (from release 2018-2-28)

 $.http.post()
	.service('protocolservice')
	.header('content-type', 'text/xml; charset=UTF-8')		// set the content-type of the body
	.body('<xml>This is a document content ...</xml>')      // set a arbitrary body as string
	.raw()													// mark the body as a raw object
	.execute();                                             // exceute the call

HTTP Execute and Response

After defining the options of the HTTP call, you execute it. The response always includes the status. If the call succeeds (http status code < 300), you get the data response. If the call fails (http status >= 300), the response includes an error field with a reason. Refer to the HTTP status codes for more information.

var response = $.http
	.get()
	.service('vacation')
	.path('/status/{year}/{month}')
	.param('year', '2017')
	.param('month', '10')
	.query('includeIllness', false)
	.query('remainingHoliday', true)
	.execute();

// will produce: http://<serviceHost>:<servicePort>/vacation/status/2017/10?includeIllness=false&remainingHoliday=true

response.status;                                    // contains the http status code
repsonse.reason;                                    // exists if an error occurred, contains the reason for the error
response.error;                                     // exception message
response.data;                                      // the returning data object


The following examples show how to use HTTP requests.

Setting Read Permissions for File Elements

Setting Read Permissions for Process File Elements

If users do not have read permission for a process file element, you can grant permission.

To see a description of the corresponding API call, call the following URL on your installed system: 
http://<hostname>/rest-ws/#ENDPOINT:DmsService.putAdditionalVisibilityList

Note: If you plan to call it in events running in the user context, you must switch to the system context. For more information, see here.

The following code snippet from a project shows how it is used.

/**
* functions for adding additional visibility START
*/
this.addOrgObjectToInvoiceVisibility = function(orgObjectName) {
	this.$.log.info(this.LOG_TAG + "[addOrgObjectToInvoiceVisibility] start");
	this.$.log.info(this.LOG_TAG + "[addOrgObjectToInvoiceVisibility] dmsInvoice.id: " + this.$.variable("dmsInvoiceId").value);

	globals.addOrgObjectsToVisibilityListSu(orgObjectName, this.$.variable("dmsInvoiceId").value);
}

this.addOrgObjectsToVisibilityListSu = function(orgObjectName, dmsObjectId) {
	this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] start");
	this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] dmsObjectId= [" + dmsObjectId + "]");

	// get list of currently assigned additional visibility users and groups 
	var targetObjectAddVis = globals.getObjectsAdditionalVisibilitiesSu(dmsObjectId);

	//flatten and filter for possible doublettes
	var tmpList = [];
	for (i=0; i<targetObjectAddVis.length; i++) {
		if (tmpList.indexOf(targetObjectAddVis[i].name) < 0) {
			tmpList.push(targetObjectAddVis[i].name); 
		}
	}

	targetObjectAddVis = tmpList;
	this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] targetObjectAddVis: "+JSON.stringify(targetObjectAddVis));
	//
	var orgObjectsToAdd = [];
	var activity = this.$.activity("this");

	//build up worklist

	if (orgObjectName.length > 0) {
		if (targetObjectAddVis.indexOf(orgObjectName) < 0) {
			orgObjectsToAdd.push(orgObjectName);
		} 
	} else {
		if (activity.personalizer) {
			this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] adding personalizer to workload [" + activity.personalizer.name + "]");

			if (targetObjectAddVis.indexOf(activity.personalizer.name) < 0) {
				orgObjectsToAdd.push(activity.personalizer.name);
			} 
		} else {
			var performers = activity.performers;
			this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] adding performers JSON.stringify(performers) [" + JSON.stringify(performers) + "]");
			
			for (var i = 0; i < performers.length; i++) {
				//orgObjectsToAdd.push(this.getUserName(performers[i].id));
				if (targetObjectAddVis.indexOf(performers[i].name) < 0) {
					orgObjectsToAdd.push(performers[i].name);
				}
			}
		}
	}

	//only perform operations if necessary 
	if (orgObjectsToAdd.length > 0) {
		//add our additions
		for (i=0; i<orgObjectsToAdd.length; i++) {
			if (targetObjectAddVis.indexOf(orgObjectsToAdd[i]) < 0) {
				targetObjectAddVis.push(orgObjectsToAdd[i])
			}
		}	

		//prep operation
		var postBody = {};
		postBody['organizationobjects'] = targetObjectAddVis;
		this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu]postBody: "+JSON.stringify(postBody));

		this.$.http.put()
			.path('/service/dms/additionalvisibility/{id}')
			.param("id", dmsObjectId)
			.body(postBody);

		//fire operation
		var response;
		this.$.sudo(function() { response = $.http.execute()});

		//process result
		if(!response.reason) {
			this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] update successfull: "+JSON.stringify(response));
			return true;
		} else {
			this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] update not successfull:"+JSON.stringify(response));
		}
	} else {
		this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu]update not necessary");
	}

	this.$.log.info(this.LOG_TAG + "[addOrgObjectsToVisibilityListSu] end");
	return false;
}

this.getObjectsAdditionalVisibilitiesSu = function(objectId) {
	this.$.log.info(this.LOG_TAG + "[getObjectsAdditionalVisibilitiesSu] start with objectId: "+objectId);

	this.$.http
		.get()
		.path("/service/dms/{id}/")
		.param("id",objectId)
		.query('additionalvisibility', true)
		.query('fields', false)
		.query('content', false);

	var response;
	this.$.sudo(function() { response = $.http.execute()});

	if(!response.reason) {
		this.$.log.info(this.LOG_TAG + "[getObjectsAdditionalVisibilitiesSu] response: "+JSON.stringify(response));
		
		var additionalvisibility = null;

		if (response.data != null) {
			additionalvisibility = response.data.additionalvisibility;
			this.$.log.info(this.LOG_TAG + "[getObjectsAdditionalVisibilitiesSu] succesfull with "+JSON.stringify(additionalvisibility));

			if(response.data != null) {
				return additionalvisibility;
			} else {
				return [];
			}
		} else {
			this.$.log.info(this.LOG_TAG + "[getObjectsAdditionalVisibilitiesSu] query not successfull, no hit");
			return [];
		}
	} else {
		this.$.log.info(this.LOG_TAG + "[getObjectsAdditionalVisibilitiesSu] query not successfull, reason: " + response.reason);
		return [];
	}
}

/**
* functions for adding additional visibility END
*/

Creating Link Documents

A link document is a document object that contains a link to the content file of another document object. When you open the first object, the content of the second object is shown in the preview.

// first create the new document object (=documentId) from type 'doctype' 
// with the same index data as the (source) document object
// of the content file (=sourceDocumentId) within a specific folder (=docFolderId)
$.http.post();
$.http.path('/service/dms/create/doctype');
$.http.query('parentType', 'register'); 
$.http.query('parentId', docFolderId); 
$.http.query('usercomment', 'Documentation copied from ' + sourceobject.title); 
$.http.body( sourceobject.data );
var documentId = execHttp(201).id;
// then create the link to the content of the source object
$.http.put();
$.http.path('/service/dms/{documentId}/content/link/{sourceDocumentId}');
$.http.param('documentId', documentId); 
$.http.param('sourceDocumentId', sourceDocumentId); 
$.http.query('usercomment', 'Document publishing'); 
$.http.query('type', 'document'); 
execHttp(204);
// Helper function to execute the http call and do the error handling
function execHttp(status) {
 var ret = $.http.execute();
 if( ret.status!=status ) {
 throw "Unexpected http status code "+ret.status+" for http "+$.http;
 }
 return ret.data;
}


Starting a Process Within an Event Script

You can start a process within an event script by calling the modelid, the projectid or the project path. Using the project path is the preferred way to call a process, since it does not require an ID.

You have to use the http-connector. With this you can call every REST-ws endpoint.

Starting a process using modelid

// You can start a process and put some process parameters to it. The following example uses the parameters 'firstname' and 'lastname'.
// Additionally you can put an object to the process. The process engine will put it into the process file.
// The context variable will be the body of the request later.
 
var context = {
    data: {
        firstname: 'Ada',
        lastname: 'Lovelace'
    },
    contents: {
        0: {
            id: '7F822BD2065744CBA85736FD5A10179B',
            type: 'Image'
        }}
};
 
// Define a post request, set the endpoint and put a query parameter and the defined body object. Then execute.
var res = $.http.post().path('/service/bpm/process')
    .query('modelid', '310FCE1DC0A04247A793FBDEB5DA32F6')
    .body(context)
    .execute();

Starting a process using projectid

Use the context and body as above.

$.http.post().path('/service/bpm/process')
    .query('projectid', '123')    // The projectid of a process model can be looked up via REST-WS call.
    .execute();

Starting a process using project path

This is the preferred way to start a process within an event script. Use the context and body as above.

$.http.post().path('/service/bpm/process')
    .query('projectpath', 'myModelGroup')
// The project path parameter shall contain the model group name, from which the default model of the model group will be started. 
// Model groups and model status are managed in the management studio, and the default model shall be also activated in order to be started. 
// Special characters in path should be encoded, for instance if project names contains empty spaces, you have to encode this with '+' or '%20'.
    .execute();

Sending E-mails

You can use a web service-based message service to send an e-mail update to a user.

// first prepare the attachments, example 1 with a Base64-encoded string
var attachmentBase64 = "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MAowIDYwMCA2MDAgMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCAwIDYwMCAwIDAgNjAwIDYwMAo2MDAgMCA2MDAgNjAwIDYwMCAwIDYwMCA2MDAgNjAwXQovRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL1N1YnR5cGUvVHlwZTE+PgplbmRvYmoKMTIgMCBvYmoKPDwvQmFzZUZvbnQvVFhRUVFUK0hlbHZldGljYS9Gb250RGVzY3JpcHRvciAxMyAwIFIvVHlwZS9Gb250Ci9GaXJzdENoYXIgMzIvTGFzdENoYXIgMTE2L1dpZHRoc1sKMjc4IDAgMCAwIDAgODg5IDAgMCAzMzMgMzMzIDAgMCAyNzggMzMzIDI3OCAwCjU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiAyNzggMCAwIDU4NCAwIDAKMCA2NjcgNjY3IDcyMiA3MjIgNjY3IDYxMSA3NzggMCAyNzggMCA2NjcgNTU2IDgzMyA3MjIgNzc4CjY2NyAwIDcyMiA2NjcgNjExIDcyMiA2NjcgOTQ0IDY2NyA2NjcgMCAwIDAgMCAwIDAKMCAwIDAgMCA1NTYgNTU2IDAgMCAwIDIyMiAwIDAgMCAwIDAgMAowIDAgMzMzIDAgMjc4XQovRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL1N1YnR5cGUvVHlwZTE+PgplbmRvYmoKOSAwIG9iago8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL1BRVEREVytIZWx2ZXRpY2EtQm9sZC9Gb250QkJveFstMjIgLTIxOSA5MzIgNzQxXS9GbGFncyAzNAovQXNjZW50IDc0MQovQ2FwSGVpZ2h0IDc0MQovRGVzY2VudCAtMjE5Ci9JdGFsaWNBbmdsZSAwCi9TdGVtViAxNTAKL01pc3NpbmdXaWR0aCAyNzgKL1hIZWlnaHQgNTQ5Ci9DaGFyU2V0KC9BL0IvQy9EL0UvRi9HL0gvSS9LL0wvTS9OL08vUC9SL1MvVC9VL1YvVy9YL1kvWi9hL2IvYy9jb2xvbi9jb21tYS9kL2UvZWlnaHQvZi9maXZlL2ZvdXIvZy9oL2h5cGhlbi9pL2svbC9tL24vbmluZS9vL29uZS9wL3BlcmlvZC9yL3Mvc2V2ZW4v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ZGY6YWJvdXQ9J2JkNDdlZWRkLWE3ZGMtMTFlNi0wMDAwLWJmOTcxNTgxNTNlMScgeG1sbnM6eG1wPSdodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvJz48eG1wOk1vZGlmeURhdGU+MjAxNi0xMS0wOFQwODowMTo1OCswMTowMDwveG1wOk1vZGlmeURhdGU+Cjx4bXA6Q3JlYXRlRGF0ZT4yMDE2LTExLTA4VDA4OjAxOjU4KzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT4KPHhtcDpDcmVhdG9yVG9vbD5TZXJ2ZXIgaHR0cDovL3d3dy5hY3RpdmVwZGYuY29tPC94bXA6Q3JlYXRvclRvb2w+PC9yZGY6RGVzY3JpcHRpb24+CjxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSdiZDQ3ZWVkZC1hN2RjLTExZTYtMDAwMC1iZjk3MTU4MTUzZTEnIHhtbG5zOnhhcE1NPSdodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vJyB4YXBNTTpEb2N1bWVudElEPSdiZDQ3ZWVkZC1hN2RjLTExZTYtMDAwMC1iZjk3MTU4MTUzZTEnLz4KPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9J2JkNDdlZWRkLWE3ZGMtMTFlNi0wMDAwLWJmOTcxNTgxNTNlMScgeG1sbnM6ZGM9J2h0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvJyBkYzpmb3JtYXQ9J2FwcGxpY2F0aW9uL3BkZic+PGRjOnRpdGxlPjxyZGY6QWx0PjxyZGY6bGkgeG1sOmxhbmc9J3gtZGVmYXVsdCc+UHJpbnQgVG8gRmlsZTwvcmRmOmxpPjwvcmRmOkFsdD48L2RjOnRpdGxlPjxkYzpjcmVhdG9yPjxyZGY6U2VxPjxyZGY6bGk+U1ZDX0RFRlJJWldBUFAxMDAxPC9yZGY6bGk+PC9yZGY6U2VxPjwvZGM6Y3JlYXRvcj48L3JkZjpEZXNjcmlwdGlvbj4KPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSd3Jz8+CmVuZHN0cmVhbQplbmRvYmoKMiAwIG9iago8PC9Qcm9kdWNlcihhY3RpdmVQREYgU2VydmVyKQovQ3JlYXRpb25EYXRlKEQ6MjAxNjExMDgwODAxNTgrMDEnMDAnKQovTW9kRGF0ZShEOjIwMTYxMTA4MDgwMTU4KzAxJzAwJykKL1RpdGxlKFByaW50IFRvIEZpbGUpCi9DcmVhdG9yKFNlcnZlciBodHRwOi8vd3d3LmFjdGl2ZXBkZi5jb20pCi9BdXRob3IoU1ZDX0RFRlJJWldBUFAxMDAxKQovRlMoRm9ybVNjYXBlIFNvZnR3YXJlIDM0NTk0KT4+ZW5kb2JqCnhyZWYKMCAyMwowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDQ2OTIgMDAwMDAgbiAKMDAwMDAyNzk5NiAwMDAwMCBuIAowMDAwMDA0NjMzIDAwMDAwIG4gCjAwMDAwMDQ0NDMgMDAwMDAgbiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDA0NDIzIDAwMDAwIG4gCjAwMDAwMDQ3NTcgMDAwMDAgbiAKMDAwMDAxMzc0OCAwMDAwMCBuIAowMDAwMDE0OTU1IDAwMDAwIG4gCjAwMDAwMTQyMTIgMDAwMDAgbiAKMDAwMDAxOTc1MCAwMDAwMCBuIAowMDAwMDE0NTM4IDAwMDAwIG4gCjAwMDAwMjI4ODIgMDAwMDAgbiAKMDAwMDAxMTgzMSAwMDAwMCBuIAowMDAwMDA0ODcxIDAwMDAwIG4gCjAwMDAwMDQ3OTggMDAwMDAgbiAKMDAwMDAwNDgyOCAwMDAwMCBuIAowMDAwMDEzNjk2IDAwMDAwIG4gCjAwMDAwMTUzNzkgMDAwMDAgbiAKMDAwMDAyMDA5MiAwMDAwMCBuIAowMDAwMDIzMjg0IDAwMDAwIG4gCjAwMDAwMjY1MDcgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAyMyAvUm9vdCAxIDAgUiAvSW5mbyAyIDAgUgovSUQgWzxEMzk2QkU4RUY4MUNCMjczNTJDQTk1NkJDNURCRTQ3RD48RDM5NkJFOEVGODFDQjI3MzUyQ0E5NTZCQzVEQkU0N0Q+XQo+PgpzdGFydHhyZWYKMjgyMzcKJSVFT0YKMjQgMCBvYmoNPDwNL1R5cGUgL1NpZw0vRmlsdGVyIC9BZG9iZS5QUEtMaXRlDS9TdWJGaWx0ZXIgL2FkYmUucGtjczcuc2hhMQ0vUiA2NTU0MQ0vTSAoRDoyMDE2MTEwODA3MDE1OVopDS9OYW1lIChJbmdyYW0gTWljcm8gVUsgTHRkKQ0vUmVhc29uIChJbnZvaWNlcykNL0xvY2F0aW9uIChXeW1idXNoLCBNaWx0b24gS2V5bmVzLCBVSywgIFZBVCBObzogR0I0NDAzNTUyODBccikNL0NvbnRhY3RJbmZvICg8bm9uZT4pDQ0vQ29udGVudHMgPDMwODIwNzc2MDYwOTJhODY0ODg2ZjcwZDAxMDcwMmEwODIwNzY3MzA4MjA3NjMwMjAxMDEzMTBmMzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMDUwNTAwMzAyMzA2MDkyYTg2NDg4NmY3MGQwMTA3MDFhMDE2MDQxNDU3MzIxZGI1NGY3NWUyZGYxYTg4MDY4M2Q1Y2RjZjk2YzFlN2U5ZGZhMDgyMDU3MTMwODIwNTZkMzA4MjA0NTVhMDAzMDIwMTAyMDIxMDQ2ZTQxNDUxODUzNGZhNGFkZDk2ZDA5ZWIzZTllODM2MzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMGIwNTAwMzA3MTMxMGIzMDA5MDYwMzU1MDQwNjEzMDI0OTQ1MzExNjMwMTQwNjAzNTUwNDA4MTMwZDQzNmY3NTZlNzQ3OTIwNDQ3NTYyNmM2OTZlMzEwZjMwMGQwNjAzNTUwNDA3MTMwNjQ0NzU2MjZjNjk2ZTMxMWEzMDE4MDYwMzU1MDQwYTEzMTE0NDY5Njc2OTJkNTM2OTY3NmUyMDRjNjk2ZDY5NzQ2NTY0MzExZDMwMWIwNjAzNTUwNDAzMTMxNDQ0Njk2NzY5MmQ1MzY5Njc2ZTIwNDM0MTIwNDQ2OTY3NjkyZDQ5NDQzMDFlMTcwZDMxMzUzMDM0MzAzOTMwMzAzMDMwMzAzMDVhMTcwZDMxMzczMDM0MzAzODMyMzMzNTM5MzUzOTVhMzA4MWY5MzEwYjMwMDkwNjAzNTUwNDA2MTMwMjQ3NDIzMTE2MzAxNDA2MDM1NTA0MDcxMzBkNGQ2OTZjNzQ2ZjZlMjA0YjY1Nzk2ZTY1NzMzMTFjMzAxYTA2MDM1NTA0MGExMzEzNDk2ZTY3NzI2MTZkMjA0ZDQ5NjM3MjZmMjA1NTRiMjA0Yzc0NjQzMTBmMzAwZDA2MDM1NTA0MGIxMzA2NDM3MjY1NjQ2OTc0MzEyNDMwMjIwNjAzNTUwNDBiMTMxYjY5NzM3Mzc1NjU2NDIwNjI3OTIwNDQ2OTY3NjkyZDUzNjk2NzZlMjA0YzY5NmQ2OTc0NjU2NDMxMmMzMDJhMDYwMzU1MDQwYjE0MjM3NjYxNmM2OTY0NjE3NDY1NjQyMDYyNzkyMDQ0Njk2NzY5MmQ1MzY5Njc2ZTIwNGM2OTZkNjk3NDY1NjQyMDViNTg1MzVkMzExYzMwMWEwNjAzNTUwNDAzMTMxMzQ5NmU2NzcyNjE2ZDIwNGQ2OTYzNzI2ZjIwNTU0YjIwNGM3NDY0MzEzMTMwMmYwNjA5MmE4NjQ4ODZmNzBkMDEwOTAxMTYyMjY5NmU3NjZmNjk2MzY1NjI2Zjc1NmU2MzY1MmU3NTZiNDA2OTZlNjc3MjYxNmQ2ZDY5NjM3MjZmMmU2MzZmMmU3NTZiMzA4MjAxMjIzMDBkMDYwOTJhODY0ODg2ZjcwZDAxMDEwMTA1MDAwMzgyMDEwZjAwMzA4MjAxMGEwMjgyMDEwMTAwY2Y0YmUxMGNhNjE0OWE2NjIyM2JiYjE0NDNjZDhmMzJjYTJmOTEzNGUwZjYyNWIwMTFkMzc2NzU3ZmQ3ZmRmYzdlNjg4MzkzOWJkYjc0YWI1MzFhZTBhNTBkOGU1MDIzOWFiMzg5ZTg3ZDVjZDQ2MjFiZWM4ZTk3MjhmN2ZiODI2NTE4N2ZiZjIwYWFkMzg2NmJjMGZkYTliODA5MThiZDBlMjVjNDM3ZjA1YWM0OTY3OWI4OWY2ZGJiNTQ5ZmM2MDFmZDIyNjU2OTQyYzNmNDAwNzk2YWVhNTVkY2IzZDM0YThjYWYxMWI4NzAyMGJjNDVhMTBjZGVlMTFmMzUyZDdhYTUxOTZlM2I1YzM5NDc2NzNhMjA4NGU5YzU4ZTkzZTY2MjU4NTJmZjM5NzdmYWQ2MGVhYzU3ZGM5OWZiYjUwMGFhNDM2OGY5NDY5MDA2MTIyNzZiZjlhNmJlZmEwYzM5YTU2MTkyZmJjMjQ2ZDJhZjkwY2YwYjMzNDExM2VkZjM5MWVlNDhkN2QwOTE5ZWE5MjM2M2QxMGU0ZTE1NWYzZGNlODUxZTI5ODc0MWY2NThlNTE5MGJiNTNjMmQwNTg4ZjJiM2QzY2ZjNTg0YTk0OWJjNTU2ODUzNDhhMDAwOGU4MTQzYTRkYjFjNzhmZTlmMzdmYTkzYzc3OTcyM2YwMjAzMDEwMDAxYTM4MjAxNzYzMDgyMDE3MjMwMWYwNjAzNTUxZDIzMDQxODMwMTY4MDE0ZDczYjgyYTYyYjMxY2RiMTk0OWViN2VhNjYyOTNhYzUzZDE2YzBiZjMwMWQwNjAzNTUxZDBlMDQxNjA0MTRhMDExNDgzZDZiMjFjZWIxNzExMzY4NmEwNzhjNDAwYzc4YjEzNDM2MzAwZTA2MDM1NTFkMGYwMTAxZmYwNDA0MDMwMjA1YTAzMDBjMDYwMzU1MWQxMzAxMDFmZjA0MDIzMDAwMzAxZDA2MDM1NTFkMjUwNDE2MzAxNDA2MDgyYjA2MDEwNTA1MDcwMzA0MDYwODJiMDYwMTA1MDUwNzAzMDIzMDQxMDYwMzU1MWQyMDA0M2EzMDM4MzAzNjA2MGIyYjA2MDEwNDAxYjIzMTAxMDIwMjA5MzAyNzMwMjUwNjA4MmIwNjAxMDUwNTA3MDIwMTE2MTk2ODc0NzQ3MDczM2EyZjJmNjM3MDczMmU3NTczNjU3Mjc0NzI3NTczNzQyZTYzNmY2ZDMwM2UwNjAzNTUxZDFmMDQzNzMwMzUzMDMzYTAzMWEwMmY4NjJkNjg3NDc0NzAzYTJmMmY2MzcyNmMyZTc1NzM2NTcyNzQ3Mjc1NzM3NDJlNjM2ZjZkMmY0NDY5Njc2OTUzNjk2NzZlNDM0MTQ0Njk2NzY5NDk0NDJlNjM3MjZjMzA3MDA2MDgyYjA2MDEwNTA1MDcwMTAxMDQ2NDMwNjIzMDM5MDYwODJiMDYwMTA1MDUwNzMwMDI4NjJkNjg3NDc0NzAzYTJmMmY2MzcyNzQyZTc1NzM2NTcyNzQ3Mjc1NzM3NDJlNjM2ZjZkMmY0NDY5Njc2OTUzNjk2NzZlNDM0MTQ0Njk2NzY5NDk0NDJlNjM3Mjc0MzAyNTA2MDgyYjA2MDEwNTA1MDczMDAxODYxOTY4NzQ3NDcwM2EyZjJmNmY2MzczNzAyZTc1NzM2NTcyNzQ3Mjc1NzM3NDJlNjM2ZjZkMzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMGIwNTAwMDM4MjAxMDEwMDc0ZDFiZWE4OWY3OTI5MmU5YTgxNjY2OTU1MDljODZlYWUzN2ZlMTU1ZGI1NWM4YjBhNDQ4MDg3NmZiZTE3ODIwMDMwYTVjZDg1N2I0OTU3MmQ3MTEwMWQxNWZkMGQ1ZDlkMTA0MzJhYjUyMmVkNmY2MGE4MzBjNDk1NGM4YjRhOWMxODcwZDk3ODVhZDI2YmNlMzY2MDY5NTA4YTg5YmY1MzI1NDBlNTUxODQ2YjQwZGFmMjFhYWJmYzQxZjdiMmVhZDQ4YTA2MWMzZThkMmVlNWNjOTNkZmI2MWYwNWZlM2EyMGM0ZTAwMWIyM2NhZTkzY2Y5NDFkOTM4ZjlhY2I3NWJmYTE2Y2FjYTYzNzgzNDRiYzI1ZmNlMWUyZGUwNmQ0YzUyZDIzMDEyNDY4YjcxN2EwYTNhOGZjYmFhZjVmZGI0MTBmM2U2NmJjNzAxNDAzNjljN2I0MDRkODc5ZTc1NjIyMDUyZmU3NWQ3MjVkNjY2ZjRhZDU0ZjRhY2EwY2U4YTgxNTRhODY5MDJlNTAzY2YzNTIzNGNjNDQ5ODc5YTg5NzQ2ZDdiYWVhYjZiOGFkMWY2NWFjZjA3NmI2N2Y5NGMzZGY1YTg2ZTg2YzhkNGU3YTFlOTFjMjBiMTA0YjgxOGQzZjc2MTc5OWFiMWJjMGUzZWNiMGYyOTE1YjU4MzE4MjAxYjEzMDgyMDFhZDAyMDEwMTMwODE4NTMwNzEzMTBiMzAwOTA2MDM1NTA0MDYxMzAyNDk0NTMxMTYzMDE0MDYwMzU1MDQwODEzMGQ0MzZmNzU2ZTc0NzkyMDQ0NzU2MjZjNjk2ZTMxMGYzMDBkMDYwMzU1MDQwNzEzMDY0NDc1NjI2YzY5NmUzMTFhMzAxODA2MDM1NTA0MGExMzExNDQ2OTY3NjkyZDUzNjk2NzZlMjA0YzY5NmQ2OTc0NjU2NDMxMWQzMDFiMDYwMzU1MDQwMzEzMTQ0NDY5Njc2OTJkNTM2OTY3NmUyMDQzNDEyMDQ0Njk2NzY5MmQ0OTQ0MDIxMDQ2ZTQxNDUxODUzNGZhNGFkZDk2ZDA5ZWIzZTllODM2MzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMDUwNTAwMzAwZDA2MDkyYTg2NDg4NmY3MGQwMTAxMDEwNTAwMDQ4MjAxMDBiNTczMzU2YWE4Y2EwMTZjODY4MzllYTM2NTIwOTNhYzNhZTdhNDFhOGNiZTUwZTlhZWUxMjY4MTljNjQ3MjE5N2FhNWExODA5ZjE1ZGIxMzJkZWViZmRiYTU4YjAwYWNhNWVjNDE4NTAzMWY5NDhkMzQ0YjE2ODU2NWY5M2QyZTU5MjgyMjY2MGUzMjcwMjQyMzFhMTYwMjMzZjgzZmVkMjM0ZDg3YWM3NjE1MTZhMTcyZWJiMDM3NTE5YmUxNGVlZWY1ZDc3MDllY2IwNjlhYjVhZjYyM2QzMGQ3ZThkOWZiOTI5Yzk3ZjBhODZmYjJjODQ2Yjg5NGM2NjNiMDM1OWMyNjU0OTMwMzY5ZjdmYTRhMGVmNzQzZTc4MjY2NDVkZGJmNWU5YjQwZWIwOGNkODlmZTdkMTIxZjU0MWI3YWE4MDI0MThkOTE5OTc1YjNjYTEzNjk2YTJiYWM2NTI0N2Y5NzZjYWU5ZjRjNmQ0ODRhMzk2ZjVjMTU5MzE5YWZmODZkNDgyZTg5ZDJjNzZjYTdiZmEyNjU4ZGI4ZTJjNjlhY2YyNDdlZjNjNjNlODEzMzgzMzFhYjk5Yzc4ZDllNjNmZjMxOTdkZjFmZjY5MGE2ODY2NGJmNDRjZmZlN2FlNGQ3ZTQ1OTA2MGM3YTFmMDEyZjcyNzNjZTgyZmVjMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwPiANL0J5dGVSYW5nZSBbMCAyOTEwMCAzMzE2MCAxMDc2XSAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Pg1lbmRvYmoNMjUgMCBvYmoNPDwvVHlwZSAvQW5ub3QgL0ZUIC9TaWcgL1N1YnR5cGUgL1dpZGdldA0vUmVjdCBbMCAwIDAgMF0NL0YgMTMyIC9TaWdGbGFncyAzDS9UIChBUFRLX1NpZ25hdHVyZV8yNSkNL1YgMjQgMCBSDQ0vUCA0IDAgUj4+DWVuZG9iag00IDAgb2JqDTw8IC9UeXBlIC9QYWdlIC9NZWRpYUJveCBbIDAgMCA1OTUuMjggODQxLjg5IF0gL1JvdGF0ZSAwIC9QYXJlbnQgMyAwIFIgL1Jlc291cmNlcyA8PCAvUHJvY1NldCBbIC9QREYgL0ltYWdlQyAvVGV4dCBdIC9FeHRHU3RhdGUgMTYgMCBSIC9YT2JqZWN0IDE3IDAgUiAvRm9udCAxOCAwIFIgPj4gL0NvbnRlbnRzIDUgMCBSIC9Bbm5vdHMgWyAyNSAwIFIgXSA+Pg1lbmRvYmoNMjYgMCBvYmoNPDwNL1R5cGUgL0ZvbnQNL1N1YnR5cGUgL1R5cGUxIA0vRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZw0vQmFzZUZvbnQgL0hlbHZldGljYQ0+Pg1lbmRvYmoNMjcgMCBvYmoNWzI1IDAgUl0NZW5kb2JqDTI4IDAgb2JqDTw8L0ZpZWxkcyAyNyAwIFINL0RSIDw8L0ZvbnQ8PC9IZWx2IDI2IDAgUj4+ICA+Pi9TaWdGbGFncyAzIC9EQSgvSGVsdiAwIFRmIDAgZyk+Pg1lbmRvYmoNMSAwIG9iag08PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgL01ldGFkYXRhIDIyIDAgUiAvQWNyb0Zvcm0gMjggMCBSID4+DWVuZG9iag14cmVmDQoxIDENCjAwMDAwMzM4MTAgMDAwMDAgbg0KNCAxDQowMDAwMDMzMzY4IDAwMDAwIG4NCjI0IDUNCjAwMDAwMjg4NTEgMDAwMDAgbg0KMDAwMDAzMzIzMSAwMDAwMCBuDQowMDAwMDMzNTg4IDAwMDAwIG4NCjAwMDAwMzM2ODcgMDAwMDAgbg0KMDAwMDAzMzcxMiAwMDAwMCBuDQoyOCAxDQowMDAwMDMzNzEyIDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgMjkvUm9vdCAxIDAgUi9JbmZvIDIgMCBSL0lEWzxEMzk2QkU4RUY4MUNCMjczNTJDQTk1NkJDNURCRTQ3RD48RDM5NkJFOEVGODFDQjI3MzUyQ0E5NTZCQzVEQkU0N0Q+XS9QcmV2IDI4MjM3ID4+DQpzdGFydHhyZWYNCjMzODkzDQolJUVPRg0K";
var attachment1 = {
	name: "160006874EBUKA-1.pdf",
	contenttype: "application/pdf",
	binarycontent : {
		value: attachmentBase64
	}
}


// and a second attachment which is an original file stored in yuuvis, defined by its object type and ID (= variable 'Attachment')
var attachment2 = {
	objectcontent : {
		type: $.variable('Objecttype').value,
		id: $.variable('Attachment').value,
		rendition: "pdf"				// optional, or "tiff" / "jpeg", if not set, the original document file is attached
	}
};

// now prepare the body of the HTTP request:
var jsonBody = {
	from: $.variable('Sender').value,
	to: $.variable('Receiver').value,
	cc: $.variable('ReceiverCC').value,
	subject: $.variable('Subject').value,
	body: $.variable('Notification').value,
	attachments : [attachment1,attachment2]
}

var response = $.http.post().path("/service/message/mail").body(jsonBody).execute();


// see more examples of this web service-based message service in the http://yourenaiodomain:8080/rest-ws interface. 


Codesystems

To assign a codesystem entry to a process variable, use the following calls.

// list all codesystems
 
var res = $.http.get().path('/service/system/cs/list')
    .query('elements', true)
    .execute();
 
var codesystems = res.data; // all catalogs
 
for (var i in codesystems) {
    $.log.info(codesystems[i].name);                // prints the technical name of the catalog into the server log
    if (codesystems[i].name == 'address') {     // You can load only one codesystem by its id 
        var cs_address = $.http.get().path('/service/system/cs/{id}')
            .param('id', codesystems[i].id)     
            .query('elements', true)
            .execute();
         
        $.log.info(JSON.stringify(cs_address.data));    // log a stringified json object to the log
    }
}


Loading and Creating DMS Objects

// Get a dms object by its id
var response1 = $.http.get().path('/service/dms/{id}')      // Create a GET request to the endpoint with given path
    .param('id', '7F822BD2065744CBA85736FD5A10179B')        // Define the path parameter
    .query('type', 'picture')                               // The query performs better if the type of the document is known.
    .execute();
 
var item1 = response1.data; // The dms item is stored in the data block
var data1 = item1.data;     // The data block inside the item is the index data
 
// Create a new data object and assign some values
var data2 = {
    name: 'sweet pony',
    format: '16:10'
};
 
var response2 = $.http.post().path('/service/dms/create/{childType}')       // Create a POST request to the endpoint with the given path
    .param('childType', 'Picture')
    .query('usercomment', 'run pony run...')        // as user comment
    .body(data2)                                    // put the index data to body
    .execute();
 
// if response2.status is '201' the object was created successfully
 
var id = response2.data;    // the id of the created object is returned

Switching to Server Context

enaio redline release 2018-03-28 (3.34.x) or later.

Activity events like WorkitemPersonalizedWorkitemCanceledWorkitemSaved are executed on the server side and run in the user context. To execute a function without user security limitations, you may need to switch to a server user context. You can call the 'sudo' function, as shown in the following example.

Beginning with enaio redline release 4.12.18, you have a second option for complex subroutine calls and the 'this' context. Now it is possible to put the name of the function as first parameter and the object on which the method will be called as the second parameter.

All other BPM events run in server context.

// Find out in which context the script runs
$.whoami();  // returns the user's login name or that of the server user

var getUser = function() {
  return $.whoami();
}

// execute a function in user context
getUser();			// returns 'johnson' for example
// execute a function in a server context
$.sudo(getUser);	// returns 'root' for example


// execute an http request in server user context:
$.sudo( function() {$.http.get().path('/service/organization/whoami').execute()});

// execute a complex method using 'this' in a separate global function
$.sudo('myFunctionName', myObjectFromGlobalScript);

Exception Handling

It can happen that things go wrong and exceptions occur. You should work with try, catch, finally, if you want to check whether a function has worked correctly. Even in the done() function many values are stored. If you called a third party system correctly and the done() function failed, you can react on such errors and rollback the data. The script writer is responsible to keep an eye on own data changes.

$.variable('name').value = 'schmidt'; 
var successful = true;

// exception handling of third party calls
try {
  callThirdParty(job);
} catch (err) {
  // do some error handling
  $.log.error(err.name + ': ' + err.message);		// print out the error name and the reason message
  $.log.error(JSON.stringify(err, Object.getOwnPropertyNames(err)));
  rollbackThirdParty(job);
  successful = false;
} finally {
  $.log.info("...");
}

if (successful) {
    try {
		$.done();   // save all
    } catch (err1) {
      rollbackThirdParty(job);
    } finally { /* do something */ }
} else {
  // nothing will be saved because $.done() is not called.
  throw new Error('...');
}

External Javascript Libraries

You can load an external Javascript library if it is stored in the server api-lib directory (<DMS:Service>/standalone/configuration/bpm-script-api/lib). Using an external library enables you to get a codesystem you prefer.

In case of an update, the lib folder will not be overwritten by a DMS service update.

load($.LIB_PATH + 'lodash.min.js');     // LIB_PATH is a constant of the library path, make sure the library is stored in this directory
                                        // for more information about the JavaScript library lodash, go to: https://lodash.com/docs 
var res = $.http.get().path('/service/system/cs/list')  // get all codesystems
    .query('elements', true)
    .execute();
 
var codesystems = res.data;                             // all catalogs
var x = _.filter(codesystems , function(o) { return o.name === 'address'});     // filter all codesystems whose name attribute is 'name'
var codesystem = x[0];                                  // select this one
 
x = _.filter(codesystem.entries, function(o) { return o.data === 'Dear Miss'}); // filter all entries by data
var entry = x[0];                                       // select this one
 
$.variable('address').value = entry.id; // assign the id of the entry to a codesystem process variable 
$.done();   // save all


Global Script

In yuuvis® RAD designer, you can write a global script for a process model. This global script is loaded to each of the model's event scripts. Constants or functions defined in the global script can be used in each of these scripts.

Example 1

// define a function
var getMyObject = function() {
    callHelper();
    return {
        a: '123',
        b: 120.5,
        c: {
            c1: 'x',
            c2: 'y'
        }
    };
};
 
// define a variable
var pi = 3.1415;
// define a function that is only used in the global script
function callHelper() {
    // ...

// load a library which will be available in all other scripts of the process
var libexists = true;
try {
   load($.LIB_PATH + 'moment-with-locales.js');
   } catch (e) {
      libexists = false;
}
if (libexists) {load($.LIB_PATH + 'moment-with-locales.js')};
$.log.debug("[Adhoc] libexists GLOBAL: "+libexists);
// define which functions or objects are accessible in the event script.

if (libexists) {
  return {
     moment : moment,       // function name of moment
     libexists : libexists  // react on existing moment library
     myFunc: getMyObject,
     myConst: pi
    };
}

return {
   libexists : libexists,
   myFunc: getMyObject,
   myConst: pi
};


The event script can use the provided functions.

$.variable('theValueOfPi').value = myConst;     // assign any of your own 'global' variables to process variables
var obj = myFunc();     // or just call your own 'global' functions

Example 2

Since user-defined history entries are a common use case in event scripts, it makes sense to use a global script.

var global = {}; 
global.create = function($) { 
	
	var writeHistoryEntry = function(message) {
	    var historyEntry = $.history.createEntry();
	    historyEntry.message = message;
	    $.history.entries.push(historyEntry);
	};

	return {
	    writeHistoryEntry: writeHistoryEntry
	};
};

The event script uses the provided functions.

writeHistoryEntry('This is my first message');			
writeHistoryEntry('Oh, it's so easy I do it again');
writeHistoryEntry('Oh my God. Should it actually be 3 messages?');

$.done(); // Use the done function if you want to save changed data.

Extended Log

Only supported in versions up to and including 3.21.x

To log information, first enable the logging for a script.

$.setDebugLog(true);

Activate an additional debug log to log internal API logs.

$.setDebugLog(true);
 
// sample output
>> output: DEBUG: variable.init:  datafield.name = field_datetime
>> output: DEBUG: variable.init:  datafield.type = DATETIME
>> output: DEBUG: variable.init:  datafield.value = null
>> output: DEBUG: variable.save:  type = DATETIME
>> output: DEBUG: variable.save:  value = Thu May 05 2022 12:00:00 GMT+0200 (CEST)