この特集のトップページへ
Chapter 6:ビジネスロジックの設計



6.4.2 伝票情報の編集
●伝票を編集するビジネスコンポーネントの実装
 以上のようにDataObj.SlipコンポーネントとDataObj.SlipInformationコンポーネントに実装してきたメソッドを組み合わせて呼び出し,伝票を編集するビジネスコンポーネントを作成してゆくことにする。このサンプルでは,伝票を編集するメソッドはBusiness.Slipコンポーネントに実装してゆく。

○伝票情報の更新
 まずは,伝票情報の更新から考えてゆく。伝票情報の更新には,2つある。1つは,伝票情報テーブル内のCUSTOMERIDフィールドの値とONEBILLFLAGフィールドの値を変更するもの,もう1つは,伝票追加情報テーブルの各フィールドの値を変更するものである。前者の処理を実現するにはDataObj.SlipコンポーネントのUpdate_CUSTOMERIDメソッド(List 6-95)とUpdate_ONEBILLFLAGメソッド(List 6-96)を,後者の処理を実現するにはDataObj.SlipInformationコンポーネントのAddRecordメソッド(List 6-92)とSetDeletedメソッド(List 6-107)を,それぞれ組み合わせて呼び出す。

 しかし,プレゼンテーション層から見た場合,伝票情報テーブルと伝票追加情報テーブルに分けられている必然性はなく,どちらを更新するにしても1つのメソッドで更新を実現したほうが便利であると考えられる。多くの場合,伝票の情報を更新するときには,Fig.6-78のようなユーザーインタフェースを表示し,ユーザーに情報を編集してもらうことになると思われる。

Fig.6-78 伝票情報を編集するためのユーザーインタフェースの例
fig6_78

 そこで,ビジネスロジック層側では,伝票情報テーブルも伝票追加情報テーブルも一緒に更新できるメソッドを実装する。このメソッドをBusiness.SlipコンポーネントにUpdateSlipという名前で実装すると,List 6-110のようになる。

 List 6-110UpdateSlipメソッドは,やや複雑な処理をしているので,順に説明してゆこう。

 まず,39〜41行目では,DataObj.Slipコンポーネントを実体化したのち,IsDeletedメソッド(List 6-104)を呼び出し,削除ずみでないことを確認している。削除ずみであればエラーとする。そして次に,44行目と45行目でDataObj.SlipコンポーネントのGetRecord_Slipメソッド(List 6-97)とGetRecord_Billメソッド(List 6-98)を呼び出し,その時点における伝票の情報を取得している。ここまでは問題ないだろう。

 やや複雑になっているのが,53〜61行目の処理である。53行目では,このメソッドを呼び出したユーザーと,その時点のMADEUSERフィールドの値(伝票の起票者)が一致するかどうかを確認している。もし両者が一致せず,かつメソッドを呼び出したユーザーがSalesManagerロール,SalesAdminロール,AllAdminロールのいずれにも属していないのであれば,エラーを返す。この処理によって,自分が起票した伝票以外は編集できないように制限することができる。一般に伝票というものは,起票者以外に手軽に書き換えを許すべきではない。そのため,このように起票者以外は書き換えられないような仕組みを用意することにした。

 なお,SalesManagerロール,SalesAdminロール,AllAdminロールに属するユーザーに限っては,他人が作成した伝票も書き換えることができるように実装した。もちろん,別にこうしなくてもかまわないのだが,完全に起票者以外は書き換えられないようにしてしまうのは賢くない。そのような実装にしてしまうと,伝票の起票者が人事異動などでいなくなってしまった場合,そのユーザーが起票した伝票は誰も編集できなくなってしまうためである。やはり,管理者に相当するロールには,何らかの特権を与える必要があるだろう。今回は作らないが,伝票の起票者(MADEUSERフィールドの値)を変更するメソッドを実装しておく方法もあるだろう。そのようなメソッドを実装しておけば,ある伝票の処理を別のユーザーに容易に引き継がせることができるようになる。

 さて,実際に伝票の情報を更新しているのは,67行目以降である。しかし,67行目のまえに,65行目でその時点における伝票の状態を取得しておき,伝票が編集可能な状態であるかどうかを逐一調べるようにしている。たとえば67〜83行目では,CUSTOMERIDフィールドの更新処理をしているわけだが,70行目では,伝票の状態がRequestingConsentよりも大きい場合にはエラーとして扱っている。List 6-105SlipStatus列挙型を参照してもらうとわかるように,RequestingConsentは承認依頼中であることを示すものである。つまり70行目では,もう承認されてしまったならば,CUSTOMERIDフィールドを更新できないという制限を課していることになる。承認依頼中に至っていなければ,List 6-95で実装したUpdate_CUSTOMERIDメソッドを呼び出し,実際にCUSTOMERIDフィールドの値を更新する。

 以下,ONEBILLIDDIVISIONPERSONDELIVERDATESENT_ADDRSENT_TELMEMOの順で各フィールドの値を更新してゆくが,処理内容はほぼ同様である。ONEBILLIDフィールドの値を更新しようとしていた場合には,List 6-96で実装したUpdate_ONEBILLIDメソッドを呼び出し,更新処理をしている。残りのフィールドは,伝票情報テーブルではなく,伝票追加情報テーブルに付随するものである。そこで,List 6-107で実装したDataObj.SlipInformationコンポーネントのSetDeletedメソッドを呼び出して現在のレコードを削除し,List 6-92で実装したAddRecordメソッドを呼び出して新しいレコードを追加するという手順を踏むことで,フィールドの値を更新している。これは「○伝票追加情報テーブルの更新」で説明したように,履歴を残すための処置である。

 なお,List 6-110Err.Raiseメソッドを呼び出すときに使っているERR_CANTUPDATE定数は,List 6-34に示したBusinessError列挙型にList 6-111のように追加しておくものとする。

