2022年8月26日金曜日

APEX 22.1の承認コンポーネント(4) - 多段階承認の実装

 OracleのAnanya Chatterjeeさんによる以下の記事が、公式ブログに寄稿されています。

Implementing Multi-Approvals in Oracle APEX 22.1

APEXの承認コンポーネントのタスクは、承認または却下することによって完了します。一旦承認/却下するとタスクは完了し、それ以降の操作はできません。そのため、職制を通した承認といったフローを、ひとつのタスクで扱うことはできません。

Ananya Chatterjeeさんは直属の上司がタスクを承認するときに、その上の階層での承認が必要であれば、承認時に実行されるコードの中で新たにタスクを生成することにより多段階での承認を実装しています。

以前の記事で作成した休暇申請を行なうAPEXアプリケーションに、多段階承認を実装してみます。

APEX 22.1の承認コンポーネント(1) - 概要
http://apexugj.blogspot.com/2022/07/new221-approvals-component-intro.html
APEX 22.1の承認コンポーネント(2) - 基本的なアプリケーションの作成
http://apexugj.blogspot.com/2022/07/new221-approvals-component-basicapp.html
APEX 22.1の承認コンポーネント(3) - ユーザー・データの利用
http://apexugj.blogspot.com/2022/07/new221-approvals-component-userdata.html

最初に承認の階層を定義します。アプリケーションのユーザーは、申請太郎申請花子承認太郎承認花子管理者です。

申請太郎の直属上司を承認太郎承認太郎の上司を管理者とします。また、申請花子の直属上司は承認花子、その上司を管理者とします。

UNI_USERSを作成し、上記の階層をデータとして入力します。SQLワークショップSQLスクリプトより実行します。



せっかく表UNI_USERSを作成したので、サインインのユーザーがハードコードされている認証スキームを更新します。

共有コンポーネント認証スキーム固定ユーザー認証を開き、ソースを以下に置き換えます。登録されているユーザーに変更はないので、このソースの置き換えはアプリケーションに影響を与えません。



共有コンポーネントタスク定義休暇申請を開きます。

参加者潜在的所有者の定義を変更します。現在の定義は以下になっています。申請太郎の上司は承認太郎、申請花子の上司は承認花子です。それ以外、つまり承認太郎と承認花子の上司は管理者です。
begin
  if :APEX$TASK_INITIATOR = '申請太郎' then
      return '承認太郎';
  elsif :APEX$TASK_INITIATOR = '申請花子' then
      return '承認花子';
  else
      return '管理者';
  end if;
end;
上記を表UNI_USERSを参照した定義に置き換えます。

タスクの開始者(APEX$TASK_INITIATOR)ではなく、サインインしているユーザー(APP_USER)の上司を潜在的所有者としています。


アクションを更新します。タスクが完了したときのイベント処理で、結果が承認済みのときに実行されるコードを変更します。

イベント時完了結果承認済アクションを開きます。


アクションコードを、以下のコードに置き換えます。休暇の申請期間が一週間を超える場合、休暇申請ステータス(表UNI_REQUESTSの列STATUS)をTRANSFEREDにしてタスクを完了し、承認者の上司による承認を求めるタスクを作成しています。




以上で多段階での承認が実装できました。

動作を確認してみます。

申請太郎でサインインし、2022/12/01から2022/12/31までの休暇を申請します。


自分で開始を開くと、承認太郎にタスクがアサインされていることが確認できます。


承認太郎でサインインし私のタスクを開き、アサインされたタスクを承認します。


休暇申請一覧を開くと、表UNI_REQUESTSの列STATUSTRANSFEREDになっていることが確認できます。


管理者でサインインし私のタスクを開き、アサインされたタスクを承認します。


休暇申請一覧を開くと、表UNI_REQUESTSの列STATUSAPPROVEDになっていることが確認できます。


以上で多段階での承認の実装が確認できました。


タスクの詳細の更新



本記事での実装では、タスクパラメータを使っていません。そのため、タスクの詳細のページの詳細に何も表示されません。


ページ・デザイナにてタスクの詳細のページを開き、リージョン詳細ソースを置き換えます。

ソースSQL問合せを以下に置き換えます。
select reason, start_date, end_date
from uni_requests
where id = (
    select detail_pk from apex_tasks 
    where task_def_static_id = 'LEAVE_REQUEST'
    and application_id = :APP_ID
    and task_id = :P5_TASK_ID
);  

属性外観テンプレートValue Attribute Pairs - RowからValue Attribute Pairs - Columnに変更します。


以上の変更により、タスクの詳細に追加情報(Reason、Start Date、End Date)が表示されます。




自分で開始の一覧の更新



直属上司の上司の承認をとった場合、自分で開始に該当する休暇申請のタスクが2行表示されます。


自分で開始のページを開き、リージョン自分で開始 - レポートソースSQL問合せを以下のSELECT文に置き換えます。
select *
from table ( apex_approval.get_tasks ( p_context => 'INITIATED_BY_ME' ) )
where task_id in (
    select max(task_id)
    from apex_tasks
    where application_id = :APP_ID
    and detail_pk in (
        select id from uni_requests where requester = :APP_USER
    )
)
同じ休暇申請の場合、最後に作成されたタスクを一覧の対象にしています。


レポートを実行すると、表示が1行になっていることが確認できます。


Oracle APEX 22.1の承認コンポーネントを使った、多段階承認の実装の紹介は以上になります。

複雑なワークフローの実装であれば、Flows for APEXの利用をお勧めします。しかし、Flows for APEXではBPMNによるワークフローの定義が必須です。BPMNによるワークフローの定義まではしたくないといった場合は、このように承認コンポーネントの複数のタスクを連結することでワークフローを実装できます。

今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/simple-approvals-component-multilevel.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。