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

head2.gif 6.4.5 伝票情報の削除
 最後に,伝票情報を削除するメソッドについて考える。

○伝票を削除するデータオブジェクトのメソッド
 ではまず,伝票を削除するデータオブジェクトのメソッドから実装してゆく。伝票を削除する場合,DELETEDFLAGフィールドをTrueにして削除扱いにするケースと,レコードそのものを削除してしまうケースの2通りがある。前者のメソッドをSetDeletedFlag,後者のメソッドをDeleteRecordとしてDataObj.Slipコンポーネントに実装したものが,List 6-136List 6-137である。SetDeletedFlagメソッドのほうは,DELETEDFLAGフィールドをTrueにするのかFalseにするのかを引数で指定できるようになっている。削除ずみにしたいのであればTrueを指定し,すでに削除ずみにしたものを復活させたい場合にはFalseを指定する。

 ところで,伝票を削除するときには,それに付随する伝票追加情報レコードと明細情報レコードも削除しなければならない。そこで,DataObj.SlipInformationコンポーネントとDataObj.SlipDetailコンポーネントのそれぞれにList 6-138List 6-139に示すDeleteRecordメソッドを実装しておく。

 DataObj.SlipInformationコンポーネントのDeletedRecordメソッド(List 6-138)は,引数に伝票番号をとり,その伝票番号に結び付けられている伝票追加情報テーブル中のレコードを削除する。すでにFig.6-77にも示したように,伝票レコードと伝票追加情報レコードとは1対多の関係になる。ここでは,結び付けられているすべてのレコードを削除するように実装した。

 DataObj.SlipDetailコンポーネントのDeletedRecordメソッド(List 6-139)は,引数に伝票番号をとり,その伝票番号に結び付けられている明細情報テーブル中のレコードを削除する。明細情報レコードも伝票レコードに対して1対多の関係になるわけだが,結び付けられているすべてのレコードを削除するよう実装してある。

 なお,List 6-138List 6-139ではレコードそのものを実際に削除するわけだが,その際DataObj.Historyコンポーネントを使って履歴を残す処理は実装していない。これは,(1)伝票の明細や伝票の追加情報は1つの伝票に対して複数割り当てられることがあるため,逐一履歴をとると長くなる傾向がある,(2)List 6-137で示したDataObj.SlipコンポーネントのDeleteRecordメソッドではDataObj.Historyコンポーネントを使って伝票そのものが削除されたという履歴を残しているので,明細や追加情報が削除されたことまで記録しなくても実用上問題ない,という判断からである。

○伝票を削除するビジネスコンポーネントのメソッド
 次に,伝票を削除するビジネスコンポーネントのメソッドについて考える。顧客情報や製品情報の削除と同様に,伝票の削除でも1度目の削除ではDELETEDFLAGフィールドをTrueにして削除ずみにするだけ,2度目の削除でそのレコードそのものを削除するという2段階の削除形態をとる。ただし,レコードそのものを削除できるのは,SalesAdminロールかAllAdminロールに属するユーザーに制限する。また,伝票のレコードが削除されたときには,それに付随する明細情報と伝票追加情報も削除する。


