この特集のトップページへ
>
Chapter 6:ビジネスロジックの設計
6.3.5 在庫の処理
●入庫予定の更新
次に,入庫予定の削除処理を実装する。在庫情報テーブルにおいても,入庫予定を削除する際にはレコードそのものを削除するのではなく,DELETEDFLAGフィールドの値をTrueにすることで削除したように見せるようにする。また,顧客の削除や製品の削除と同様に,すでにDELETEDFLAGフィールドがTrueになっている入庫予定を,特定の権限を持ったユーザーが削除しようとした場合には,レコードそのものを削除するという仕組みを提供することにする。ここで特定の権限を持つユーザーは,ProductsAdminロールまたはAllAdminロールに属するユーザーとする。
まず,データオブジェクトであるDataObj.StockコンポーネントにList 6-83に示すSetDeletedFlagメソッドを実装する。
SetDeletedFlagメソッドは,引数に削除の対象となるレコードを表すレコードIDの値と設定したいDELETEDFLAGフィールドの値とを渡すと,指定したレコードのDELETEDFLAGフィールドの値を設定する。第2引数にTrueを渡せばDELETEDFLAGフィールドの値はTrueに設定され(そのレコードは削除されたものとして扱われ),Falseを渡せばDELETEDFLAGフィールドの値がFalseに戻る(削除されたレコードが復活される)。
また,本当にレコードを削除するために,List 6-84に示すDeleteRecordメソッドも実装しておく。DeleteRecordメソッドは,指定されたレコードそのものを削除してしまうメソッドである。
ビジネスロジック側では,List 6-83に示したSetDeletedFlagメソッドと,List 6-84に示したDeleteRecordメソッドとを組み合わせ,削除処理を実現する。これを,Business.ProductコンポーネントにDeleteStorageという名前のメソッドとして実装したものがList 6-85である。
DeleteStorageメソッドでは,もしDELETEDFLAGフィールドの値がFalseであれば,List 6-83のSetDeletedFlagメソッドを呼び出し,それをTrueに設定するだけである。しかし,すでにDELETEDFLAGフィールドの値がTrueであった場合には,List 6-84に示したDeleteRecordメソッドを呼び出し,レコードそのものを削除する。ただし,レコードそのものを削除できるのは,ProductsAdminロールかAllAdminロールに属するユーザーだけに制限している(41〜49行目)。また,DeletedStorageメソッドの30〜32行目では,事前にIsDueメソッド(List 6-73)を呼び出して,削除対象となるレコードが施行ずみでないことを,24〜27行目ではInStockメソッド(List 6-82)を呼び出して,それが入庫予定のレコードであることを,それぞれ確認している。前者は,入庫予定の更新時と同じ理由で確認している。つまり,施行ずみのレコードを削除した場合には,製品情報テーブルのSTOCKフィールドの値も併せて修正しないと,入庫数と在庫数とのあいだに不整合が生じるおそれがある。後者は,出庫予定のレコードが削除されてしまうと,伝票上の出庫数と実際の出庫数との関係が狂ってしまうためである。
ここで,DeleteStorageメソッドで削除ずみとしたレコード(DELETEDFLAGフィールドの値をTrueにしたレコード)を復活させるメソッドも用意しておこう。復活させるにはDELETEDFLAGフィールドの値をFalseに戻せばよい。そのためには,第2引数にFalseを指定して,SetDeletedFlagメソッド(List 6-83)を呼び出せばよい。実際,顧客情報テーブルや製品情報テーブルの処理では,そのような方法で,いったん削除ずみとした顧客や製品を復活させる処理を実装してきた。
しかし,在庫情報テーブルの場合には,やや勝手が違う。いまいちど,このサンプルで使っているテーブルの連携図をFig.6-67に示す。
Fig.6-67 テーブルの連携図

Fig.6-67を参照するとわかるように,在庫情報テーブルでは製品情報テーブルと伝票情報テーブルの2つを参照している。このため,レコードを復活しようとしたときには,PRODUCTIDフィールドの値で示されている製品情報テーブル内のレコードがすでに削除されていたり,SLIPIDフィールドの値で示されている伝票情報テーブル内のレコードが削除されてしたりして,参照先がなくなっていることがあり得る。よって,在庫情報テーブル内のレコードを復活させる場合には,事前にPRODUCTIDフィールドの値(製品番号)が示している製品情報テーブル内のレコードと,SLIPIDフィールドの値(伝票番号)が示している伝票情報テーブル内のレコードの2つが,それぞれ存在しているかどうかを確かめなければならない。
指定された製品番号を持つ製品が存在するかどうかは,DataObj.Productコンポーネントにすでに実装したIsDeletedメソッド(List 6-58)で確かめることができる。指定された伝票番号を持つ伝票が存在するかどうかのメソッドは,まだ実装していない。しかし,入庫予定を示す場合には,伝票を参照してしない(SLIPIDフィールドの値には常にNullを格納している)ので,特に調査しなくてもよい。
ビジネスロジック側では,次の2つの処理をすることでレコードの復活ができる。この2つの処理を実際にBusiness.ProductコンポーネントにUndeleteStorageメソッドとして実装すると,List 6-86のようになる。
- List 6-58に示したDataObj.ProductコンポーネントのIsDeletedメソッドを呼び出して,復活させようとしている在庫情報テーブル中のレコードが参照している製品が削除されていないかどうかを確かめる
- 削除されていなければ,List 6-83に示したDataObj.SlipコンポーネントのSetDeletedFlagメソッドを呼び出し,DELETEDFLAGフィールドの値をFalseに設定する
List 6-86では,プログラム内でロールによるセキュリティを判定していない。しかし,実際に運用するときには,ProductsAdminロールとAllAdminロールに属するユーザー以外には呼び出されないよう,[コンポーネントサービス]管理ツールでセキュリティを設定する。
| Chapter 6 47/92 |
