5)交通費申請照会画面:[承認]ボタン押下処理の実装
tutorial.action.paperwork.TransportationInquiryAction#doApproveメソッド内を、以下のようにコーディングしてください。
// ----------------------------------------------------------------------
// TODO ActivitiのAPIを使って承認処理を実装してください。
// ----------------------------------------------------------------------
// [STEP1] この申請に関して、実行可能かつアクティブなタスクを取得します。
Task task = taskService
.createTaskQuery()
.taskAssignee(userLoginDto.userId)
.processInstanceBusinessKey(
transportationInquiryForm.transportationId)
.active()
.singleResult();
if (task == null) {
saveError("errors.haita");
return "transportationInquiry.jsp";
}
// [STEP2] フロー分岐の情報(flowCtrl=APPROVE)を設定し、タスクを完了します。
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("flowCtrl", "APPROVE");
taskService.complete(task.getId(), variableMap);
// [STEP3] このプロセスの終了状態に応じて、承認状況を設定します。
HistoricProcessInstance historicProcessInstance = historyService
.createHistoricProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.finished()
.singleResult();
if (historicProcessInstance == null) {
// 完了していない→「01:申請中」のまま
transportation.approvalState = "01";
} else {
// 完了している→「02:承認済み」とする
transportation.approvalState = "02";
}
// ----------------------------------------------------------------------
// ここまで
// ----------------------------------------------------------------------
コードの解説
[STEP1]
taskService(ActivitiのAPI)を使用して、ログインしているユーザーが実行可能かつアクティブなタスクを取得しています。
TaskQueryというタスクに関する情報を、さまざまな条件で取得することができるAPIを使用しています。
「流れるようなインターフェース」と呼ばれる"文章を記述していくようにメソッドを呼び出していく手法"でコーディングします。
- taskAssignee(userLoginDto.userId)=「ログインユーザーが実行可能なタスク」という条件
- processInstanceBusinessKey(transportationInquiryForm.transportationId)=「この申請データと紐づくタスク」という条件
- active()=「現在アクティブなタスク」という条件
- singleResult()=「条件に一致するタスクを1件取得する」というメソッドの実行
「if (task == null) { ・・・」の部分は、他のユーザーによって承認/却下が行われた場合にアクティブなタスクを取得できない可能性があることを考慮しています。
[STEP2]
「承認」「却下」によってシーケンスフローが分岐しますので、どちらのシーケンスフローに流れるべきかの情報をflowCtrlという変数名で設定しています。
プロセス定義ファイル上のシーケンスフローの条件プロパティに「${flowCtrl='APPROVE'}」と「${flowCtrl='REJECT'}」を設定しましたが、この条件をMapで設定しています。
taskService#completeは、タスクを完了させるメソッドです。
第1引数にタスクIDを、第2引数に上で設定したMapを渡しています。
[STEP3]
交通費申請テーブルにある「承認状況」のカラムを適切に更新するために、historyService(ActivitiのAPI)を使用して、この交通費申請プロセスの完了状態をチェックしています。
庶務確認タスクで承認されても、マネージャー承認待ちのときは、「申請中」という承認状況のままにしたいためです。
ここでは、HistoricProcessInstanceQueryのAPIを使って、Activiti側で管理されているプロセスの情報を取得し、完了状態をチェックしています。
- processInstanceId(task.getProcessInstanceId())=「今承認したタスクのプロセスID」を指定
- finished()=「完了したプロセス」という条件
- singleResult()=「条件に一致するタスクを1件取得する」というメソッドの実行
6)交通費申請照会画面:[却下]ボタン押下処理の実装
tutorial.action.paperwork.TransportationInquiryAction#doRejectメソッド内を以下のようにコーディングしてください。
// ----------------------------------------------------------------------
// TODO ActivitiのAPIを使って却下処理を実装してください。
// ----------------------------------------------------------------------
// [STEP1] この申請に関して、実行可能かつアクティブなタスクを取得します。
Task task = taskService
.createTaskQuery()
.taskAssignee(userLoginDto.userId)
.processInstanceBusinessKey(
transportationInquiryForm.transportationId)
.active()
.singleResult();
if (task == null) {
saveError("errors.haita");
return "transportationInquiry.jsp";
}
// [STEP2] フロー分岐の情報(flowCtrl=REJECT)を設定し、タスクを完了します。
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("flowCtrl", "REJECT");
taskService.complete(task.getId(), variableMap);
// ----------------------------------------------------------------------
// ここまで
// ----------------------------------------------------------------------
コードの解説
[STEP1]
taskService(ActivitiのAPI)を使用して、ログインしているユーザーが実行可能かつアクティブなタスクを取得しています。
- taskAssignee(userLoginDto.userId)=「ログインユーザーが実行可能なタスク」という条件
- processInstanceBusinessKey(transportationInquiryForm.transportationId)=「この申請データと紐づくタスク」という条件
- active()=「現在アクティブなタスク」という条件
- singleResult()=「条件に一致するタスクを1件取得する」というメソッドの実行
[STEP2]
ここでは、「却下」のシーケンスフローに流れたいため、flowCtrl='REJECT'をMapに設定しています。
7)交通費申請照会画面:[承認][却下]ボタン非表示処理の実装
交通費申請データの承認/却下を実行できるユーザーは、申請データごと異なります。
承認/却下を実行できないユーザーが本画面を表示したときは、[承認][却下]ボタンを非表示にする処理を実装してみましょう。
tutorial.action.paperwork.TransportationInquiryAction#indexメソッド内を以下のようにコーディングしてください。
// ----------------------------------------------------------------------
// TODO ActivitiのAPIを使って[承認][却下]ボタンを
// 非表示にする処理を実装してください。
// ----------------------------------------------------------------------
// この申請に関して、実行可能かつアクティブなタスクを取得します。
Task task = taskService
.createTaskQuery()
.taskAssignee(userLoginDto.userId)
.processInstanceBusinessKey(
transportationInquiryForm.transportationId)
.active()
.singleResult();
if (task == null) {
// アクティブなタスクがない→[承認][却下]ボタンは非表示とします。
transportationInquiryForm.approvable = false;
} else {
// アクティブなタスクがある→[承認][却下]ボタンを表示します。
transportationInquiryForm.approvable = true;
}
// ----------------------------------------------------------------------
// ここまで
// ----------------------------------------------------------------------
コードの解説
画面表示が行われる前に、ログインユーザーが[承認][却下]を実行可能かをチェックし、ボタンの表示/非表示を制御しています。
transportationInquiryForm.approvableのプロパティは、JSP側で参照しています。
<c:if test="${approvable}" >
<input type="submit" class="input-button" name="doApprove" value="承認" />
<input type="submit" class="input-button" name="doReject" value="却下" />
</c:if>
8)交通費申請アプリ(完成版)の動作確認
以下のテストケースをもとに動作確認をしましょう。
-
kagawaで申請→messiで承認→xaviで承認
- 承認状況は、「申請中」→「承認済み」と遷移することを確認
- [承認][却下]ボタンの表示制御が正しいことを確認
-
kagawaで申請→messiで承認→xaviで却下
- 承認状況は、「申請中」→「却下」と遷移することを確認
- [承認][却下]ボタンの表示制御が正しいことを確認
-
kagawaで申請→messiで却下
- 承認状況は、「申請中」→「却下」と遷移することを確認
- [承認][却下]ボタンの表示制御が正しいことを確認
