「だいじょぶだぁ」と言うとSAP CP Workflow Serviceで購買依頼登録が承認されるiOSアプリを実装する(1/2)

Mona Lisacoです。最近はもっぱらFioriばかり実装しているのですが、久々にiOSアプリに挑戦しました。

さて、[前回までの記事](https://qiita.com/monamona/items/c55435580eaad482c7f7)では、「だっふんだ」という音声コマンドによって「ドリフ大爆笑DVD」の購買依頼伝票を登録することができるiOSアプリを実装したのですが、その甲斐あって、麹町一丁目のとある雑貨店は「ドリフ大爆笑」大流行に伴う超繁忙期をどうにか乗り越えることができたようです。

ところがこのアプリはあまりにノスタルジックに心地よく購買依頼伝票が登録できてしまうため、店舗スタッフがついつい必要以上に「だっふんだ」と言って購買依頼伝票を登録してしまうという事態が発生しがちなのだとか。店舗スタッフの業務に潤いがもたらされるのは素晴らしい限りですが、やはり店長の承認を気持ちよく得たうえで伝票が切られる仕組みがあったほうが良いということで、今回は

- **スタッフ**が**「だっふんだ」**と言うとSAP CP Workflowで**店長**に「ドリフ大爆笑DVD」購買依頼登録の**承認申請**を飛ばせるiOSアプリ
- **店長**が**「だいじょぶだぁ」**と言うとSAP CP Workflowで申請を**承認**し、**「だめだこりゃ」**と言うと申請を**否認**することができるiOSアプリ
- 購買依頼登録が承認されると、「ドリフ大爆笑DVD」の**購買依頼伝票をSAP S/4HANAで登録**してくれるWorkflow

を実装していきたいと思います。

「だっふんだ」「だいじょぶだぁ」「だめだこりゃ」といった幸せな音声コマンドが麹町一丁目店の店内をひっきりなしに飛び交うようになる日もそう遠くはないでしょう。

# iOSアプリの画面イメージ

▼店舗スタッフが使用する申請用アプリの画面
![bapp1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/925beea3-2ec7-4a30-2a07-125d9ae9777b.png)

▼店長が使用する承認用アプリの画面
![bapp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/5c58a721-a36a-ee53-060d-155e9b8f53f6.png)



# アーキテクチャと構築手順、関連情報

アーキテクチャのイメージはざっくりと下図のような感じです。
![アーキテクチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/73c56285-0b3d-a0fa-1b19-e596edeb395a.png)

今回の記事(1/2)では
- SAP CP Workflow ServiceでだっふんだWorkflow定義を実装する方法
をご紹介します。

[次回の記事(2/2)](https://qiita.com/monamona/items/60bfc512509258b83842)では
- Workflow API for Neoを用いて、だっふんだWorkflowとだっふんだiOSアプリと連携させる方法
をご紹介するつもりです。

その他、今回の実装に関連する情報を下記にまとめておきます。
- そもそもSAP CP Workflowってなに？　--> サービスに関しては[こちら](https://cloudplatform.sap.com/capabilities/product-info.SAP-Cloud-Platform-Workflow.df696e5a-d973-4ecd-8d8d-532d60aa1921.html)、実装の詳細に関しては[こちら](https://help.sap.com/viewer/product/WORKFLOW_SERVICE/Cloud/en-US)
- iOS AppのSpeech Frameworkを用いた音声認識ってどうやるの？ --> [Mona Lisacoの過去記事](https://qiita.com/monamona/items/c55435580eaad482c7f7)
- OData Serviceってどうやって実装するの？ --> [zukahiraさんのOiita記事](https://qiita.com/zukahira/items/c97f49f211a70dc1b555)

# 前提条件と制限

## 前提条件

- フロントエンド実行環境: iPhone8 iOS 12.3.1
- フロントエンド開発環境: macOS Mojave 10.14.4 / Xcode 10.2.1 / Swift 5.0.1
- クラウド開発実行環境: SAP Cloud Platform（NEO） ※ SAP CPユーザを作成すれば無料のトライアル環境でWorkflow Serviceを使用できる。
   - SAP CP ConnectivityでWorkflow RuntimeのDestinationが設定されていること（デフォルトで設定されているはず）。
   - SAP CP Connectivityでオンプレミス環境へのDestinationが設定されていること。（▲）
- バックエンド: SAP S/4HANA （オンプレミス） 
   - SAP CPとSAP HANA Cloud Connector(SCC)で連携されていること。（▲）
   - 購買依頼を登録できる適当なOData Serviceが有効化されていること（この記事ではカスタム実装したOData Serviceを使用する）。（▲）

※（▲）を付したものはOData Serviceを用いるための条件なので、WorkflowとiOS Appだけ試しに実装してみたい！という場合は不要です。

## 制限

- 今回の実装はトライアル環境（1ユーザ=1環境）で行うため、店長役の人とスタッフ役の人を技術的には別ユーザとして区別できない。


# Workflow定義の実装手順
## Workflow Editorを準備し、Workflow Projectを作成する

SAP CP Workflow ServiceはSAP CP WebIDE上のWorkflow Editorを用いて実装します。
Workflow Editorというのは、要素をみょーんとドラッグして繋げるだけで、ノンコーディングでWorkflow定義を実装できるツールです。
まずはこのWorkflow EditorがWeb IDEで使えるように準備します。

Workflow Editorの準備方法は[こちらの記事](https://developers.sap.com/tutorials/cp-workflow-getting-started.html)を参照してください。
Workflow Projectの作成方法は[こちらの記事](https://developers.sap.com/tutorials/cp-workflow-create-project.html)を参照してください。
（今回は、Project NameもWorkflow Nameも`MyDafundaWorkflow`とすることにします。）

## Workflow定義をざっくりつくる

とりあえずWorkflow定義の全体を作り、詳細な設定はあとからやっていくことにしましょう。
まずは要素をみょーんと繋げてみると、こんな感じ。
![blog3ワークフロー定義.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/a871330f-7951-2f3c-d45d-2c353dadf3fb.png)

分かりやすいようにNameを変更します。
![blog4.1名前をつける.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/cfe05439-f8dd-2f66-d892-8d42c5d545b5.png)


## それぞれの要素のPropertiesを設定する
Workflow Editorの右側にPropertiesを編集できる欄があるので、ここで下記のようにプロパティを設定していきます。
${xxxx.xxxx.xxxx}という部分は、Workflow Contextという、Workflow専用の変数みたいなもの等を指し示しています。実装を進めていくうちにWorkflow Contextの正体が明らかになっていくと思うので、あまり深く考えずにコピーして埋めてみてください。

**User Task Properties**

|タブ           |プロパティ名        |設定内容                         |
|--------------|-----------------|--------------------------------|
|General       |Name             |`「だいじょぶだぁ」と言って購買依頼を承認`|
|Details       |Subject          |`「だいじょぶだぁ」と言って購買依頼を承認`|
|Details       |(Recipients)Users|自分のSAP CP User ID （例：`P00012345678`） |
|User Interface|Type             |Form                            |
|Form Details  |File Name        |`ApprovePR.form`※"Create File"をクリックして作成する   |
|Form Details  |ID               |`approvepr`                     |
|Form Details  |Revision         |`1.0`                           |

**Service Task Properties**

|タブ           |プロパティ名        |設定内容                         |
|--------------|-----------------|--------------------------------|
|General       |Name             |`SAP S/4HANAで購買依頼を登録`     |
|Details       |Destination     |SAP CP Connectivityで設定したDestinationを記載 （例：`1809_CL100`）|
|Details       |Choose a Service from|Others                      |
|Details       |Path　　　      　|使用したいOData Serviceへのパスを記載 （例:`/sap/opu/odata/sap/YIOSBLOG02_SRV/PurchaseSet`） |
|Details       |HTTP Method　　　　|POST                           |
|Details       |Path to XSRF Token|使用したいOData ServiceのXCRF Tokenへのパスを記載 （例:`/sap/opu/odata/sap/YIOSBLOG02_SRV/`） |
|Details       |Request Variable|`${context.odata.request}`      |
|Details       |Response Variable|`${context.odata.response}`      |

**Sequence Flow Properties(承認の場合)**

|プロパティ名        |設定内容                         |
|-----------------|--------------------------------|
|Name             |`承認の場合`     |
|Condition        |(＊)参照|

(＊)`${context.approved=="true"||usertasks.usertask1.last.decision=="approve"}`

**Sequence Flow Properties(否認の場合)**

|プロパティ名        |設定内容                         |
|-----------------|--------------------------------|
|Name             |`否認の場合`      |
|Condition        |Defaultにチェックする   |

## (Optional)Form UIを設定する

今回はだっふんだiOS Appをユーザインターフェースとして使用する想定なので作り込む必要はないのですが、
SAP Fiori Launchpad上で動く承認用のユーザインターフェースが超簡単に設定できるので、テスト目的で作成しましょう。
先ほどの手順で作成した`ApprovePR.form`ファイルを開いて、下記のようにプロパティを埋めます。

<img width="1048" alt="blog5.2フォームの項目.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/56502cab-dd51-37d0-44ba-69f5cd448d57.png">

<img width="1236" alt="blog6.4フォームのDecision.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/17272e4d-6a13-0c29-166a-14efe97571b7.png">


## (Optional)Sample Contextを設定する

これも実装の上で必須というわけではないのですが、テストを簡単にするためにSample Contextを設定しておきましょう。

**Start Event Properties**

|タブ           |プロパティ名        |設定内容                         |
|--------------|-----------------|--------------------------------|
|General       |Name             |`「だっふんだ」と言って承認を申請`|
|Details  |Configure Sample Context        |チェックを入れる   |
|Details  |File Name        |`SampleContext.json`※"Create File"をクリックして作成する   |

SampleContext.jsonの中身は以下のように書き換えます。

```json:SampleContext.json
{
	"approved":"",
	"odata": {
		"request": {
		//使用するODataの仕様に合わせてHTTPリクエストのbodyを設定
			"Matnr": "300280", 
			"Menge": 1,          
			"Meins": "EA"      
		},
		"response": {}
	}
}
```

## 保存してデプロイする
Ctrl+SまたはCommand+Sで変更した全てのファイルを保存し、
`MyDafundaWorkflow.workflow`および`ApprovePR.form`をそれぞれ右クリックして
Deploy-->Deploy to SAP Cloud Platform Workflowを選択します。

# デプロイしたWorkflowが動くかテストする

## Workflow Instanceを開始する
SAP Fiori Launchpad(SAP CP)へアクセスし、アプリファインダから"Monitor Workflow - Workflow Definition"という管理用のアプリを探して開きます。
"MyDafundaWorkflow"を選択して"新規インスタンスの開始"を押下し、ポップアップ上でもう一度"新規インスタンスの開始"を押下すると、
試験的にWorkflowインスタンスを開始することができます。

<img width="1629" alt="blog7.0新規インスタンス.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/ab152b52-821d-bfee-dc33-c981c4fffc99.png">

次に、"My Inbox"というアプリを開くと、作成したUser Task「『だいじょぶだぁ』と言って購買依頼を承認」が届いているはず！
「だいじょぶだぁ」ボタンと「だめだこりゃ」ボタンがちゃんと実装されてますね。
<img width="1387" alt="blog8.0MyInbox.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/2a0e73d6-2646-004b-0e3a-c1aa673200a3.png">

"Monitor Workflow - Workflow Instance"というアプリを開くと、Workflowインスタンスを監視することができます。
<img width="1357" alt="blog8.0ワークフローの監視.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/98d79f85-c028-89dc-79d9-c6bee3acad9d.png">

## だいじょぶだぁボタンを押してみる

"My Inbox"で試しに「だいじょぶだぁ」ボタンを押してから"Monitor Workflow - Workflow Instance"に戻り、インスタンスを確認してみると、ステータスが「完了」になっているはずです。
（※デフォルトでかかっているフィルタだと「完了」ステータスのインスタンスが表示されないので、フィルタの設定を変更してから確認してください。）
ログを見てみると、Service Task「SAP S/4HANAで購買依頼を登録」も無事実行されていることが分かります。

## だめだこりゃボタンを押してみる
「だめだこりゃ」ボタンを押してからインスタンスを確認してみると、同様にステータスが「完了」になっているはずですが、Service Task「SAP S/4HANAで購買依頼を登録」は実行されておらず、条件分岐がうまくいっていることが分かります。

## だいじょぶだぁ分岐条件について

分岐条件は"**Sequence Flow Properties(承認の場合)**"のプロパティに記載していました。
`${context.approved=="true"||usertasks.usertask1.last.decision=="approve"}`
これは下記のような意味を表しています。

**「Workflow Contextのapprovedの値が"true"」…(1)
または「usertask1の最後のDecisionが"approve"」…(2)
であれば購買依頼登録の方の分岐に進み、
どちらでもなければ何もしないで終了する方の分岐に進む。**

(1)は次回実装するiOSアプリのほうで使用する想定の条件で、今回のテストで使ったのは(2)のほうです。
「だいじょぶだぁ」ボタンを押すとボタンのIDである"approve"がusertask1の最後のDecisionとしてセットされるので、これをフラグにして条件分岐させています。

# 次回の記事では……

というわけで、だっふんだWorkflow定義の実装が完了しました！

ここまでの実装で店長のだいじょぶだぁ承認画面は十分使えるので承認用iOSアプリは必要ないのでは……？　だなんて野暮なことを、業務改善への熱意と矜持にあふれた麹町一丁目店の店長が考えるはずもありません。

**どうしても「だいじょぶだぁ」と言って購買依頼を承認したい！！！！！**

という店長の熱い思いを叶えるべく、[次回の記事(2/2)](https://qiita.com/monamona/items/60bfc512509258b83842)ではApple社のSpeech Frameworkを活用したiOS AppとSAP CP Workflowの連携に取り組んでいきます。

（続く）