One Point! 伝票のレコードが削除されたときには,それに付随する明細情報のレコード,伝票追加情報のレコードを削除するが,伝票のレコードが削除ずみにされたとき(DELETEDFLAGフィールドがTrueになったとき)には,明細情報のレコード,伝票追加情報のレコードのそれぞれに対してDELETEDFLAGフィールドの値をTrueにし,削除ずみにするという操作はしない。明細情報のレコードのDELETEDFLAGフィールドは伝票に付随する明細そのものが削除ずみであるかを示すのに使われている。よって,伝票が削除ずみになったときに明細情報レコードのDELETEDFLAGフィールドの値をTrueにしてしまうと,それはユーザーが明細を削除したためにDELETEDFLAGフィールドがTrueになったのか,伝票が削除ずみになったためにDELETEDFLAGフィールドがTrueになったのかの区別がつかず,後述するList 6-141UndeleteSlipメソッドでレコードを復活させるときに,明細情報のどのレコードを復活させるべきなのかの区別がつかなくなるためである(伝票追加情報レコードについても同様である)。

 ところで,伝票の削除はいつでもできるという処理ではない。発送段階まで進んだにもかかわらず伝票を削除してしまったのでは在庫の数が合わなくなるおそがあるし,経理段階まで進んで削除したのでは,伝票がない請求書が作られてしまうおそれがある。そこで,このサンプルでは伝票が作成中のときだけ伝票を削除できるように実装する。伝票が作成中であるということは,より正確にいえば,伝票の状態がList 6-105に示したSlipStatus列挙型のCreatingRejectedRequestingContentのいずれかである場合のことを示す。いい換えれば,承認されるまえの伝票に限るということである。このように実装した場合,承認された伝票は絶対に削除できないということになり得るが,「6.5 伝票の遷移」では承認ずみとした伝票を承認まえの状態に戻すというメソッドを実装する予定である。そのため,承認ずみとした伝票を削除したい場合にも,いったん承認まえの状態に戻してから削除することで解決できる。

 また,伝票は誰でも削除できるという処理ではなく,起票者のみが削除できるようにすべきである。ただし,起票者が異動した場合のことなどを考えると,営業部の管理者であるSalesAdminロールと,すべての管理者であるAllAdminロールに属するユーザーには,削除の権限を与えたほうがよいだろう(営業部の上司であるSalesManagerロールにも削除権限を与えてもよいが,伝票を削除した場合にはその伝票が見えなくなってしまうために,上司が伝票を削除したという事実を起票者が知りづらくなる。そのため,このサンプルではSalesManagerロールには削除権限を与えないことにする)。

 実際に伝票を削除するメソッドをDeleteSlipという名前でBusiness.Slipコンポーネントに実装してみよう(List 6-140)。

 List 6-140では,まず31〜33行目の処理において伝票が承認されていないことを確認している。次に36行目では,その時点で伝票が削除されていないのか,削除ずみなのか,レコードそのものが存在していないのかを調査している。

 伝票が削除されていなければ,41〜53行目の処理に入る。41〜53行目の処理では,伝票を削除する権限があるかどうかを確かめたのち,List 6-136で示したDataObj.SlipコンポーネントのSetDeletedFlagメソッドを呼び出し,その伝票のDELETEDFLAGフィールドをTrueにするという処理をしている。

 伝票が削除ずみであれば,55〜73行目の処理に移る。55〜73行目の処理では,メソッドを呼び出したユーザーがSalesAdminロールまたはAllAdminロールに属するか否かを調べ,DataObj.SlipInformationコンポーネントのDeleteRecordメソッド(List 6-138),DataObj.SlipDetailコンポーネントのDeleteRecordメソッド(List 6-139),DataObj.SlipコンポーネントのDeleteRecordメソッド(List 6-137)を順に呼び出し,伝票追加情報レコード,明細情報レコード,伝票そのもののレコードを削除している。


One Point! 細かいことだが,伝票追加情報レコードと明細情報レコードを削除するまえに伝票そのもののレコードを削除すると,「3.4.3 リレーションシップを定義する」で設定したリレーションシップに違反してエラーが発生する。

 ところで,誤操作によって伝票が削除されてしまうこともあるため,削除した伝票を復活させるメソッドも必要になるだろう。削除した伝票を復活させるには,その伝票のDELETEDFLAGフィールドの値をFalseにすればよい。このメソッドをUndeleteSlipという名前で実装すると,List 6-141のようになる。

 伝票は,CUSTOMERIDフィールドの値を通じて顧客情報テーブルのレコードを参照している(Fig.6-82)。そのため,伝票を復活させるためには,CUSTOMERIDフィールドに格納されている顧客番号に対応する顧客が顧客情報テーブルに登録されていなければならない。そのため,List 6-141では22〜29行目にあるようにDataObj.CustomerコンポーネントのIsDeletedメソッド(List 6-23)を使い,顧客が存在するかどうかを調べている。顧客が存在しているのを確認したら,あとはList 6-136に示したDataObj.SlipコンポーネントのSetDeletedFlagメソッドを呼び出し,伝票を復活させるだけである(32行目)。

Fig.6-82 テーブルの連携図
fig6_82

 ところで,List 6-141ではロールによるセキュリティを検査していない。一般に伝票を復活することができるのは,管理者であるSalesAdminロールかAllAdminロールに属するユーザーに制限するべきである。この制限はプログラム側に実装するのではなく,[コンポーネント]管理ツール側で設定するものとする。

●次回予告
 今回は伝票の登録ならびに編集操作について主に説明した。伝票は明細が入り込むので少々実装しなければならないメソッドが多くなるが,基本的な操作はさして難しいことはない。次回は,伝票を営業部から製品管理部に,製品管理部から経理部に回す処理を実装してゆく予定である。

prevpg.gif Chapter 6 65/92 nextpg.gif