【RAP】Unmanaged BOの実装 (4) Delete処理

##はじめに
この記事では、RAP(ABAP RESTful Application Programming Model)で作成したUnmanaged BOにDelete処理を追加します。

シリーズの先頭はこちら☞ [【RAP】Unmanaged BOの実装 (1)](https://qiita.com/tami/items/7d19052b1866f7aaf69f)

##処理概要
現在の構成は以下のようになっています。Behavior Implementationクラスから、実際の処理を行うAdapterクラスのメソッドが呼ばれます。Adapterクラスのローカルクラスではトランザクションバッファとのやり取りを行い、SAVEのタイミングでバッファから取り出したレコードをDBに格納します。

今回は、DELETEの処理を追加するとともに、SAVEの処理を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/857eee72-9dbe-ac22-437e-8f625b189528.png)


##実装ステップ
1. Adapterクラスの実装
1. Behavior Implementationクラスの実装

###1. Adapterクラスの実装
####1.1. インターフェースに型を追加

削除処理で使用する、エンティティのキーのみを持った型を追加します。

```abap:zif_person_adapter
  TYPES: BEGIN OF ts_person_key,
           person_id TYPE ze_person_id,
         END OF ts_person_key.

  TYPES tt_person_key TYPE SORTED TABLE OF ts_person_key WITH UNIQUE KEY person_id.

  TYPES: BEGIN OF ts_familymember_key,
           person_id TYPE ze_person_id,
           member_id TYPE ze_member_id,
         END OF ts_familymember_key.

  TYPES tt_familymember_key TYPE SORTED TABLE OF ts_familymember_key WITH UNIQUE KEY person_id member_id.
```

####1.2. ローカルクラスの実装
バッファ更新用のメソッドを追加します。また、saveメソッドに更新処理を追加します。initializeメソッドで削除用バッファの初期化を行います。

メソッド定義

```abap:lcl_person_buffer
    "削除用のバッファテーブル
    DATA mt_delete_buffer_person TYPE zif_person_adapter=>tt_person_key.
    DATA mt_delete_buffer_familymember TYPE zif_person_adapter=>tt_familymember_key.

    METHODS buffer_person_for_delete IMPORTING is_personkey TYPE zif_person_adapter=>ts_person_key
                                               it_memberkey TYPE zif_person_adapter=>tt_familymember_key.
    METHODS buffer_familymember_for_delete IMPORTING is_memberkey TYPE zif_person_adapter=>ts_familymember_key.
```

メソッド実装

```abap
  METHOD buffer_person_for_delete.
    CHECK is_personkey IS NOT INITIAL.
    INSERT is_personkey INTO TABLE mt_delete_buffer_person.

    CHECK it_memberkey IS NOT INITIAL.
    INSERT LINES OF it_memberkey INTO TABLE mt_delete_buffer_familymember.
  ENDMETHOD.

  METHOD buffer_familymember_for_delete.
    CHECK is_memberkey IS NOT INITIAL.
    INSERT is_memberkey INTO TABLE mt_delete_buffer_familymember.

  ENDMETHOD.

  METHOD save.
    DATA(lt_perton) = get_person_create( ).
    DATA(lt_familymember) = get_familymember_create(  ).

    INSERT zperson_u FROM TABLE @lt_perton.
    UPDATE zperson_u FROM TABLE @mt_update_buffer_person.
    DELETE zperson_u FROM TABLE @( CORRESPONDING #( mt_delete_buffer_person ) ). "追加

    INSERT zfamilymember_u FROM TABLE @lt_familymember.
    UPDATE zfamilymember_u FROM TABLE @mt_update_buffer_familymember.
    DELETE zfamilymember_u FROM TABLE @( CORRESPONDING #( mt_delete_buffer_familymember ) ). "追加
  ENDMETHOD.

  METHOD initialize.
    CLEAR: mt_create_buffer_person,
           mt_update_buffer_person,
           mt_delete_buffer_person, "追加
           mt_create_buffer_familymember,
           mt_update_buffer_familymember,
           mt_delete_buffer_familymember. "追加
  ENDMETHOD.
```
####1.3. グローバルクラスの実装
Behavior Implementationクラスから呼び出されるメソッドを実装します。

メソッド定義

```abap:zcl_person_adapter
    METHODS delete_person IMPORTING is_personkey type zif_person_adapter=>ts_person_key
                                    it_memberkey type zif_person_adapter=>tt_familymember_key.
    METHODS delete_familymember IMPORTING is_memberkey type zif_person_adapter=>ts_familymember_key.
```

メソッド実装

```abap
  METHOD delete_person.
    lcl_person_buffer=>get_instance( )->buffer_person_for_delete(
      EXPORTING
        is_personkey = is_personkey
        it_memberkey = it_memberkey
    ).
  ENDMETHOD.

  METHOD delete_familymember.
    lcl_person_buffer=>get_instance( )->buffer_familymember_for_delete( is_memberkey ).

  ENDMETHOD.
```

###2. Behavior Implementationクラスの実装
delete処理には"key"という構造にエンティティのキーが渡されます。Personエンティティの場合、ひもづくFamily Memberも削除する必要があるため、削除対象のFamily Memberのキーを取得してAdapterクラスのdeleteメソッドに渡します。

Person

```abap:zbp_i_person_u>lhc_person
  METHOD delete.
    DATA ls_personkey TYPE zif_person_adapter=>ts_person_key.
    DATA lt_memberkey TYPE zif_person_adapter=>tt_familymember_key.

    LOOP AT keys ASSIGNING FIELD-SYMBOL(<key>).
      ls_personkey-person_id = <key>-PersonID.

      SELECT person_id, member_id FROM zfamilymember_u
        WHERE person_id = @<key>-PersonID
        INTO TABLE @lt_memberkey.

      zcl_person_adapter=>get_instance(  )->delete_person(
        EXPORTING
          is_personkey = ls_personkey
          it_memberkey = lt_memberkey
      ).

    ENDLOOP.

  ENDMETHOD.
```

Family Member

```abap:zbp_i_familymember_u>lhc_familymember
  METHOD delete.
    DATA ls_memberkey TYPE zif_person_adapter=>ts_familymember_key.

    LOOP AT keys ASSIGNING FIELD-SYMBOL(<key>).
      ls_memberkey-person_id = <key>-PersonID.
      ls_memberkey-member_id = <key>-MemberID.
      zcl_person_adapter=>get_instance(  )->delete_familymember( ls_memberkey ).

    ENDLOOP.

  ENDMETHOD.
```

##動作確認
Personを削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/671fb81a-7a11-5b3c-348c-38facb1bd91a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/64e49f41-e946-92ba-4590-99791969feaa.png)
削除されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c0b36a88-20f5-d3e3-d7c5-8cdb338096e8.png)
Family Memberも削除されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/d4dbfbbc-24c5-c615-2063-ad599780072e.png)

次はFamily Memberのみ削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/09407961-ea9a-8283-6655-99312b249678.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/82a4fbb9-1d8d-984c-342c-822c7184959d.png)
削除されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/57323174-d3fe-da26-e2b8-8902f3212b06.png)