How to Let a Robot Nominates Translators Randomly (3)

Packaging execution of Questetra monitoring API into Add-on XML. I will introduce a method to designate a person in charge with low translation workload as a priority.

Hi, there!

“Automation of Business Process” is a hot topic. (Again, the same words I began with.)
As declared, I am writing this in series. (This may be the final?)

This time, I would like to introduce you a smarter robot than before.
However, it is not randomly.。
It doesn’t match with the title anymore. (Pardon me.)

When, where and How do You Ask Robot to Help You?

The part the robot to help is the same as before. (Step of “2. Designate”)

<Translation flow: Using a robot>

* Original article: “Episode 538: Analyzing Time Required for Translating 100 Characters in Japanese”

In the previous article, “How to Let a Robot Nominates Translators Randomly (2)”, it was defined as follows.

<Designation rule>
*”Designate a translator randomly out from a group of who are capable of translating specified languages.
<Input to robot>
*Information about language capability of target users

However, with those definitions, there might be complaints such as

“Even though it looks like designated randomly, I’m holding plenty of jobs already. I can’t handle anymore!”

Since the translator was randomly designated without compassion, the workload situation of each person to do translation has been ignored.
Even though the number of work allocation could be averaged, there was a possibility that the flow of work would be stagnant.

Therefore, I am going to change the “Designation rule” and “input to the robot”.
The number of work allocation will become more average than the random designation, by defining

<Designation rule>
*”Designate a translator out from a group of who are capable of translating specified languages
* Designate with priority to those who are holding less number of Step of “3. Translate” to handle in the current month
<Input to the robot>
*Information about language capability of target users
*The number of “3. Translate” Step that target user is handling in the current month

Let a robot doing works in above rule.

Implement Robot with Add-on XML (Auto-processing package)

Specification of robot

The behaviors of the robot are;

1. Find the number of people and the individuals who are capable of translating specified language pattern
2. Retrieve the number of “3. Translate” Step in the current month which is being handled by the target users of 1
3. Designate a person who has less number of Step to handle out from target users

Regarding

2. Retrieve the number of “3. Translate” Step in the current month which is being handled by the target users of 1

it can be realized by using “Monitoring API in Developer APIs” of Questetra.

Developer APIs: Workflow APIs
By leveraging the workflow APIs, easy developments are available, such as “Android application for processing assigned Tasks (My Tasks)” or “Key collaboration tools to aggregate operational data (process data) of the past”. Business data to be transmitted to the application from the API is limited to data on which the user of the application is authorized.

https://www.questetra.com/tour/tour/reference/apis-workflow/

It will be better to use “Querying for Task records operated by the User: /API/OR/Workitem/list” among the Monitoring APIs.
Set search conditions (Criteria) for executing API referring to “XML: Criteria for Workitem Search”.
For the XML of search condition (Criteria) that satisfies

2. Retrieve the number of “3. Translate” Step in the current month which is being handled by the target users of 1

that shall be

<workitem-criteria>
  <process-model-info-id>
    ●●App ID of search target●●
  </process-model-info-id>
  <states>
    <state>STARTED</state>
  </states>
  <node-number>●●Node ID of "3. Translate"●●</node-number>
  <workitem-allocated-quser-id>●●User ID of search target●●</workitem-allocated-quser-id>
</workitem-criteria>

Implementation of robot

I am going to implement it with Add-on XML this time as well.

<Confiurations in Package>
* User type Data Item to store the designated user
* Master name of Options XML which stores attribute information of target users
* Matching-word of attribute information (Select type Data Item)
* App ID of the target for count search
* Node ID of the target Step (“3. Translate”) for count search
* Email address of the API executing user
* Password of the API executing user
* Application root URL

Configure Add-on as above figure so that implement the behaviors mentioned in “Specification of robot”.

<Codes in Add-on XML for “Designation (by Workload + Master search)”>

<?xml version="1.0" encoding="UTF-8"?><service-task-definition>

<label>Designation (by Workload + Master search)</label>

<configs>
  <config name="conf_TargetQUser" required="true" form-type="SELECT" select-data-type="QUSER">
    <label>Designated User</label>
  </config>
   <config name="conf_MatchingWord_QUserMasterName" required="true" form-type="TEXTFIELD">
    <label>Master name of matching-word compatible user list</label>
  </config>
  <config name="conf_MatchingWord" required="false" form-type="SELECT" select-data-type="SELECT_SINGLE">
    <label>Matching-word</label>
  </config>
   <config name="conf_Research_Count_MId" required="true" form-type="TEXTFIELD">
    <label>App ID of the target for count search</label>
  </config>
   <config name="conf_Research_Count_NodeId" required="true" form-type="TEXTFIELD">
    <label>Node ID of the target Step ("3. Translate") for count search</label>
  </config>
  <config name="conf_API_User_MailAddress" required="true" form-type="TEXTFIELD">
    <label>Email address of the API executing user</label>
  </config>
  <config name="conf_API_User_Password" required="true" form-type="TEXTFIELD">
    <label>Password of the API executing user</label>
  </config>
  <config name="conf_ApplicationRootURL" required="true" form-type="TEXTFIELD">
    <label>Application root URL</label>
  </config>
  <config name="conf_DebugPrint" required="false" form-type="SELECT" select-data-type="STRING_TEXTAREA">
    <label>Data indication for debugging (No-display if not specified)</label>
  </config>
</configs>


