クラウド型 ワークフロー

入力データの変更履歴を自動取得する

工程間の入力された内容を差分チェックし、変更履歴として記録する自動工程(プロセスモデラーアドオン)の実現方法を解説します。

こんにちは、古久保です。

(ひつこいですが、)
Questetra では、「業務の自動化」、イロイロ、取り組んでおります。
プロセスモデラーアドオンという形で様々な自動化を可能にしています。

プロセスモデラー アドオン
業務プロセスを定義する「モデリング機能」は、(a) モデリングアイコンの追加、(b) 選択肢候補のマスター化、(c) PDF生成工程の有効化、の3つの観点で機能強化することが可能です。以下のアドオンをインポートすれば、より高度な業務プロセスを、より効率良く定義できるようになります。オリジナルのアドオンファイルを自作することも可能です。

http://www.questetra.com/ja/addon/#tax-term-browser-api-orchestration-ja

今回は、これまで、コピペで対応していたような操作を自動化させてみたいと思います。

◆シナリオ

ワークフローサンプルの月末請求フローを元に自動化例を作成します。

第557話:様々なAPIと通信する全自動請求フロー
月末のカード請求業務が、ヌケモレなく実施されるようになった!
それぞれのお客様への「請求金額」について、、、いつ誰が入力し、いつ誰が承認したのか、全てがリアルタイムに捕捉できるようになった。しかも、クレジット会社 API (Stripe API)にアクセスしてくれる「自動工程」のおかげで……

http://ja.workflow-sample.net/2017/10/automatic-billing-operation.html

<ワークフロー図(オリジナル)>

<入力フォーム:課金情報>

開始された月末請求フローにおいて課金情報を入力+保存をしてお客様からの変更情報を待ち、タイマ中間イベントにて自動的に流れるようにしています。
「1.請求先情報の編集」工程「1rr.請求先情報の編集」工程にてお客様から変更依頼があれば入力し、分岐「情報更新」の流れで自工程に戻るようになっています。

そこで、

* 元々の課金情報って何だったかしら?????

ということがありそうです。
お客様とのやりとりが1度で済めば良いですが、複数発生した場合、過去の決定事項を記録して後に見直せられるようにしたいものです。

さりとて、、、

* お客様とのやりとりのメールを見直せばええのちゃう?
* やりたいけど、なにやら手間が掛かりそうでやるの嫌ー。

とも思うでしょう。
しかも、少なくとも複数工程にて変更の可能性がありますのでより対応の手間が掛かりそうにも思えてしまいます。

そのような懸念を自動工程のアドオン(ワークフロー基盤内でのスクリプト処理)で解決したいと思います。

今回は、「変更履歴セットサービス」という名称にて自動処理サービスを作成します。
要件としては、

* どのデータ項目が変更されたかの履歴を参照することができる。
* 変更履歴の対象とする項目を複数設定できる。

で考えたいと思います。

◆実装

変更履歴セットサービス」アドオンの設定仕様としては、

* 履歴取得対象項目名
– データ項目名を記載(文字列型/数値型/日付型/日時型/選択肢型 限定)
– 複数記載可能(半角カンマ区切り)
* 履歴セット用項目
– 変更履歴内容をセットするデータ項目
– 文字列複数行データ項目を選択
* 直近データセット用項目
– 比較元内容をセットするデータ項目
– 文字列複数行データ項目を選択

※サンプルアプリに対して「履歴セット用項目」「直近データセット用項目」をあらかじめ追加しておく必要があります。

となります。
<変更履歴セットサービス設定画面:設定例>

※コードは、後述します。

この「変更履歴セットサービス」をワークフロー図に設定します。
「情報変更」の分岐が発生する箇所に設定

<ワークフロー図:変更履歴セットサービスを設定)>

これにより、情報変更アクションが発生し、フローが流れることで変更履歴が自動的にセットされるようになります。

<実行結果画面>

<「変更履歴セットサービス」アドオンのコード>

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

<label>変更履歴セットサービス</label>

<configs>
  <config name="conf_ItemNamesForNoteHistory" required="true" form-type="TEXTFIELD">
    <label>履歴取得対象項目名(型:文字列/数値/日付/日時/選択肢)※カンマ区切りで記載</label>
  </config>
  <config name="conf_NoteHistory" required="true" form-type="SELECT" select-data-type="STRING_TEXTAREA">
    <label>履歴セット用項目</label>
  </config>
  <config name="conf_RecentNote" required="true" form-type="SELECT" select-data-type="STRING_TEXTAREA">
    <label>直近データセット用項目</label>
  </config>
  <config name="conf_DebugPrint" required="false" form-type="SELECT" select-data-type="STRING_TEXTAREA">
    <label>デバッグ用データ表示(指定が無い場合、非表示)</label>
  </config>
</configs>