○伝票情報の取得
 次に,伝票情報の取得について考える。これは単にデータオブジェクトをそのまま呼び出して,その結果を戻すように中継すればよい。たとえば,DataObj.SlipコンポーネントのGetRecord_Slipメソッド(List 6-97)を呼び出し,伝票にかかわる基本的な情報を取得するメソッドとして実装する。このようなメソッドをBusiness.SlipコンポーネントにGetSlipという名前で実装すると,List 6-112のようになる。

 List 6-112に示したGetSlipメソッドは,単純にDataObj.SlipコンポーネントのGetRecord_Slipメソッドを呼び出すだけである。しかし,38行目では,事前にChk_Viewというプロシージャを呼び出している。Chk_Viewプロシージャの内容はList 6-113のとおりである。このプロシージャはセキュリティのチェックをする働きを担う。

 List 6-113は,呼び出したユーザーが属するロールと,その時点における伝票の状態によって伝票の情報を取得できるかどうかを調べるものである。List 6-113では,次のような規定で伝票を参照できるかどうかを判定している。

  1. COM+のセキュリティ機能が有効に設定にされていない場合には,参照不可とする(11〜14行目)

  2. SalesManagerSalesAdminAllAdminのいずれかのロールに属していれば,すべての伝票を参照可能とする(17〜21行目)

  3. 削除ずみの場合には,参照不可とする(25〜28行目)

  4. Salesロールに属していれば,削除ずみのもの以外はすべての伝票を参照可能とする(31〜34行目)

  5. 承認ずみであれば,製品管理部員を表すProductsロールと,製品管理部の管理者を表すProdutcsAdminロールに属するユーザーは参照可能とする(37〜44行目)

  6. 発送ずみであれば,経理部員を示すAccountingロールと,経理部の管理者を表すAccountingAdminロールに属するユーザーは参照可能とする(46〜53行目)

 以上の判定方法は,おおむね一般的で問題ないと思う。ただ,異存があるとすれば,4.の判定方法であろう。List 6-113Chk_Viewプロシージャでは誰が起票した伝票なのかをチェックしていないため,Salesロールに属するユーザーは他人の伝票であっても参照することができる。しかし,これでは好ましくないケースもあるだろう。その場合には,伝票を承認するまえであれば,起票したユーザーまたはSalesManagerロールに属するユーザーしか参照できないように,Chk_Viewプロシージャに条件を付け加えればよい(承認まえに限る必要はないのだが,承認後も他人はその伝票を参照できないとしたら,製品管理部や経理部のユーザーが仕事を進められない。そのため,承認されたあとも他人に伝票を見せないという設定は無意味であろう)。

 同様にして,請求書処理(List 6-114),承認依頼処理(List 6-115),承認処理(List 6-116),却下処理(List 6-117),発送処理(List 6-118),経理処理(List 6-119)にかかわる情報についても,それぞれ実装する。これらの処理では,GetRecord_Billメソッド(List 6-98),GetRecord_Requestメソッド(List 6-99),GetRecord_Consentedメソッド(List 6-100),GetRecord_Rejectedメソッド(List 6-101),GetRecord_Sendメソッド(List 6-102),GetRecord_Accountingメソッド(List 6-103)をそれぞれ呼び出す。これらのメソッドでも,Chk_Viewプロシージャ(List 6-113)を事前に呼び出し,取得する権限があるかどうかを調査するようにした。

 また,その時点の伝票の状態を示すメソッドも用意しておく。このメソッドは,List 6-106に示したGet_SlipStatusメソッドを呼び出して処理するものとなる(List 6-120)。

 以上で,伝票情報テーブルのレコードにかかわる情報はすべて取得できるようになった。さらに,伝票追加情報テーブルのレコードにかかわる情報も取得できるように,GetSlip_Detailメソッド(List 6-121)とGetSlip_Detailsメソッド(List 6-122)も実装しておく。前者は,DataObj.SlipInformationコンポーネントのGetRececordメソッド(List 6-108)を呼び出し,その時点の伝票に結び付けられている伝票追加情報テーブル内のレコード内容を返すものである。後者は,DataObj.SlipInformationコンポーネントのGetRecordsメソッド(List 6-109)を呼び出し,伝票追加情報テーブルの書き換え履歴を返す。

prevpg.gif Chapter 6 58/92 nextpg.gif