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

6.5.2 承認依頼処理
●在庫の予約処理
 「3.2.6 在庫の処理」でも説明したように,伝票を受け付けたならば,伝票の明細に記載されている製品を受注された数量分だけ予約ずみとして確保する。そうしないと,あとから追加した伝票が在庫を利用してしまい,「いざ納入予定日になったら在庫が足りない」という事態に陥りかねないからである。

 このサンプルでは,在庫のうちの予約数は製品情報テーブルのBACKORDERフィールドで管理する。すなわち,伝票を受け付けたならば,伝票の明細に記載されている数量分だけ,製品情報テーブルの該当製品を示すレコードのBACKORDERフィールドの値を加算しなければならない。

 そこで,製品情報テーブルを操作するデータオブジェクトであるDataObj.Productコンポーネントに対し,予約数を加算処理するためのメソッドを実装する。ここでは,このメソッドをAddBackOrderという名前で実装する(List 6-150)。AddBackOrderメソッドは,引数に製品番号と数量をとり,製品情報テーブル中の指定された製品番号を持つレコードのBACKORDERフィールドの値を指定された数量分だけ加算する処理をするものである。

●承認依頼するためのビジネスロジックの実装
 以上で,承認依頼するために必要なデータオブジェクトのメソッドは揃った。次にいままで実装してきたデータオブジェクトのメソッドを組み合わせ,承認依頼処理をするためのメソッドを実装する。承認依頼処理で実施すべき一連の処理は,大まかにいうと次のとおりである(Fig.6-85)。

  1. 伝票のREQ_CONSENTFLAGフィールドの値をTrueにする
     伝票のREQ_CONSENTFLAGフィールドの値をTrueにし,伝票の状態を「承認依頼中」にする。それにはList 6-142で示したDataObj.SlipコンポーネントのSet_REQ_CONSENTFLAGメソッドを使えばよい。

  2. 在庫を調べる
     伝票に付随する明細レコードを調べ,在庫が足りるかどうかをチェックする。伝票に付随するすべての明細レコードを調べるには,List 6-130に示したDataObj.SlipDetailコンポーネントのGetRecordsメソッドを使えばよい(「●明細の一覧取得」を参照)。そして,GetRecordsメソッドで取得した個々の明細レコードのうち,削除ずみでないもの(DELETEDFLAGフィールドがFalseであるもの)に対して在庫が足りるかどうかをチェックする。在庫が足りるかどうかは明細のレコードに記された対象製品の製品番号を利用し,List 6-148に示したGetNowStockメソッドならびにList 6-149に示したGetWillStockメソッドを使えばよい。

  3. 在庫の予約を処理する
     また,個々の明細のレコードに記されている数量だけ在庫を予約ずみとする。それには,List 6-150に示したDataObj.ProductコンポーネントのAddBackOrderメソッドを呼び出せばよい。

 ただし,上記の内容はすべてトランザクション処理として実装するものとし,その順序は問わない。実際にBusiness.SlipコンポーネントにRequestConsentメソッドとして実装したものが,List 6-151である。

