M230 AUTOMATED STEP
Last updated Oct 31, 2017

Auto Executing Complicated Data Processing (ECMAScript)

By placing a Script Step in the middle of the Workflow diagram, data editing by ECMA Script is available. You can automate processing of string editing, for example, calculating the working hours between "Attendance time" and "Quitting time" or, automatically adding the day of the week information to the 'Operation date'. (You can achieve a more complicated processing, than by "ServiceTask (data assignment)".)

M230-1-en


1. Data Assignment
Automatic assignment of date or numbers which are generated by the ECMAScript
2. Data Editing
Editing the entered values and strings, and then assigning them as new data.
  • The “ECMA Script”, is a scripting language that is standardized based on the intersection between JavaScript and JScript

a. Recommended JavaScript
All classes defined in “ECMA-262, Edition 3” (JavaScript 1.5)
b. Available JavaScript
Many classes of “ECMA-262, Edition 5” (JavaScript 1.7/1.8)
c. Available Java class
Java classes that are required to access business data, Others
  • Basic knowledge of JavaScript and Java will be needed

R2300 Functions available in Script Task

1. Register ECMA Code
Enter the processing code, such as Data reference, Data processing, Data assignment
  • Assignment or updating of Business data is performed collectively after the completion of script processing
  • Updating and Assignment will not be performed in the event of an error (Proceeds to the next Step)
  • Processing time of the Script is limited to a maximum of 30 seconds (Will vary slightly according to the load condition)
//// == Data Retrieving ==
var dataA = engine.findDataByNumber("0") + ""; // Retrieving data 0
var dataB = engine.findDataByNumber("Data B") + ""; // Retrieving data with the name of "Data B"
// convert java.lang.String → javascript string

//// == Calculating ==
var newData = dataA + dataB;

//// == Data Updating ==
engine.setDataByNumber("3", newData ); // Data Updating

R2301 Script Data Retrieving / Assignment

R2252 OAuth Token Getting Procedure

M230-2-en



a. Rhino Engine
[Script Step] is processed with “Rhino”, the JavaScript engine (Server-side)
b. Feature of Rhino
Process Model designers can set an automatic processing scrip not only by “ECMAScript” (JavaScript) but also by “Java methods”. (Scripting Java). For example, if you generate an object in a format such as new java.lang.String ("kyoto") , it is possible to use methods of Java String class, such as replaceFirst () .
c. Retrieving Data on Workflow
To retrieve Business data, such as “Billing Date” or “Estimated Price”, make use of a special method of data.get("♦Data Definition ID♦")engine.findDataByNumber("♦ITEM ID♦"). As it calls as a Java instance, an explicit type conversion like var text = data.get("♦Data Definition ID♦") + "";var text = engine.findDataByNumber("♦ITEM ID♦") + ""; is recommended when you handle as JavaScript string/object.

/// TYPEOF test - for Rhino ECMA engine

var workflowData = data.get("0") ;

var teststring = ""; 

  teststring += "-- primitive Number -- \n"; 
  teststring += typeof 99        + "\n"; // 'number'
  teststring += typeof 9.99      + "\n";
  teststring += typeof Infinity  + "\n";
  teststring += typeof NaN       + "\n";
  teststring += typeof Number(9) + "\n";

  teststring += "-- primitive String -- \n"; 
  teststring += typeof ""             + "\n"; // 'string'
  teststring += typeof "Questetra"    + "\n";
  teststring += typeof (typeof 99)    + "\n";
  teststring += typeof String("ECMA") + "\n";

  teststring += "-- Object -- \n"; 
  teststring += typeof new Number(9)                + "\n"; // 'object'
  teststring += typeof new String("ECMA")           + "\n";
  teststring += typeof new java.lang.String("ECMA") + "\n";
  teststring += typeof workflowData                 + "\n";
  teststring += typeof data.get("0")                + "\n";
  teststring += typeof new com.questetra.bpms.core.model.formdata.ListArray() + "\n";

  teststring += "-- XML -- \n"; 
  teststring += typeof <foo bar="BAR">FOO</foo>            + "\n"; // 'xml'
  teststring += typeof XML('<foo bar="BAR">FOO</foo>')     + "\n";
  teststring += typeof new XML('<foo bar="BAR">FOO</foo>') + "\n";

  teststring += "--- additional info --- \n"; 
  teststring += typeof true + "\n";          // 'boolean'
  teststring += typeof undefined + "\n";     // 'undefined'
  teststring += typeof [1, 2, 4] + "\n";     // 'object'
  teststring += typeof /s/ + "\n";           // 'object'
  teststring += typeof null + "\n";          // 'object' (not 'null')
  teststring += typeof function(){} + "\n";  // 'function'
