返金 v1

注文ごとに、返金できる残りを勘定にする。売上で増え、返金で減り、0 より下にはならない。返金は承認を待つあいだ押さえる

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

勘定

勘定分け方単位境界説明
返金できる残り注文 ごと円0 以上。下回る振替は 返金超過 で拒否されるその注文でまだ返金できる額
売上一つだけ円外の勘定。境界は無く、マイナスにもなる
返金済み一つだけ円外の勘定。境界は無く、マイナスにもなる

勘定のあいだの流れ

返金 の勘定のあいだの流れ 売上計上 返金 返金できる残り(注文)円0 以上(返金超過) 売上円・外の勘定 返金済み円・外の勘定

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

振替

売上計上

  • 移動: 売上 から 返金できる残り(注文) へ 額。
  • キー: 注文 ごとに一度だけ動く。同じ呼び出しの二度目は何もせず、done_before を返す。キーが同じで 額 が違う二度目の呼び出しは、key_conflict で拒否される。
  • すぐに動かす(do)。
操作拒否されうる理由いつ
売上計上.dokey_conflict注文 が同じで、ほかの引数が違う呼び出しが、前に済んでいる
拒否される例

売上計上.do: key_conflict

 1  売上計上.do(注文: 注文-1, 額: 1)  通る
 2  売上計上.do(注文: 注文-1, 額: 2)  key_conflict で拒否される

返金

承認を待つあいだ押さえる。承認されたら確定し、却下されたら取り消す

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

返金.hold: 返金超過

 1  返金.hold(申請: 申請-1, 注文: 注文-2, 額: 1)  返金超過 で拒否される(1 つ目の移動が 返金できる残り(注文-2) から 1 を取ろうとしたときの残高は、確定 0、出ていく仮押さえ 0)

返金.hold: key_conflict

 1  売上計上.do(注文: 注文-1, 額: 1)              通る
 2  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 1)  通る
 3  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 2)  key_conflict で拒否される

返金.hold: already_refused

 1  返金.hold(申請: 申請-1, 注文: 注文-2, 額: 1)  返金超過 で拒否される(1 つ目の移動が 返金できる残り(注文-2) から 1 を取ろうとしたときの残高は、確定 0、出ていく仮押さえ 0)
 2  返金.hold(申請: 申請-1, 注文: 注文-2, 額: 1)  already_refused で拒否される

返金.post: key_conflict

 1  売上計上.do(注文: 注文-1, 額: 2)              通る
 2  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 2)  通る
 3  返金.post(申請: 申請-2)                       通る
 4  返金.post(申請: 申請-2, 額: 1)                key_conflict で拒否される

返金.post: already_voided

 1  売上計上.do(注文: 注文-1, 額: 2)              通る
 2  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 2)  通る
 3  返金.void(申請: 申請-2)                       通る
 4  返金.post(申請: 申請-2)                       already_voided で拒否される

返金.post: expired

 1  売上計上.do(注文: 注文-1, 額: 2)              通る
 2  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 2)  通る
 3  pass 7 日                                     返金(申請-2) が期限切れ
 4  返金.post(申請: 申請-2)                       expired で拒否される

返金.post: over_hold

 1  売上計上.do(注文: 注文-1, 額: 2)              通る
 2  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 2)  通る
 3  返金.post(申請: 申請-2, 額: 3)                over_hold で拒否される

返金.post: no_such_hold

 1  返金.post(申請: 申請-1)  no_such_hold で拒否される

返金.void: already_posted

 1  売上計上.do(注文: 注文-1, 額: 2)              通る
 2  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 2)  通る
 3  返金.post(申請: 申請-2)                       通る
 4  返金.void(申請: 申請-2)                       already_posted で拒否される

返金.void: expired

 1  売上計上.do(注文: 注文-1, 額: 2)              通る
 2  返金.hold(申請: 申請-2, 注文: 注文-1, 額: 2)  通る
 3  pass 7 日                                     返金(申請-2) が期限切れ
 4  返金.void(申請: 申請-2)                       expired で拒否される

返金.void: no_such_hold

 1  返金.void(申請: 申請-1)  no_such_hold で拒否される

シナリオ

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

    勘定確定出ていく仮押さえ入ってくる仮押さえ
    仮押さえ状態
    返金 の勘定のあいだの流れ 売上計上 返金 返金できる残り(注文)円0 以上(返金超過) 売上円・外の勘定 返金済み円・外の勘定