受注時の個別在庫移動を廃止し、リクエスト → 承認 → 出庫 → 入庫 の業務フローに載せ替える。あわせて「会社のどこに在庫があるか」を受注確定の場で見えるようにする。
受注を打つタイミングで個別に倉庫移動ができるが、なぜ個別に行うのかが不明。
調査結果: 受注画面の在庫移動は、伝票を draft で作った直後に出庫確定と入庫完了を同一リクエスト内で連続実行していた。in_transit(移動中)を一切経由せず完了まで飛ぶ。
$transfer = WarehouseTransfer::create([...'status' => 'draft']);
WarehouseTransferItem::create([...]);
$transfer->confirmToInTransit($userId); // 即
$transfer->confirmToCompleted($userId); // 即
承認も現場の出庫作業も介在しない、正式フローの裏口になっている。倉庫移動というより即時の在庫付け替え。「元に戻す」も取消ではなく逆方向の移動を新規作成する実装で、伝票が2件残る。
一括受注確定画面に出るのは、その受注の出荷倉庫の有効残数のみ。足りないときに「どこかから移動できる可能性があるか」が判断できない。
やりたいこと: 有効残数が足りない場合に限り、会社全体で在庫があるかを見せる。理想は「どの倉庫にいくつあるか」まで。
draft → in_transit → completed は実装済み。shipped_by / received_by も記録されるfrom から減算、入庫時に to へ加算Stock::effectiveQuantity() = 実在庫 − 未消込outbound予約 + 未消込inbound予約。単一倉庫のみを対象InventoryReservation を一切作らない出庫で from から減り、入庫で to に入る。その間、在庫はどの倉庫にも存在しない。会社の総在庫が一時的に減る。
受け皿として「移動中」という倉庫が作られていたが、これは倉庫マスタに物理拠点と状態が混在する構造で、しかも中身がどこ行きなのか辿れない。今回これを廃止する。
draft で作られる。同じ from / to のリクエストはまとめて1伝票にできる。却下も履歴に残る。
from に outbound 予約、to に inbound 予約が張られる。実在庫は動かさない。
移動中の在庫は from 倉庫に物理的に残したまま、予約で有効残数を動かす。「移動中」倉庫は使わない。
| 状態 | stocks(実在庫) | 予約 | 有効残数への影響 |
|---|---|---|---|
draft |
動かない | なし | なし |
in_transit |
動かない(from に置いたまま) | from に outbound to に inbound |
from が減り、to が増える |
completed |
from −出庫数 to +入庫数 |
両方とも消込 | 実在庫に置き換わる |
Stock::effectiveQuantity() は既に 実在庫 − 未消込outbound + 未消込inbound なので、計算式は無改修。source_type に warehouse_transfer_item を足すだけで乗る。発注の入荷予約と全く同じ構造。
結果として、from の有効残数は出庫時点で即引かれ、to には「間もなく着く分」が見え、会社の総在庫は移動中も正しいままになる。
transfer_requests 新規id
company_id
product_id
from_warehouse_id 移動元
to_warehouse_id 移動先
quantity 依頼数
requested_by 依頼者
sales_order_id 任意 — どの受注発の依頼か
status pending | approved | rejected
warehouse_transfer_id 承認後に紐づく(複数リクエスト → 1伝票)
reject_reason
timestamps
warehouse_transfer_items カラム追加quantity 予定数(承認時に確定)
quantity_shipped 実出庫数 ← 新規
quantity_received 実入庫数 ← 新規
ブレ = quantity_shipped − quantity_received
この3カラム構成は、発注の quantity / quantity_received と同型。UIも実装も揃う。
現行は既に warehouse_transfers の1レコードをステータスで進める形になっており、伝票が2つ生成されているわけではない。ブレの記録は上記の明細カラムで足りるため、1伝票のままとする。
有効残数が不足している行にのみバッジを出し、クリックで倉庫別の在庫を展開する。足りている行には何も出さない。
商品A 受注100 有効残数 20 ⚠
└ [他倉庫に 350 あり] ←クリックで展開
会津 200個 [リクエスト]
中部工場 120個 [リクエスト]
東京 30個 [リクエスト]
商品B 受注50 有効残数 800 ←足りているので何も出ない
既存の個別即時移動(在庫移動フォーム・元に戻すボタン)は撤去し、この導線に置き換える。
調達チーム向け。pending のリクエスト一覧から、同じ from / to をまとめて選択し、1つの移動伝票(draft)として承認する。却下は理由とともに履歴に残す。
draft で出庫確定、in_transit で実入庫数を入力して完了。出庫数と入庫数にブレがある場合は明示する。
transfer_requests 新設、明細に出庫数 / 入庫数を追加、ステータスを定数化(現在は生文字列)confirmToInTransit() の意味が「在庫を減らす」から「予約を張る」に変わる。この領域は現在テストが1件も無いため、テストを先に置いてから着手する。| 論点 | 結論 | 理由 |
|---|---|---|
| 移動中の表現 | 伝票ステータス | 倉庫マスタに物理拠点と状態が混在するのを避ける。from / to が伝票に載るので「どこからどこへ、いくつ」が辿れる |
| 移動中の在庫 | from に残して予約で引く | 会社の総在庫が移動中も正しい。既存の有効残数の式を変えずに済む |
| リクエストの持ち方 | 別テーブル | 複数リクエストを1伝票にまとめられる。却下も履歴に残る |
| 出庫 / 入庫の伝票 | 1伝票のまま | 現行が既に1レコード。ブレは明細カラムで表現できる |
| 他倉庫の表示 | 不足時のみ展開 | 必要なときだけ情報が出る。集計も不足行だけで済む |
| 個別即時移動 | 撤去 | 承認も出庫作業も経ない裏口。リクエスト導線に置き換える |