//  teststring += typeof Symbol() + "\n";    // ERROR (not 'symbol')

retVal.put( "0", teststring );

testX <- String("BPMS")
testX is NOT instanceof String
testX is NOT instanceof java.lang.String

testY <- new String("ECMA")
testY is instanceof String
testY is NOT instanceof java.lang.String

testZ <- new java.lang.String("JAVA")
testZ is instanceof String
testZ is instanceof java.lang.String

test1 <- data.get( "8" )
test1 is instanceof String
test1 is instanceof java.lang.String

test1b <- data.get( "8" ) + ""
test1b is NOT instanceof String
test1b is NOT instanceof java.lang.String

test2 <- data.get( "9" ) // Select
test2 is NOT instanceof String
test2 is NOT instanceof java.lang.String
test2 is instanceof java.util.ArrayList

d. Update Data on Workflow
To update Data on Workflow with the value calculated at a Script Step, make use of a special method retVal.put("♦Data Definition ID♦","♦New Value♦")engine.setDataByNumber("♦ITEM ID♦","♦NEW VALUE♦"). (You must explicitly describe "java.math.BigDecimal" to return the result of the calculation in the script to the Workflow side, for there exists only "number type" in ECMA/JavaScript type for numerical values.)
e. Function and Sample Codes Useful for your Business

//////// == Calculating ==
var myrand = Math.floor( Math.random() * 5 ) ; // 0 or 1 or 2 or 3 or 4

//// == Updating ==
retVal.put("♦DataDefID♦", java.math.BigDecimal(myrand) );

//// == Retrieving ==
var timestart = data.get("♦DataDefID♦"); // Datetime type:Process Start time
var timesent = data.get("♦DataDefID♦"); // Datetime type:Reply e-mail transmission time

//// == Calculating ==
var conciergesec = timesent.getTime() - timestart.getTime();
var conciergehour = java.math.BigDecimal( Math.floor( conciergesec / (1000 * 60 * 60) )); // Math.floor Rounding

//// == Updating ==
retVal.put("♦DataDefID♦",conciergehour);

var daystart = timestart.getDay(); // Memo of day of the week of inquiry occurrence
if (daystart == 0) retVal.put("♦DataDefID♦","Sunday");
if (daystart == 1) retVal.put("♦DataDefID♦","Monday");
if (daystart == 2) retVal.put("♦DataDefID♦","Tuesday");
if (daystart == 3) retVal.put("♦DataDefID♦","Wednessday");
if (daystart == 4) retVal.put("♦DataDefID♦","Thursday");
if (daystart == 5) retVal.put("♦DataDefID♦","Friday");
if (daystart == 6) retVal.put("♦DataDefID♦","Saturday");

//// == Retrieving ==
var mynumber = data.get("♦DataDefID♦") + ""; 

//// == Calculating ==
if( mynumber.length == 13 ){
 var mysum = 0;
 for( i=1; i<13; i++){
 mysum += parseInt( mynumber.charAt(i) ) * (i % 2 + 1);
 }
 var checkdigitnum = 9 - mysum % 9;
 var typedcd = parseInt( mynumber.charAt(0) );

//// == Updating ==
 if( typedcd == checkdigitnum ){
 retVal.put("♦DataDefID♦", "OK" ); 
 } else {
 retVal.put("♦DataDefID♦", "ERROR" ); 
 }
}

//// == Retrieving ==
var weatherjson = JSON.parse(data.get("♦DataDefID♦")); // In assumption of already obtained in an Intermediate Event, etc.

