在庫の引当 v1

SKU ごとの在庫。入荷で増え、注文のために 30 分押さえ、出荷で確定し、キャンセルで取り消す。返品は棚に戻す

chobo doc が examples/inventory/inventory.ja.book から作ったページ。勘定ごとに残高を持ち、残高は入った量から出た量を引いたもの。どの振替も勘定の下限と上限を守り、守れない振替は、その境界に付けた名前で拒否されて、どの移動も行われない。振替には、すぐに動かすもの(do)と、動かす量をまず押さえるもの(hold)がある。押さえた分は、あとで確定される(post。全部か一部)か、取り消される(void)か、有効期限で切れる。

勘定

勘定分け方単位境界説明
在庫sku ごと個0 以上。下回る振替は 在庫切れ で拒否される倉庫の棚にある数
仕入先一つだけ個外の勘定。境界は無く、マイナスにもなる
客一つだけ個外の勘定。境界は無く、マイナスにもなる

勘定のあいだの流れ

在庫の引当 の勘定のあいだの流れ 入荷 引当 返品 在庫(sku)個0 以上(在庫切れ) 仕入先個・外の勘定 客個・外の勘定

四角は勘定で、矢印は振替の移動。角の丸い破線の四角は外の勘定で、境界を持たない。破線の矢印は仮押さえの振替で、まず押さえ、確定したときに動く。

振替

入荷

  • 移動: 仕入先 から 在庫(sku) へ 数。
  • キー: 納品書 と sku の組ごとに一度だけ動く。同じ呼び出しの二度目は何もせず、done_before を返す。キーが同じで 数 が違う二度目の呼び出しは、key_conflict で拒否される。
  • すぐに動かす(do)。
操作拒否されうる理由いつ
入荷.dokey_conflict納品書 と sku が同じで、ほかの引数が違う呼び出しが、前に済んでいる
拒否される例

入荷.do: key_conflict

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 1)  通る
 2  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 2)  key_conflict で拒否される

引当

出荷で確定し、キャンセルで取り消す

  • 移動: 在庫(sku) から 客 へ 数。
  • キー: 注文 と sku の組ごとに一度だけ動く。同じ呼び出しの二度目は何もせず、done_before を返す。キーが同じで 数 が違う二度目の呼び出しは、key_conflict で拒否される。仮押さえが終わったあとに同じキーでもう一度押さえると、done_before を返し、何も押さえない。
  • 仮押さえ: まず押さえる。確定と取消は呼ぶ側がする。押さえてから 30 分で期限が切れ、押さえた量は元に戻る。
引当.hold 押さえ中 確定(post) 確定 取消は already_posted で拒否される 違う額の確定は key_conflict で拒否される 取消(void) 取消 確定は already_voided で拒否される 30 分たつ 期限切れ 確定も取消も expired で拒否される
仮押さえの状態post(確定)void(取消)
押さえ中確定する。額を渡せばその額、渡さなければ全額で、残りは元に戻る。押さえた額を超えれば over_hold で拒否される。押さえてから 30 分たっていれば expired で拒否される取り消す。押さえた量は元に戻る。押さえてから 30 分たっていれば expired で拒否される
確定同じ額なら done_before、違う額なら key_conflict で拒否されるalready_posted で拒否される
取消already_voided で拒否されるdone_before
期限切れexpired で拒否されるexpired で拒否される
仮押さえが無いno_such_hold で拒否されるno_such_hold で拒否される
操作拒否されうる理由いつ
引当.hold在庫切れ在庫(sku) が 0 を下回る
引当.holdkey_conflict注文 と sku が同じで、ほかの引数が違う呼び出しが、前に済んでいる
引当.holdalready_refused注文 と sku が同じ呼び出しが、前に境界で拒否されている。境界で拒否されたキーは、あとで足りるようになっても通らない
引当.postkey_conflict仮押さえは、違う額で確定済み
引当.postalready_voided仮押さえはもう取り消されている
引当.postexpired仮押さえの期限が切れている
引当.postover_hold押さえた額より多く確定しようとした
引当.postno_such_holdその 注文 と sku の仮押さえが無い
引当.voidalready_posted仮押さえはもう確定している
引当.voidexpired仮押さえの期限が切れている
引当.voidno_such_holdその 注文 と sku の仮押さえが無い
拒否される例

