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



6.2.3 顧客情報の削除
●顧客を削除するビジネスロジック
 では,顧客を削除するメソッドをビジネスロジックに加えてゆく。ここでは,Business.Customerコンポーネントに,DeleteCustomerという名前のメソッドとして実装しよう。そのプログラムはList 6-33のようになる。

 List 6-33では,List 6-27に示したDataObj.SlipオブジェクトのIsExistsCustomerメソッドと,List 6-29に示したDataObj.BillオブジェクトのIsExistsCustomerメソッドを呼び出し,削除対象となる顧客を参照している伝票や請求書が存在しないことを確認している。そして,そのような伝票や請求書が存在しないことを確認したら,List 6-31に示したSetDeletedFlagメソッドを呼び出し,DELETEDFLAGフィールドの値をTrueに設定している。


One Point! 厳密にいえば,事前にDataObj.SlipオブジェクトのIsExistsCustomerメソッドやDataObj.BillオブジェクトのIsExistsCustomerメソッドを呼び出し,削除対象となる顧客が伝票や請求書で使われているかどうかを確かめる必要はない。なぜなら,「Chapter 3 データストア層の構築」でデータベースに制約条件を設定しているからである。もし,その制約条件に違反するような操作をデータベースに対して実行しようとすると,データベースエンジン側でエラーが発生するため,トランザクションが全体としてアボートされる。しかし,制約違反によるトランザクションのアボートに処理を委ねてしまうと,(1)制約を設定し忘れたときに問題となることがある,(2)制約設定によるアボートが生じるのかどうかはプログラムリストを見て判断することはできず,メンテナンス面でわかりにくくなる可能性がある,という2点から,List 6-33ではプログラム側でも削除対象となる顧客を参照する伝票や請求書が存在しないことを確認している。

 また,List 6-33では,すでに顧客が削除ずみ(DELETEDFLAGフィールドの値がTrue)のときに呼び出され,かつ,呼び出したユーザーがSalesAdminロールもしくはAllAdminロールに属している場合には,List 6-32に示したDeleteRecordメソッドを呼び出してレコードそのものを削除してしまうようにした(40〜49行目)。これによって,顧客を削除する際,1回目の削除ではDELETEDFLAGフィールドをTrueにするだけであり,さらにもう1回削除すると,そのレコード自身を削除する,という機能を実現できるようになる。

 なお,List 6-33の30行目で使っているErr_CANTDELETE定数は,List 6-9で示したBusinessError列挙型にList 6-34のように加えるものとする。

 ところで,List 6-33では,レコードそのものを削除できるユーザーをSalesAdminロールもしくはAllAdminロールに所属するユーザーに限っている。これに対して,顧客を削除ずみにする処理(DELETEDFLAGフィールドの値をTrueにする処理)は,誰でも実行できるようになっている。しかし,状況によっては,顧客を登録した当事者ユーザーだけが顧客を削除ずみにできるようにしたいこともあるだろう。そのような場合には,顧客を登録するAddRecordメソッド(List 6-2)が顧客情報テーブルのMADEUSERフィールドに作成者のアカウント名を格納することを利用し,たとえば次のような条件文を入れればよい。


Dim old_NAME As Variant, old_YOMIGANA As Variant
Dim old_ZIP As Variant, old_ADDRESS As Variant
Dim old_TELEPHONE As Variant
Dim old_FAX As Variant, old_BILLDAY As Variant
Dim old_MEMO As Variant, old_MADEUSER As Variant
Dim old_MADEDATE As Variant
Dim old_LASTUSER As Variant, old_LASTDATE As Variant
' 現在の情報を取得
objDataCustomer.GetRecord ID, old_NAME, old_YOMIGANA, _
                          old_ZIP, old_ADDRESS, _
                          old_TELEPHONE, old_FAX, _
                          old_BILLDAY, old_MEMO, _
                          old_MADEUSER, old_MADEDATE, _
                          old_LASTUSER, old_LASTDATE
' 顧客を登録したユーザーと呼び出したユーザーが同じかどうか
If old_MADEUSER <> objContext.Security.GetOriginalCallerName() Then
    ' 異なるのでエラー扱いとする
    Err.Raise Err_CANTDELETE, App.Title, "登録者以外は削除できません"
End If

 削除した顧客を復活させるメソッドも,同様の方法で実装できる。UndeleteCustomerという名前のメソッドして実装したものが,List 6-35である。

 List 6-35は,第2引数をFalseにしてList 6-31に示したSetDeletedFlagメソッドを呼び出し,DELETEDFLAGフィールドの値をFalseに設定するというだけのものである。なお,List 6-35では,顧客を復活できるかどうかという権限の判定をプログラム側に実装していない。一般に,削除した顧客を復活できるのは管理者に限りたいから,SalesAdminロールやAllAdminロールに属するユーザーだけに絞りたいだろう。だが,このような判定はCOM+カタログのセキュリティ機構で実現できるため,プログラム側での判定処理は省いた。

 しかし,実際の業務においては,SalesAdminロールやAllAdminロールに属さないユーザーであっても,顧客を削除ずみにした当事者ユーザーに限って,一定時間内ならば復活する処理を許可したいこともあるだろう。そうしておけば,ユーザーが誤操作によって顧客を削除してしまっても,一定時間以内ならば管理者の手を煩わせることなく,その顧客を復旧できるからである。そのようにしたい場合には,顧客情報テーブルのLASTUSERフィールドの内容とメソッドを呼び出したユーザー(ObjectContextオブジェクトから得られるSecurityオブジェクトのGetOriginalCallerNameメソッドで取得できる)を比較し,さらにLASTDATEフィールドと現在時刻とを比較する,というような処理を加えればよいだろう。

prevpg.gif Chapter 6 27/92 nextpg.gif