//// == Calculating ==
var mydesc = weatherjson.list[0].weather[0].description;
var mytemp = java.math.BigDecimal(weatherjson.list[0].temp.max - 273.15); 

//// == Updating ==
retVal.put("♦DataDefID♦", mydesc );
retVal.put("♦DataDefID♦", mytemp );

//// == Retrieving ==
var fromaddr = data.get("♦DataDefID♦") + "";
var inq = data.get("♦DataDefID♦") + "";

//// == Calculating ==
var inquirywithmark = inq.replace(/(^.*$)/gm, "> "+"$1"); // Greater-than sign as quotation

//// == Updating ==
retVal.put("♦DataDefID♦", fromaddr + '\n' + inquirywithmark ); 

//////// == Retrieving ==
var csv_text = data.get("♦DataDefID♦"); // In assumption of CSV data (four columns) of String type multiple lines
// ex)
// Nakagyo-ku, Kyoto-shi, Kyoto-pref, Japan
// Malibu, Los Angeles County, California, USA

//// == Calculating ==
var csvObj = new String( csv_text ); // String Object (JavaScript)
var tmpTable = new com.questetra.bpms.core.model.formdata.ListArray(); // Table type data
var lineArray = csvObj.split("\n"); // Split per each line, storing in array String[] 
for (var i=0; i < lineArray.length; i++){
 var tmpRow = new com.questetra.bpms.core.model.formdata.ListArray.ListRow(); // Added row (horizontal row)
var cellstrArray = lineArray[i].split(","); // Split at each comma, and Store to array
tmpRow.addCol( cellstrArray[0] );
 tmpRow.addCol( cellstrArray[1] );
 tmpRow.addCol( cellstrArray[2] );
 tmpRow.addCol( cellstrArray[3] );
 tmpTable.addRow( tmpRow ); // Add Row 
}

//// == Updating ==
retVal.put("♦DataDefID♦", tmpTable );

//// ==  Retrieving ==
// mytable: com.questetra.bpms.core.model.formdata.ListArray
var mytable = data.get("♦DataDefID♦"); // Retrieving Table type Data

//// == Calculating ==
var i=0;
var n = mytable.size();
var texttsv = "";
for (i=0; i < n; i++){
 texttsv += mytable.get(i, 0) + "\t";
 texttsv += mytable.get(i, 1) + "\t";
 texttsv += mytable.get(i, 3) + "\t";
 texttsv += mytable.get(i, 4) + "\n";
}

//// == Updating ==
retVal.put("♦DataDefID♦", texttsv ); 

//// == Retrieving ==
var quserEmail = data.get("♦DataDefID♦") + ""; // In assumption that "example@example.net" is stored to the Strings data

//// == Calculating ==
// com.questetra.bpms.core.event.scripttask.QuserDaoWrapper
var quser = quserDao.findByEmail(quserEmail);

//// == Updating ==
retVal.put("♦DataDefID♦", quser);

//// == Retrieving ==
optionsList = itemDao.findAll("value-display-list.xml", true); // M319 Options-XML

//// == Calculating ==
optionsNum = optionsList.size();
var value_id_list = "";
var display_label_list = "";
for (i=0; i < optionsNum; i++){
 value_id_list += optionsList.get(i).getValue() + "\n";
 display_label_list += optionsList.get(i).getDisplay() + "\n";
}

//// == Updating ==
retVal.put("♦DataDefID♦", value_id_list);
retVal.put("♦DataDefID♦", display_label_list);

//// == Retrieving ==
optionsList = itemDao.findAll("value-display-list.xml", true); // M319 Options-XML

//// == Calculating ==
var tmpTable = new com.questetra.bpms.core.model.formdata.ListArray(); // Table type data
optionsNum = optionsList.size();
for (i=0; i < optionsNum; i++){
 var tmpRow = new com.questetra.bpms.core.model.formdata.ListArray.ListRow(); // Added row (horizontal row)
tmpRow.addCol( optionsList.get(i).getValue() );
 tmpRow.addCol( optionsList.get(i).getDisplay() );
 tmpTable.addRow( tmpRow ); // Add row
}

//// == Updating ==
retVal.put("♦DataDefID♦", tmpTable );