<script><![CDATA[
// Script for Designation (by Workload + Master search)(ver. 20170911)
// (c) 2017, Questetra, Inc. (the MIT License)

//// == Config Retrieving ==
var targetQUserNum = configs.get("conf_TargetQUser");
var matchingWord_QUserMasterName = configs.get("conf_MatchingWord_QUserMasterName");
var targetMatchingWordNum = configs.get("conf_MatchingWord");
var processModelInfoId = configs.get("conf_Research_Count_MId");
var nodeId = configs.get("conf_Research_Count_NodeId");
var userName = configs.get("conf_API_User_MailAddress");
var apiPass = configs.get("conf_API_User_Password");
var applicationRootURL = configs.get("conf_ApplicationRootURL");
var debugPrintNum = configs.get("conf_DebugPrint");

//// == Data Retrieving, Data Define ==
// Retrive list of Options XML for search
var matchingWord_QUserList = itemDao.findAll(matchingWord_QUserMasterName,true);
var matchingWord = null;
if (targetMatchingWordNum != ""){
	matchingWord = engine.findDataByNumber(targetMatchingWordNum).get(0).getValue();
}
// matchingList [n][0] Element number in Options XML
// matchingList [n][1] Number of Issues handled in current month
var matchingList = new Array();
var targetQuserList;
var targetNum;
var debug = "";

//// == Calculating ==
var j = 0;
for (var i=0; i < matchingWord_QUserList.size(); i++){
	if (matchingWord != null){
		// if "matching-word" is not specified, set all the contents of Options XML
		if (matchingWord_QUserList.get(i).getDisplay().indexOf(matchingWord) != -1){
			matchingList[j] = new Array();
			matchingList[j][0] = i;
			matchingList[j][1] = getRequestCount((quserDao.findByEmail(matchingWord_QUserList.get(i).getValue())).getId());
			j++;
		}
	// if "matching-word" is not specified, set all the contents of Options XML
	}else{
		matchingList[j] = new Array();
		matchingList[j][0] = i;
		matchingList[j][1] = getRequestCount((quserDao.findByEmail(matchingWord_QUserList.get(i).getValue())).getId());
		j++;
	}
}
// Set the element number with the least allocation processing from the target list
var tmpId = 0;
for (var i = 0; i < matchingList.length; i++){
	debug += "matchingList[" + i + "]:" + matchingList[i][0] + ":" + matchingList[i][1] + "\n";
	if (matchingList[tmpId][1] > matchingList[i][1]){
		tmpId = i;
	}
}
targetNum = matchingList[tmpId][0];
debug += "matchingList.length:" + matchingList.length + "\n";
debug += "targetNum:" + targetNum + "\n";

// for Debug
if (debugPrintNum != ""){
    engine.setDataByNumber(debugPrintNum,debug);
}

//// == Data Updating ==
engine.setDataByNumber(targetQUserNum,quserDao.findByEmail(matchingWord_QUserList.get(targetNum).getValue()));

//// ==Acquire the start count of the designated App from the API of  App processing history of this month==
//// Paarameter:quserId: User ID of search target
//// Return value: value of count element in API response
////        If an error occurs in the API, it returns zero.
function getRequestCount(quserId){
    try{
        var formatter = new java.text.SimpleDateFormat("yyyy-MM");
        var thisMonth = formatter.format(processInstance.getProcessInstanceStartDatetime());
        var uri = applicationRootURL + "/API/OR/Workitem/list";
        var criteria = "<workitem-criteria><process-model-info-id>";
        criteria += processModelInfoId;
        criteria += "</process-model-info-id>";
        criteria += "<states><state>STARTED</state></states>";
        criteria += "<node-number>" + nodeId + "</node-number>";
        criteria += "<workitem-allocated-quser-id>" + quserId + "</workitem-allocated-quser-id>";
        criteria += "</workitem-criteria>";
        var response = httpClient.begin()
          .queryParam( "limit", "1000" )
          .queryParam( "criteria", criteria )
          .basic(userName,apiPass)
          .get( uri );
        responseJson = response.getResponseAsString();
        if( response.getStatusCode() == 200 ){
            var jsonObj = JSON.parse( responseJson );
            debug += "quserId:" + quserId + ":recordCount:" + jsonObj.count + "\n";
            return jsonObj.count;
        }else{
            return 0;
        }
    }catch(e){
        return 0;
    }
}
]]></script>


<icon>
(omitted)
</icon>

</service-task-definition>

Closing

Don’t you think it has become a little bit smarter robot than before?

* Packaging the execution of (Questetra) API, and use it for automatic processing.

That is the point of this article.
This time, it is an API that can be used in Questetra, but it is also possible to use API of various services. (Although it must be said “as long as API specifications fit”, I suppose that the specification is general.)
At our website “Process Modeler Add-on”, we have prepared packages for cooperating with various systems.
I hope you to give some try.

Process Modeler Add-ons
The “Modeling function” that defines a Business Process can be enhanced by three aspects: a) Addition of a modeling icon, b) Mastering choice options, and c) PDF Auto-generation. By importing the following Add-ons, you can more efficiently define further advanced Business Processes. You can also create your own Add-on file by yourself.

https://www.questetra.com/addon/#tax-term-browser-api-orchestration-en

If you have any questions, please feel free to contact us.

2017-10-11

About Masato Furukubo

Questetra, Inc. Sales Department
View all posts by Masato Furukubo

Recommendations
Prev article - 50. Questetra Tips Several Ways to Manage Master Data with Questetra
Next article - 50. Questetra Tips Automatically Acquire Revision History of Input Data
Another article - Masato Furukubo How to Let a Robot Nominates Translators Randomly (2)

Archive

 RSS