APEXの開発者であるAnanya Chatterjeeさんによる以下の記事です。
Custom Plugins for non-sequential steps in APEX Workflow
https://blogs.oracle.com/apex/post/custom-plugins-for-non-sequential-steps-in-apex-workflow新入社員のオンボーディング・プロセスを、APEXワークフローとして実装しています。
英語の元記事では、以下のワークフローを作成しています。
本記事では上記のワークフローから、タイムアウトの処理とメール通知を省略したワークフローを作成して、並列処理の実装を学習します。作成するワークフローは以下です。
赤枠で囲った部分が、APEXワークフローのアクティビティRequest Accessが行っている処理になります。この処理は、Workflow Activityプラグインとして実装されています。
承認タスクEmployee Badge Access(社員バッチの承認)とEmp Laptop Approval(ラップトップの購買承認)のふたつの承認タスクを作成し、両方のタスクが処理されるまで待機します。両方の承認タスクともに承認されたときにアクティビティRequest Accessの結果はtrueとなり、どちらかが却下された時は結果はfalseになります。その後、次のアクティビティ(切替えのAccess Approved)へ進みます。
両方が承認されたときに、アクティビティComplete Trainingに移り、新入社員がトレーニングの終了を確認するとワークフローが完了します。
APEXワークフローの並行処理の部分はアクティビティRequest Accessのコードに実装されています。APEXのダイアグラムには、承認タスクEmployee Badge AccessとEmp Laptop Approvalは現れません。
つまり、APEX 23.2のAPEXワークフローではBPMNの並列ゲートウェイにあたる記述ができないため、Workflow Activityプラグインを作成することで並列処理を実装しています。
以下より、元記事の手順に従って新入社員のオンボーディングを処理するAPEXアプリケーションを作成してみます。
クイックSQLの以下のモデルより表EMP_STATSとEMP_ONBOARDING_STATUSを作成します。表EMP_ONBOARDING_STATUSに列TRAINING_STATUSとONBOARDING_STATUSが含まれていますが、今回の記事ではほぼ使いません(列ONBOARDING_STATUSにREQUESTEDを設定するだけ)。
英語の元記事では、これらの列を更新するアクティビティUpdate Onboarding SuccessとUpdate Onboarding Failureの追加は読者への課題となっています。
レビューおよび実行をクリックし、表の作成までを実施します。
スクリプトの実行にはSQLスクリプトを使います。
アプリケーションの作成をクリックします。
参加者に、潜在的所有者としてRALMUELLを追加します。社員バッチによるアクセスを承認できるのは、ユーザーRALMUELLだけです。
共有コンポーネントのタスク定義を開きます。
承認タスクとしてEmployee Badge AccessとEmp Laptop Approval、アクション・タスクとしてComplete Trainingを作成します。
タスク定義Employee Badge Accessを作成します。タイプは承認タスクです。件名に以下を記述します。静的IDはEMPLOYEE_BADGE_ACCESSです。
Approve Badge access for &EMPNO. - &ENAME.
作成をクリックします。
タスク詳細ページは、ページ番号2を指定して作成します。
アクション・ソースとして表を選択し、表名にEMP_STATS(表)、アクション表の主キー列としてEMPNO(Number)を指定します。
パラメータとして、JOINING_DATEとMGR_NAMEを追加します。両方ともデータ型は文字列です。
アクションとしてOn Badge Access Completedを追加します。
コードに以下を記述します。
eba_demo_wf_parallel_pkg.complete_badge_access(
p_task_pk => :APEX$TASK_PK
,p_task_outcome => :APEX$TASK_OUTCOME
);
プロシージャCOMPLETE_BADGE_ACCESSは、表EMP_ONBOARDING_STATUSの列BADGE_ACCESSを承認タスクの結果(APPROVEDまたはREJECTED)で更新します。その後、列LAPTOP_STATUSを確認し、値がPENDINGでない(APPROVEDまたはREJECTED)であれば、APEX_WORKFLOW.CONTINUE_ACTIVITYを呼び出してAPEXワークフローのアクティビティRequest Accessの次の処理(切替えAccess Approved)に遷移させます。
タスク定義Emp Laptop Approvalを作成します。タイプは承認タスクです。件名に以下を記述します。静的IDはEMP_LAPTOP_APPROVALです。
Laptop Request for &ENAME.
作成をクリックします。
タスク詳細ページは、ページ番号3を指定して作成します。
アクション・ソースとして表を選択し、表名にEMP_STATS(表)、アクション表の主キー列としてEMPNO(Number)を指定します。
参加者に、潜在的所有者としてJANEを追加します。ラップトップの購入を承認できるのは、ユーザーJANEだけです。
アクションとしてOn Laptop Access Completedを追加します。
アクションのタイプはコードを実行、イベント時に完了を選択します。結果の承認済、却下済は選択せず、結果にかかわらず承認タスクが完了したときに、このアクションを実行します。
コードに以下を記述します。
eba_demo_wf_parallel_pkg.complete_laptop_access(
p_task_pk => :APEX$TASK_PK
,p_task_outcome => :APEX$TASK_OUTCOME
);
プロシージャCOMPLETE_LAPTOP_ACCESSは、表EMP_ONBOARDING_STATUSの列LAPTOP_ACCESSを承認タスクの結果(APPROVEDまたはREJECTED)で更新します。その後、列BADGE_STATUSを確認し、値がPENDINGでない(APPROVEDまたはREJECTED)であれば、APEX_WORKFLOW.CONTINUE_ACTIVITYを呼び出してAPEXワークフローのアクティビティRequest Accessの次の処理(切替えAccess Approved)に遷移させます。
プロシージャCOMPLETE_BADGE_ACCESSと対になる処理です。
タスク詳細ページは、ページ番号8を指定して作成します。
参加者に、潜在的所有者として&ENAME.を追加します。トレーニングの終了の確認は、新入社員それぞれが実施します。
パラメータとしてENAMEを追加します。ラベルはEmployee Name、データ型は文字列です。
以上でタスク定義の作成は完了です。
社員バッチの承認とラップトップの承認タスクを内部で作成するプラグインを作成します。
共有コンポーネントのプラグインを開きます。
作成済みのプラグインが一覧されます。作成をクリックします。
プラグインの作成は最初から行います。次へ進みます。
作成するプラグインの名前をOnboarding Tasks、内部名をONBOARDING_TASKSとします。タイプにプロセスを選択します。タイプがプロセスのプラグインは、データベース・サーバーで実行されるためPL/SQLで処理を記述します。
コールバックの実行ファンクション名として、以下を設定します。このプロシージャ内でAPEX_APPROVAL.CREATE_TASKを呼び出し、社員バッチとラップトップの承認タスクを作成しています。
#OWNER#.eba_demo_wf_parallel_pkg.create_tasks
完了ファンクション名として、以下を設定します。実際にこのプラグインを割り当てたワークフロー・アクティビティの完了は、それぞれの承認タスクのアクションに実装されます。このファンクションは、完了が成功したというステータスを返しています。
#OWNER#.eba_demo_wf_parallel_pkg.complete_tasks
Oracle APEXではPL/SQLコードを埋め込むことができるコンポーネントがいくつがありますが、埋め込んだコードの代わりにパッケージに含まれるプロシージャ名やファンクション名を指定することもできます。
サポート対象のコンポーネント・タイプのワークフロー・アクティビティにチェックを入れ、標準属性の完了の待機にチェックを入れます。
ここで一旦、プラグインの作成を行います。
プラグインが作成されるとカスタム属性を追加できるようになります。
カスタム属性として、REQUESTOR、EMPNO、DATE OF JOINING、MANAGER NAMEを追加します。
追加する属性のラベルにREQUESTORやEMPNOといった名前を設定します。設定のタイプにページ・アイテムを選択します。APEX 23.2ではドロップダウン・リストにページ・アイテムが2行表示されますが、どちらを選んでも大丈夫なようです。軽微な不具合でしょう。EMPNOのみ必須をオンにします。
以上でワークフロー・アクティビティに使えるプロセス・プラグインOnboarding Tasksが作成できました。
社員バッチの承認(承認タスクEmployee Badge Access)、ラップトップの購買承認(承認タスクEmp Laptop Approval)、新入社員によるトレーニング終了の確認(アクション・タスクTraining Complete)およびワークフロー・アクティビティのプロセス・プラグインOnboarding Tasksが作成できました。
これらをワークフローを作成します。
共有コンポーネントのワークフローを開きます。
作成済みのワークフローが一覧されます。作成をクリックします。
作成するワークフローの識別の名前はOnboarding Workflowとします。タイトルはOnboarding Workflow for &EMP_NAME.とします。詳細の静的IDとしONBOARDING_WFを設定します。
ワークフローの作成手順については、ハンズオン資料「Oracle APEXでワークフローを実装してみよう!」に詳しく紹介しています。ワークフローの作成手順を紹介すると記事が長くなりすぎるため、以下では作成したワークフローについて説明をします。
ワークフロー・バージョンの識別のワークフロー・バージョンは1.0とします。設定の状態は開発中になります。
ワークフローにパラメータを作成します。以下のパラメータを作成します。
静的IDがDEPARTMENT(ラベルはDepertment)、DESIGNATION(同Designation)、EMP_EMAIL(同Employee Email)、EMP_NAME(同Employee Name)、JOINING_DATE(同Joining Date)、MGR_EMAIL(同Manager Email)およびREQUESTOR(同Requestor)です。JOINING_DATEを除いて変数のデータ型はVARCHAR2、必須はオンです。
JOINING_DATEの変数のデータ型はTIMESTAMP WITH TIME ZONE、アプリケーションの書式マスクのセッション・ステート書式マスクとしてYYYY-MM-DD HH24:MIを設定します。この書式マスクは英語の元記事から変更しています。元記事では月にMONを使っていますが、MONを使用すると日本語環境で問題が発生することが多いです。
ワークフロー・バージョン変数としてEmployee IDを作成します。
静的IDはEMPLOYEE_ID、ラベルはEmployee ID、変数のデータ型はNUMBERです。他に変数としてApproverとTaskOutcomeがありますが、これらはワークフローにヒューマン・タスクのアクティビティを含めると自動的に作成されます。
アクティビティCreate Employee Recordの設定です。
英語の元記事ではPL/SQLコードを埋め込んでいますが、PL/SQLコードをパッケージEBA_DEMO_WF_PARALLEL_PKGに含めているため、タイプをAPIの呼び出しに置き換えています。
設定のパッケージはEBA_DEMO_WF_PARALLEL_PKG、プロシージャまたはファンクションとしてCREATE_EMPLOYEE_RECORDを指定します。
パラメータのファンクションの結果の値のアイテムとして、ワークフロー・バージョン変数のEMPLOYEE_IDを指定します。このアクティビティに設定された処理は、新入社員の名前や部署などを表EMP_STATSに登録したときに割り当てられた従業員番号(自動採番される主キー列EMPNOの値)を返しています。ワークフロー・バージョン変数EMPLOYEE_IDに設定された従業員番号は、これ以降のワークフロー・アクティビティから参照されます。
パラメータp_emp_nameにEMP_NAME、p_designationにDESIGNATION、p_joining_dateにJOINING_DATE、p_departmentにDEPARTMENTを割り当てます。p_joining_dateを除いて、データ型はVARCHAR2です。
パラーメータp_joining_dateのデータ型はTIMESTAMP WITH TIME ZONE、書式マスクはYYYY-MM-DD HH24:MIを設定します。
パラメータp_workflow_idは、値のタイプに静的値を選択し、静的値としてAPEXワークフローの内部変数である&APEX$WORKFLOW_ID.を設定します。データ型はNUMBERです。
アクティビティRequest Accessの設定です。
タイプとして、先ほど作成したプラグインOnboarding Tasksを選択します。
設定のREQUESTORにはワークフロー・パラメータのREQUESTOR、EMPNOにはワークフロー・バージョン変数のEMPLOYEE_ID、DATE OF JOININGにはワークフロー・パラメータのJOINING_DATE、MANAGER NAMEにはMGR_EMAILを指定します。
タイプが切替えのアクティビティAccess Approvedの設定です。
切替えのタイプはTrue False Checkを選択します。条件の条件タイプにファンクション本体を選択します。ファンクション本体に以下のPL/SQLコードを記述します。
return eba_demo_wf_parallel_pkg.access_approved(
p_employee_id => :EMPLOYEE_ID
);
ファンクションEBA_DEMO_WF_PARALLEL_PKG.ACCESS_APPROVEDは、社員バッチとラップトップの両方が承認されているとtrueを返します。
タイプにヒューマン・タスク - 作成を選択します。設定の定義にアクション・タスクとして作成したタスク定義Training Completionを選択します。ディテール主キー・アイテムとして、ワークフロー・バージョン変数のEMPLOYEE_IDを指定します。
新入社員がアプリケーションにアクセスし、社員バッチとラップトップの両方が承認されていることを確認したら、このワークフローは終了します。
パラメータEmployee Nameには、ワークフロー・パラメータEMP_NAMEを指定します。
アクティビティAccess Approvedがfalseのときは、終了状態が終了(英語はTerminatedなので本当は中断)で終了します。
正常なパスの終了状態は完了になります。
アクティビティAccess ApprovedとComplete Trainingを繋ぐ接続の名前はYes、条件のタイミングはTrueです。
新入社員オンボーディングのワークフローの設定は以上になります。
最後にAPEXアプリケーションに、ページをいくつか作成します。
最初に新入社員のオンボーディングを開始するページを作成します。
ページの作成を開始します。
ページ番号は4、ページの名前はRequest Onboardingとします。
ページの作成をクリックします。
ページが作成されます。
ワークフローを開始する際に必要なワークフロー・パラメータに与える値を入力するページ・アイテムを作成します。ワークフロー・パラメータREQUESTORを除く、すべてのワークフロー・パラメータについて、対応するページ・アイテムを作成します。
作成するページ・アイテムはP4_NAME(ラベルはEmployee Name)、P4_EMAIL(同Employee Email)、P4_JOINING_DATE(同Joining Date)、P4_DESIGNATION(同Designation)、P4_DEPARTMENT(同Department)、P4_MANAGER_EMAIL(同Manager Email)です。
ページ・アイテムP4_JOINING_DATEを除いて、タイプはテキスト・フィールドです。すべてのページ・アイテムで、セッション・ステートのストレージはリクエストごと(メモリーのみ)を選択します。
ページ・アイテムP4_JOINING_DATEは、タイプとして日付ピッカーを選択し、外観の書式マスクにYYYY-MM-DD HH24:MIを指定します。
新入社員のオンボーディングを開始するボタンSTART_ONBOARDINGを作成します。ラベルはStart Onboarding、動作のアクションはデフォルトのページの送信です。
先ほど作成したワークフローOnboarding Workflowを開始するプロセスを作成します。
識別の名前はSubmit Workflow、タイプとしてワークフローを選択します。
設定のタイプに開始を選択し、定義にOnboarding Workflowを選びます。サーバー側の条件のボタン押下時にSTART_ONBOARDINGを指定します。
REQUESTORを除くパラメータには、対応するページ・アイテムが作成されています。値のタイプとしてアイテムを選び、アイテムにそれぞれ対応したページ・アイテムを指定します。
パラメータREQUESTORについては、値のタイプに静的値を選び、静的値として&APP_USER.を指定します。アプリケーションにサインインしているユーザー、つまりこのワークフローを開始したユーザーがREQUESTORになります。
サインインしたユーザーに割り当てられているタスクを一覧する、統合タスク・リストのページを作成します。
ページの作成を開始し、統合タスク・リストを選択します。
ページ番号は5、名前はMy Tasksとします。自分に割り当てられているタスクを一覧するため、レポート・コンテキストにマイ・タスクを選択します。
ページの作成をクリックします。統合タスク・リストのページはカスタマイズせず、作成されたページをそのまま使用します。
続けて、ページの作成を開始し、ワークフロー・コンソールを選択します。
自分自身が開始したワークフローを一覧し、一覧より選択したワークフローの詳細を表示するページを作成します。
レポートのページのページ番号は6、名前はMonitor Onboarding Workflowとします。レポート・コンテキストに自分で開始を選択します。選択したワークフローの詳細を表示するフォームのページ番号は7、フォーム・ページ名はOnboarding Detailsとします。フォーム・ページ・モードはドロワーとします。
ページの作成をクリックします。ワークフロー・コンソールもカスタマイズせずに、そのまま使用します。
最後にタスク定義Training Completionの詳細ページをカスタマイズします。今までの手順通りにアプリケーションを作成していると、詳細ページはページ番号8で作成されています。
ページ・デザイナでページ番号8のタスクの詳細を開きます。
ボタンCOMPLETEのラベルを完了からAcknowledgeに変更します。
新たにタイプが静的コンテンツのリージョンを作成し、ソースのHTMLコードに以下を記述します。
Please click on the Acknowledge button to confirm the completion of your new-hire training
リージョン開発者情報はコメント・アウトします。
以上でAPEXアプリケーションが完成しました。
ワークスペースにデモ用のユーザーを追加する代わりに、デモ用の認証スキームを作成します。
認証スキームのタイプとしてカスタムを選択し、ソースのPL/SQLコードに以下を記述します。
設定の認証ファンクション名にdemo_authenticationを指定します。
認証スキームの作成を実行し、認証スキームを作成します。
作成された認証スキームをカレント・スキームにします。
以上で、作成したアプリケーションの動作を確認する準備ができました。
アプリケーションを実行し、ユーザーSTEVEでサインインします。
Request Onboardingを開き、Employee NameにJAYを指定してStart Onboardingをクリックします。
新入社員JAYのオンボーディングが開始し、社員バッチの承認タスクがユーザーRALMUELL、ラップトップの承認タスクがJANEに割り当てられます。
ユーザーSTEVEが開始したワークフローを一覧します。
Monitor Onboarding Workflowを開きます。たった今開始したワークフローが、ステータスがアクティブで一覧されます。
ワークフローの詳細を確認すると、アクティビティRequest AccessでWaiting(待機中)になっていることが確認できます。
ユーザーRALMUELLでサインインしてMy Tasksを開くと、新入社員JAYの社員バッチの承認タスクが割り当たっています。
承認します。
ユーザーJANEでサインインしてMy Tasksを開くと、新入社員JAYのラップトップの承認タスクが割り当たっています。
ユーザーSTEVEでサインインし、Monitor Onboarding Workflowからワークフローの詳細を確認します。
アクティビティComplete TrainingでWaiting(待機中)になっていることが確認できます。
詳細のフォームを開いて、画面右下にあるボタンAcknowledgeをクリックします。新入社員がアクション・タスクを承認すると、このワークフローは完了します。
ユーザーSTEVEでサインインしMonitor Onboarding Workflowより、ワークフローの完了を確認します。
社員バッチまたはラップトップの承認タスクが却下されると、ワークフローはアクティビティAccess Approvedから中断に遷移します。
今回の記事は以上になります。
APEXワークフローがBPMNの並行ゲートウェイと等価な記述をサポートしていないのは大きなディスアドバンテージと言えますが、カスタム・プラグインで実装することにより対処できる場合もあるでしょう。
今回作成したAPEXアプリケーションにエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/new-hire-onboarding.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完