<script><![CDATA[
// 変更履歴セット用スクリプト(ver. 20171015)
// (c) 2017, Questetra, Inc. (the MIT License)

main();

function main(){
	//// == 工程コンフィグの参照 / Config Retrieving ==
	var itemNamesForNoteHistory = configs.get("conf_ItemNamesForNoteHistory");
	var noteHistoryNum = configs.get("conf_NoteHistory");
	var recentNoteNum = configs.get("conf_RecentNote");
	var debugPrintNum = configs.get("conf_DebugPrint");

	//// == ワークフローデータの参照,定義 / Data Retrieving, Data Define ==
	var itemNames = new String(itemNamesForNoteHistory).split(",");
	var recentNote = engine.findDataByNumber(recentNoteNum);
	var date = new Date();
	var separateChars = ":";
	var separateStr = "---- " + date.getFullYear() + "/" + (date.getMonth()+1) + "/" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + " ----\n";
	var diffNote = "";
	var diffResult = false;
	var strs;
	var debug = "";

	//// == 演算 / Calculating ==
	if (recentNote != null){ // 2回目以降の入力の場合
		recentNoteRows = new String(recentNote).split("\n");
		for (var i=0; i < recentNoteRows.length; i++){
    		var itemName = recentNoteRows[i].slice(0,recentNoteRows[i].indexOf(separateChars));
    		var itemValue = recentNoteRows[i].slice(recentNoteRows[i].indexOf(separateChars)+1);
    		debug += itemName + ":" + itemValue + "\n";
			for (var j=0; j < itemNames.length; j++){
    			if (itemName == itemNames[j]){
    				if (!itemValue.equals(converToString(itemNames[j]))){
	  					diffResult = true;
			  			diffNote += itemNames[j] + separateChars + converToString(itemNames[j]) + "\n";
		   			}
	     		}
			}
		}
	}
	else{  // 初回入力の場合
		diffResult = true;
		for (var i=0; i < itemNames.length; i++){
			diffNote += itemNames[i] + separateChars + converToString(itemNames[i]) + "\n";
		}
	}
	//// == ワークフローデータへの代入 / Data Updating ==
	if (diffResult){ // 変更が発生している場合
		var note = engine.findDataByNumber(noteHistoryNum);
		if (note == null){
    		note = "";
		}
		note += separateStr;
	   	note += diffNote;
	   	engine.setDataByNumber(noteHistoryNum, note);
	   	recentNote = "";
		for (var i=0; i < itemNames.length; i++){
			recentNote += itemNames[i] + separateChars + converToString(itemNames[i]) + "\n";
		}
	   engine.setDataByNumber(recentNoteNum,recentNote);
	}
	
	// for Debug
	if (debugPrintNum != ""){
    	engine.setDataByNumber(debugPrintNum,debug);
	}

}
//// ==データ項目名から入力内容を文字列にして返す==
//// パラメータ:データ項目名
//// 戻り値: 「データ項目名」の示す項目に入力された内容(文字列)
function converToString(name){
	var definitionView = engine.findDataDefinitionByName(name);
	var stringData = "";
	if (engine.findDataByName(name) == null){
		return stringData;
	}
	if ((definitionView.matchDataType("STRING"))||(definitionView.matchDataType("DECIMAL"))){
		stringData = engine.findDataByName(name);
	}
	if ((definitionView.matchDataType("DATE"))||(definitionView.matchDataType("DATETIME"))){
		var formatter = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm");
		stringData = formatter.format(engine.findDataByName(name));
	}
	if (definitionView.matchDataType("SELECT")){
		var selects = engine.findDataByName(name);
		for (var i=0; i < selects.size(); i++){
			stringData += selects.get(i).getDisplay() + ",";
		}
		stringData = stringData.replace(/\,$/,"");
	}
	return stringData;
}
]]></script>


<icon>
(■■■割愛■■■)
</icon>

</service-task-definition>

◆あとがき

Questetra の仕様として、複数の工程にて同じ入力フォームに対して入力を行う場合、データは上書きとなります。
多くの場合、過去の入力内容を知る必要性は、少ないですが、「シナリオ」のようにお客様の都合でデータを任意の回数変更する場合には、過去の入力内容は参考情報として必要かもしれません。
そのような場合に、有効なアドオンです。(設定も容易に行えます)

もちろん、スクリプトタスクでも実現可能でありますが、汎用的に(他のアプリでも)使用できそうですので共有利用をイメージしてパッケージ化しました。

業務プロセス定義で利用可能な自動工程を追加する
“文字数とハッシュ値を取得する” といった処理工程を自動化したい場合、標準の[サービス工程]や[イベント]だけでは表現できません([スクリプト工程]を利用することになります)。しかし、予め “文字数カウント-addon.xml” や “SHAハッシュ-addon.xml” といった[アドオンXML]をインポートしておけば、簡単に処理工程の自動化を実現することができます。(Service-Task Addon)

http://www.questetra.com/ja/tour/m4/m415/

現在、「文字列型/数値型/日付型/日時型/選択肢型」に限定していますが、ユーザ型、組織型は比較的容易に実装できると思います。
是非ともご利用を検討頂ければと思います。

不明点や「試してみたいのでアプリのアーカイブが欲しい」等がありましたら遠慮なくご連絡ください。

2017-10-31

Masato Furukubo の紹介

Questetra, Inc. Sales Department
Masato Furukubo の投稿をすべて表示

あわせて読みたい
50.Questetra Tips の前の記事 backlog とワークフローの連携をカンタンに実現する方法
Masato Furukubo の他の記事 非同期型システム連携を監視する仕組み

アーカイブ

 RSS