引当.hold: 在庫切れ

 1  引当.hold(注文: 注文-1, sku: sku-2, 数: 1)  在庫切れ で拒否される(1 つ目の移動が 在庫(sku-2) から 1 を取ろうとしたときの残高は、確定 0、出ていく仮押さえ 0)

引当.hold: key_conflict

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 1)  通る
 2  引当.hold(注文: 注文-3, sku: sku-2, 数: 1)    通る
 3  引当.hold(注文: 注文-3, sku: sku-2, 数: 2)    key_conflict で拒否される

引当.hold: already_refused

 1  引当.hold(注文: 注文-1, sku: sku-2, 数: 1)  在庫切れ で拒否される(1 つ目の移動が 在庫(sku-2) から 1 を取ろうとしたときの残高は、確定 0、出ていく仮押さえ 0)
 2  引当.hold(注文: 注文-1, sku: sku-2, 数: 1)  already_refused で拒否される

引当.post: key_conflict

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 2)  通る
 2  引当.hold(注文: 注文-3, sku: sku-2, 数: 2)    通る
 3  引当.post(注文: 注文-3, sku: sku-2)           通る
 4  引当.post(注文: 注文-3, sku: sku-2, 数: 1)    key_conflict で拒否される

引当.post: already_voided

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 2)  通る
 2  引当.hold(注文: 注文-3, sku: sku-2, 数: 2)    通る
 3  引当.void(注文: 注文-3, sku: sku-2)           通る
 4  引当.post(注文: 注文-3, sku: sku-2)           already_voided で拒否される

引当.post: expired

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 2)  通る
 2  引当.hold(注文: 注文-3, sku: sku-2, 数: 2)    通る
 3  pass 30 分                                    引当(注文-3, sku-2) が期限切れ
 4  引当.post(注文: 注文-3, sku: sku-2)           expired で拒否される

引当.post: over_hold

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 2)  通る
 2  引当.hold(注文: 注文-3, sku: sku-2, 数: 2)    通る
 3  引当.post(注文: 注文-3, sku: sku-2, 数: 3)    over_hold で拒否される

引当.post: no_such_hold

 1  引当.post(注文: 注文-1, sku: sku-2)  no_such_hold で拒否される

引当.void: already_posted

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 2)  通る
 2  引当.hold(注文: 注文-3, sku: sku-2, 数: 2)    通る
 3  引当.post(注文: 注文-3, sku: sku-2)           通る
 4  引当.void(注文: 注文-3, sku: sku-2)           already_posted で拒否される

引当.void: expired

 1  入荷.do(納品書: 納品書-1, sku: sku-2, 数: 2)  通る
 2  引当.hold(注文: 注文-3, sku: sku-2, 数: 2)    通る
 3  pass 30 分                                    引当(注文-3, sku-2) が期限切れ
 4  引当.void(注文: 注文-3, sku: sku-2)           expired で拒否される

引当.void: no_such_hold

 1  引当.void(注文: 注文-1, sku: sku-2)  no_such_hold で拒否される

返品

客から返ってきた品を棚に戻す

  • 移動: 客 から 在庫(sku) へ 数。
  • キー: 返品番号 と sku の組ごとに一度だけ動く。同じ呼び出しの二度目は何もせず、done_before を返す。キーが同じで 数 が違う二度目の呼び出しは、key_conflict で拒否される。
  • すぐに動かす(do)。
操作拒否されうる理由いつ
返品.dokey_conflict返品番号 と sku が同じで、ほかの引数が違う呼び出しが、前に済んでいる
拒否される例

返品.do: key_conflict

 1  返品.do(返品番号: 返品番号-1, sku: sku-2, 数: 1)  通る
 2  返品.do(返品番号: 返品番号-1, sku: sku-2, 数: 2)  key_conflict で拒否される

シナリオ

chobo scenarios が帳簿から作ったシナリオ 21 本。一つ選び、ステップを一つずつ進めると、そのあとの残高と仮押さえが見られる。図では、そのステップで呼んだ振替の矢印に色が付く(拒否されたものは赤)。

    勘定確定出ていく仮押さえ入ってくる仮押さえ
    仮押さえ状態
    在庫の引当 の勘定のあいだの流れ 入荷 引当 返品 在庫(sku)個0 以上(在庫切れ) 仕入先個・外の勘定 客個・外の勘定