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



6.4.4 伝票情報一覧の取得
●伝票情報一覧を返すビジネスコンポーネントのメソッド
 次に,伝票情報の一覧を返すメソッドをビジネスコンポーネントに実装する。このメソッドは,基本的にはDataObj.SlipコンポーネントのGetRecordsメソッド(List 6-133)を呼び出すものだが,ロールを判定する必要があるため,そう単純にはゆかない。たとえば,製品管理部のユーザーに未承認の伝票を参照させるべきではないし,経理部のユーザーに未発送の伝票を参照させるべきではない。つまり,ユーザーが属するロールによって,参照できる伝票の種類を制限する必要があるということだ。

 各ロールごとにどのような制限が必要かを考えてみると,次のようになる。

Salesロール,SalesManagerロール
 SalesロールとSalesManagerロールは,営業部に所属することを示す。削除された伝票を参照できない以外,営業部のメンバには伝票の参照にあたって特に制限を課さないことにする。「伝票が承認されるまえは自分が作成した伝票しか参照できない」といった制限は実用上有用であると考えられるが,今回はそのような制限を設けないことにする。
 
SalesAdminロール
 SalesAdminロールは,営業部の管理者を示す。基本的にはSalesロールやSalesManagerロールと同じだが,削除された伝票も参照できるようにする。つまり,何も制限を課さないことにする。
 
Productsロール
 Productsロールは,製品管理部に所属することを示す。製品管理部のメンバには,営業部側で承認ずみである伝票しか参照させたくない。そのためには,GetRecordsメソッドのfilterSlip引数で,FILTER_SLIP_CREATINGFILTER_SLIP_REJECTEDFILTER_SLIP_REQUESTINGCONSENTを指定させないように制限すればよい。また,削除ずみの伝票は参照できないようにする。
 
ProductsAdminロール
 ProeuctsAdminロールは,製品管理部の管理者を示す。基本的にProductsロールと同様だが,削除ずみの伝票も参照できるようにする。
 
Accountingロール
 AccountingロールやAccountingAdminロールは,経理部に所属することを示す。経理部のメンバには,製品管理部で発送ずみの伝票しか参照させたくない。そのためには,GetRecordsメソッドのfilterSlip引数で,FILTER_SLIP_CREATINGFILTER_SLIP_REJECTEDFILTER_SLIP_REQUESTINGCONSENTFILTER_SLIP_CONSENTEDを指定されないように制限すればよい。また,削除ずみの伝票は参照できないようにする。
 
AccountingAdminロール
 AccountingAminロールは,経理部の管理者を示す。Accountingロールと同じだが,削除ずみの伝票も参照できるようにする。
 
AllAdminロール
 AllAdminロールは,すべての権限を持つ管理者である。よって,特に制限は課さないことにする。

 以上の制限を課すメソッドをBusiness.SlipコンポーネントにGetSlipsという名前で実装したものが,List 6-135である。

 List 6-135において,制限を課している部分は31〜55行目である。このうちfilterSlip引数を制限しているのが,31〜49行目の処理である。まず,AllAdminSalesAdminSalesManagerSalesのいずれのロールにも属さなかった場合には,44行目にある次の文が実行される。

filterSlip = filterSlip And _
            (Not (FILTER_SLIP_CREATING Or _
             FILTER_SLIP_REJECTED Or FILTER_SLIP_REQUESTINGCONSENT))

 この文が実行されることによって,filterSlip引数から,FILTER_SLIP_CREATINGFILTER_SLIP_REJECTEDFILTER_SLIP_REQUESTINGCONSENTの指定が除外される。

 論理演算を含んでいるので,ここでビット単位で見てゆくことにしよう。FILTER_SLIP_CREATINGFILTER_SLIP_REJECTEDFILTER_SLIP_REQUESTINGCONSENTの値を2進数で示したときの値は,次のようになる(List 6-132を参照)。

FILTER_SLIP_CREATING = 00000001
FILTER_SLIP_REJECTED = 00000010
FILTER_SLIP_REQUESTINGCONSENT = 00000100

 よって,“FILTER_SLIP_CREATING Or FILTER_SLIP_REJECTED Or FILTER_SLIP_REQUESTINGCONSENT”の値を2進数で示すと,00000111となる。これをNOT演算した結果は,11111000である。すなわち,44行目のfilterSlip変数は次の演算と同じである。

filterSlip = filterSlip And 11111000
(ここではわかりやすくするために2進数で記述したが,
 Visual Basicはこの表記を直接は受け付けない)

 つまり,FILTER_SLIP_CREATINGFILTER_SLIP_REJECTEDFILTER_SLIP_REQUESTINGCONSENTの指定がfilterSlip変数から取り除かれることになる。このような「ある値のNOTをとってそれとAND演算し,値を取り除く」という処理は論理演算でよく使用されるので,覚えておくとよいだろう。

 ProductsロールやProductsAdminロールに関する処理も同様である。45行目でProductsロールにもProductsAdminロールにも属していないことがわかったら,47行目のようにしてFILTER_SLIP_CONSENTEDの指定を取り除いている。

 以上の処理によって,ロールに応じて制限を課すことができる。なお,51〜54行目では,AllAdminSalesAdminProductsAdminAccountingAdminというどのロールにも属していなければ,IncludeDeleted引数を強制的にFalseへと設定する。この処理については,特に説明する必要はないだろう。

 ところで,細かい点ではあるが,ロールを判定するときには1人が複数のロールに属している可能性がある点にも注意してほしい。たとえば,45〜47行目では,ProductsロールにもProductsAdminロールにも属していなければ,filterSlip引数からFILTER_SLIP_CONSENTEDの指定を取り除くようになっている。この処理の条件部分は,次のように「AccountingロールまたはAccountingAdminロールに属していれば」という条件に置き換えることもできる。

If objContext.IsCallerInRole("Accounting") Or _
   objContext.IsCallerInRole("AccountingAdmin") Then

 しかし,このような条件に置き換えた場合,あるユーザーがAccountingロールとProductsロールの両方に所属する場合,挙動が変わってくる。もとの44行目の状態では,ユーザーがProductsロールに属するという条件を満たすから,結果は偽になり,FILTER_SLIP_CONSENTEDの指定を取り除く処理は実行されない。しかし,上記のように置き換えた場合には,Accountingロールに属するという条件が満たされるので,結果は真となり,FILTER_SLIP_CONSENTEDの指定を取り除く処理が実行されることになる。

 このように,ロールを評価する条件式や順序によって,あるユーザーが複数のロールに所属するときの挙動が変わってくる。この点には十分注意してほしい。

prevpg.gif Chapter 6 64/92 nextpg.gif