Fig.6-85 承認依頼にするための処理
fig6_85

 List 6-151RequestConsentメソッドは,引数に伝票番号と承認依頼時のコメントをとり,指定された伝票の状態を「承認依頼中」に変更する。List 6-151の処理は次のようになっている。

  1. 操作できるかどうかの調査
     まず,事前に指定された伝票を承認依頼の状態にしてよいかどうかを調査する。ここでは,(1)伝票が削除ずみでないこと,(2)伝票の状態が作成中または却下された状態であること,(3)メソッドを呼び出したユーザーに適切な権限があること,という3つの要件を調査する。(1)の要件を調査しているのが33〜36行目,(2)の要件を調査しているのが39〜43行目,(3)の要件を調査しているのが45〜62行目である。ユーザーの権限の調査としては,作成者とメソッドを呼び出したユーザーが一致する,もしくはメソッドを呼び出したユーザーがSalesAdminロールまたはAllAdminロールに属するという条件を課すことにした。

  2. 伝票のフラグを変更する
     操作できるかどうかの調査が終わったら,次に伝票のフラグを操作する。66〜69行目では,REQ_CONSENTFLAGフィールドの値をTrueに設定して伝票の状態を「承認依頼中」にするとともに,REJECTEDFLAGフィールドの値をFalseとし,「却下ずみ」という状態を解除するという処理をしている。これらの処理には,DataObj.SlipコンポーネントのSet_REQ_CONSENTFLAGメソッド(List 6-142)と,DataObj.SlipコンポーネントのSet_REJECTEDFLAGメソッド(List 6-144)を用いている。

  3. 在庫の確認ならびに在庫の予約
     次に,伝票ならびに明細の情報を読み取り,在庫の確認と予約処理をする。そのためにまず,76行目にあるようにDataObj.SlipInformationコンポーネントのGetRecordメソッド(List 6-108)を呼び出し,伝票の納入予定日を取得する。そして81行目にあるようにDataObj.SlipDetailコンポーネントのGetRecordsメソッド(List 6-109)を呼び出し,伝票に結び付けられている明細の一覧をADODB.Recordsetオブジェクトとして取得する。
     89〜114行目は,個々の明細(81行目で取得したADODB.Recordsetオブジェクトの個々のレコード)に対するループ処理となる。ここでは,削除ずみでない明細に対し,(1)在庫数の確認,(2)予約数の追加,という2つの処理をする。
     その処理をするため,まず92行目と93行目において明細のレコードのPRODUCTIDフィールドの値とNUMBERフィールドの値を取得する。前者は明細に記載されている製品番号が,後者はその数量が,それぞれ格納されているフィールドである。そして次に,96行目にあるようにList 6-148に示したDataObj.ProductコンポーネントのGetNowStockメソッドを呼び出し,その時点で利用できる在庫数を取得,さらに99行目にあるようにDataObj.StockコンポーネントのGetWillStockメソッド(List 6-149)を呼び出し,納入予定日までに在庫として増える予定の数量を取得する。このGetNowStockメソッドの戻り値とGetWillStockメソッドの戻り値の合計を,明細に記載されている数量と比較し,足りなければエラーとする。この処理が102〜105行目である。なお細かいことであるが,104行目を見るとわかるように,ユーザーにはわかりやすいエラーメッセージを返すよう,単に「在庫が足りません」ではなく,「どの製品が足りなくて,いくつならば受け付けられるのか」を返すようにした。こうしておけば,ユーザーはどの製品をいくつまでに抑えれば伝票の状態を「承認依頼中」にすることができるかを判断できるようになる。
     在庫の確認が終わったならば,予約数を加える処理をする。この処理は108行目にあり,DataObj.ProductコンポーネントのAddBackOrderメソッド(List 6-150)を呼び出すことによって実現している。


One Point!List 6-151では,在庫の確認と予約数の追加を同じループ内で処理しているが,これを別々のループに分けると,処理を誤るおそれがある。たとえば,製品Aという在庫が20個あり,伝票の明細に,(1)製品Aを10個注文する明細と,(2)製品Aを15個注文する明細,の2つが付属していたとしよう。このとき,同じループ内で在庫の確認と予約数の追加をした場合には,(1)の処理をしたときに在庫の予約数が10個増え,その段階で利用可能な在庫数は20−10=10個となる。よって,次の明細である(2)の処理をしたときに15個の注文を受け付けられないことがわかる。しかし,在庫の確認と在庫の予約数を別の処理にした場合,(1)の処理を実行しても在庫数は20個のまま変わらない。よって(2)の処理は15個の注文となり,在庫不足とならないから受け付けてしまう。このように,在庫を確認した直後に予約数を追加しないと,伝票に同じ製品の明細が複数含まれていたときに,在庫の調査で誤った結果を返すおそれがある。
prevpg.gif Chapter 6 69/92 nextpg.gif