Source Change — 出荷元変更
Units の単位が、引当先(出荷元A)では加工できない(例: 刻印は流山でしかできない)ため、別の出荷元B へ物理返送してから B で加工・出荷するケースの管理です。1 単位につき 1 件を起票し、単一の advance エンドポイントで「出荷元の切替 → 返送中 → 受領」を前進させます。
Base URL
https://api.lmile.io· 認証x-ingest-secretヘッダー または operator JWT(Authorization: Bearer)(詳細) ·shopはリクエストボディに含めます(API キーで呼ぶ場合は省略できます)
/api/routing/change-sourceは機械間 secret(x-ingest-secret)と倉庫スタッフの operator JWT のどちらでも呼べます(系統はヘッダの有無で明示判別。詳細)。operator JWT 経由は操作スタッフを記録します(起票 =opened_by_staff_user_id/ 前進・中止 =updated_by_staff_user_id)。
Oversell / Reallocate(同一出荷元内の振替)や Fulfillment の
in_transit_to_mfc(出荷元は変えず現在在庫のみ MFC へ移動)とは別経路です。本 API は出荷元(fulfillment source)そのものを A→B に変え、A→B の返送レグを追跡します。在庫は状態のみ更新しinventory_levelsは変更しません。
ステップ(status)
change_requested
1: 出荷元を A→B に切替(起票)
旧 decision を superseded・新 decision(出荷元=B)を applied/unit を source_change_pending・出荷元=B・引当=B在庫・現在在庫=A のまま/B のヘッダを作成し relink/旧出荷元A へ cancel dispatch/返送便ラベルを自動生成(A の label+return 設定)
return_in_transit
2: A が出庫し返送中
in_transit_at / unit → source_change_in_transit(returnTrackingNumber 上書き可)
return_received
3: B が返送を受領
received_at / 現在在庫を B へ確定・unit → allocated(通常フロー再開)/新出荷元B へ create dispatch
cancelled
中止(任意の非終端から)
cancelled_at / cancel_reason/SoT を起票前の出荷元A へ巻き戻し(WMS への再連絡は運用側 best-effort)
遷移は 1 ステップ前進が基本。cancelled は change_requested / return_in_transit からのみ。return_received / cancelled は終端。それ以外のジャンプは 409 invalid_transition。
return_received で unit が allocated に戻るため、以降は B 側で 在庫確保(/api/routing/secure:加工後の確保→最終出荷ラベル生成)→ Fulfillment(梱包→出荷完了)の既存フローに合流します。
エンドポイント
POST
/api/routing/change-source
出荷元変更の起票 + 前進(単一 advance)
起票済みケースの一覧(送り側の梱包キュー / 受け側の入荷待ちキュー)は Operator Queues の GET /api/operator/source-changes を参照してください。複数の単位を箱単位でまとめて返送する場合は Transfer API(倉庫間移動バルク)を使います — バルクの dispatch / receive は本 API の return_in_transit / return_received と同一の遷移を一括実行します(バルク所属の単位は返送ラベルの夜間バッチ生成から除外されます)。
POST /api/routing/change-source
対象単位の変更が無ければ起票(change_requested)し、あれば指定 status へ前進します。toStatus 省略時は 1 ステップ前進。起票時のみ toSourceLocationId が必須で、対象 unit は secured である必要があります(LM-913: 店舗で確保してから流山転送を起票する物理オペに合わせ、secured のみに一本化。確保前の allocated 起票は廃止)。前回の変更が中止(cancelled)済みの単位は、secured であれば同一行を再オープンして再度起票できます(LM-956。中止後に再び転送が必要になったケース)。
リクエスト
ボディパラメータ
shop
string
✓
店舗ドメイン(API キーで呼ぶ場合は省略できます)
routingOrderId
string (uuid)
△
対象注文。無ければ sourceSystem + externalOrderRef で特定
sourceSystem / externalOrderRef
string
△
routingOrderId 未指定時に必須
fulfillmentUnitId
string (uuid)
△
対象単位。無ければ barcode + lineInstanceNo で特定
barcode / lineInstanceNo
string / number
△
fulfillmentUnitId 未指定時に必須
toSourceLocationId
string (uuid)
△
新出荷元。起票時必須。有効メンバーを持ち、MFC または return_destination_enabled であること
toInventoryLocationId
string (uuid)
新出荷元配下の引当先在庫ロケーション(省略時は最優先メンバー)
mode
string
省略 / transfer = 返送フロー(本ページの既定動作)。switch = 即時切替(下記「mode: switch」参照。同一レグのまま出荷元だけを更新)
toStatus
string
目標 status(省略 = 1 ステップ前進)。change_requested / return_in_transit / return_received / cancelled
tag
string
顧客出荷 dispatch(A への cancel / B への create)の tag
returnTag
string
返送便ラベルの tag(既定 return)。A 拠点の action=label 設定を解決
fields.reason
string
変更理由(例: 刻印は流山のみ)
fields.returnTrackingNumber
string
返送便の追跡番号(自動生成より優先。手動上書き)
fields.returnCarrierCode
string
返送便のキャリアコード
fields.externalShipmentRef
string
返送便の外部出荷 ID
fields.cancelReason
string
中止理由(cancelled 用)
fields.note
string
任意メモ
レスポンス
changeId
出荷元変更 id(sot.lm_fulfillment_source_changes.id)
status
更新後の変更 status
unitStatus
連動して更新された単位の status
fromSource / toSource
旧 / 新 出荷元ロケーション
toInventoryLocationId
新出荷元配下の引当先在庫ロケーション
returnTrackingNumber / returnLabelStatus
返送便の追跡番号 / ラベル生成結果(generated / skipped / failed)
returnLabelPrintStatus
返送ラベルの物理印刷結果(printed / skipped / failed / none)。旧出荷元 A の action=print 設定で印刷(Dispatch Config)。レスポンスのみで行には保存しません
cancelDispatches / createDispatches
A への cancel(起票時)/ B への create(受領時)の dispatch 結果
releasedShelfLinks
起票時に解放した旧出荷元 A の棚紐付け数(secured からの起票で旧ヘッダが空になった場合のみ非 0)
opened
この呼び出しで起票したか(再オープン含む)
reopened
前回 cancelled だった単位を再オープンして起票したか(LM-956)
changed
状態が変化したか(同一 status への再呼び出しは false)
挙動・冪等性
解決キー: 1 単位につき変更 1 件(
shop + fulfillment_unit_idで一意)。初回呼び出しで起票、以降は前進。前回がcancelled(終端)の単位は前進できないため、起票相当として同一行を再オープンします(reopened: true。secured必須。新 decision / 新ヘッダ / 旧ヘッダ cancel / 返送便ラベル生成を起票と同一に再実行し、前回の進行・バルク・チェック・返送ラベル列は初期化)。LM-956。起票(
change_requested): 出荷元を B へ切替(旧 decision をsuperseded・新 decision をapplied)、unit の 3 ロケーション列を更新(現在在庫は返送前=A のまま)、B のヘッダをallocatedで作成し unit を relink、A へcancelを dispatch、A のlabel+returnTag設定で返送便ラベルを自動生成します。対象 unit はsecuredのみ(それ以外は409 unit_not_changeable)。securedからの起票: 確保を解除し(unit のsecured/secured_atをクリア。B 受領でallocatedに復帰後、B で再確保)、unit が抜けて旧出荷元 A のヘッダにアクティブ unit が残らない場合は、A の顧客出荷ヘッダをcancelledに遷移・発行済み配送ラベルを運用破棄マーク(label_voided_at。キャリア void は呼ばず tracking / label 列は監査用に温存)・棚紐付けをreleased_reason="source_changed"で解放します(解放数はレスポンスのreleasedShelfLinks)。旧拠点でピック済みの事実(棚在庫減算済)は温存され、バルク発送時に二重減算しません。返送便ラベルは A 拠点に
action=labelの dispatch 設定が必要(送付先 B の住所はテンプレートに定義)。未設定ならreturnLabelStatus: "skipped"。fields.returnTrackingNumberを渡すと自動生成より優先します。受領(
return_received): 現在在庫を B へ確定し unit をallocatedに戻して B へcreateを dispatch。以降の確保・最終出荷ラベルは/api/routing/secure(B の設定)で生成します。中止(
cancelled): SoT(出荷元・引当・現在在庫・decision・unit)を起票前の A へ巻き戻します。WMS への再連絡(A への再開・B への取消)は運用側 best-effort(dispatch しません)。単位の
properties(明細単位の任意キー/値 = Routing のlines[].properties)は新 decision へ引き継がれ、A への cancel / B への create の dispatch payload と返送指示の明細にも含まれます。同一 status への再呼び出しは
changed: falseの no-op。在庫は状態のみでinventory_levelsは不変。
mode: "switch"(即時切替・同一レグ)
物理的な返送を伴わず、データ上の出荷元だけを付け替えたい場合の動作です。変更ケース(lm_fulfillment_source_changes)を起票せず、旧レグの取消も新レグの作成もしません — 出荷レグ(shipment)と単位(unit)は同じ id のまま、出荷元・引当ロケーションが新拠点へ更新されます。現物の移動は運用側の対応です。
対象単位:
allocatedまたはsecured、かつ未ピック(それ以外は409 unit_not_switchable)。進行中の返送ケースを持つ単位は対象外(409 transfer_in_progress— 返送フロー側で前進/中止してください)。対象レグ: 切替はレグ(shipment)のヘッダごと新拠点へ移すため、同一レグに他の active な単位がある場合(複数明細・同一商品×複数点)は
409 shipment_has_siblings、MFC 集約グループ(1箱=1注文)に属するレグは409 consolidation_group_memberになります。いずれも従来の返送フロー(transfer)を使ってください。新出荷元の適格性は
transferと同一(有効メンバー + MFC /return_destination_enabled)。起きること: 新 decision の記録(旧は
superseded)→ unit の出荷元 / 引当 / 現在在庫ロケーションを新拠点へ更新(securedは解除しallocatedへ)→ 同一レグの引当拠点を更新・集約棚を解放 → 旧拠点の棚紐付けを解放 → 旧出荷元 WMS へcancel・新出荷元 WMS へcreateを dispatch(いずれも best-effort。返送フローの受領と同じ)→ 新拠点が自己在庫なら割当保管棚を再分配 → 新旧両拠点の自己在庫 available を再計算 → 切替先の確保待ち通知イベント(store_secure_pending_assigned)を発火 → タイムライン(メモ)に変更履歴を記録。発行済みの配送ラベルが載っている場合はレスポンスに
requiresLabelReissue: trueが返ります(旧出荷元の契約で発行済みのため、ラベル再発行が必要)。レスポンス例:
{ "ok": true, "mode": "switch", "shipmentId": "...", "fromSourceLocationId": "...", "toSourceLocationId": "...", "toInventoryLocationId": "...", "unsecured": true, "requiresLabelReissue": false, ... }再実行: 切替完了後に同じボディを再送すると、新旧が同一になるため
422 same_sourceになります(重複適用はされません)。
エラー
エンドポイント固有:
400
注文・単位の特定情報なし / 起票で toSourceLocationId 欠落
{ "ok": false, "error_kind": "invalid_input", "error": "toSourceLocationId required to open a source change" }
404
注文・単位が存在しない
{ "ok": false, "error_kind": "unit_not_found", "error": "fulfillment unit not found for order" }
409
単位が secured でない(確保が先)/ 不正なステップ遷移
{ "ok": false, "error_kind": "unit_not_changeable", "error": "unit must be 'secured' to change source — secure it first (current: allocated)" }
409
mode=switch: 単位が allocated / secured 以外・ピック済み
{ "ok": false, "error_kind": "unit_not_switchable", "error": "unit is already picked — switch is only allowed before pick" }
409
mode=switch: 進行中の返送ケースがある
{ "ok": false, "error_kind": "transfer_in_progress", "error": "unit has an open source-change case (change_requested) — advance or cancel it instead" }
409
mode=switch: 同一レグに他の active 単位がある
{ "ok": false, "error_kind": "shipment_has_siblings", "error": "shipment has 1 other active unit(s) — in-place switch supports single-unit legs only (use the transfer flow)" }
409
mode=switch: MFC 集約グループのレグ
{ "ok": false, "error_kind": "consolidation_group_member", "error": "shipment belongs to an MFC consolidation group — use the transfer flow (in-place switch would break the box grouping)" }
422
新出荷元が同一 / 未解決 / メンバーなし / 返送先でない / 指定在庫がメンバー外
{ "ok": false, "error_kind": "not_a_return_destination", "error": "target source is neither an MFC nor return_destination_enabled" }
共通エラー(401 / 400 / 403 / 405 / 500 / 503)は Error Codes を参照。
A への cancel / B への create dispatch は WMS 設定が無ければ
skipped(cancelDispatches/createDispatches配列で返却。silent skip しません)。
データモデル
sot.lm_fulfillment_source_changes— 1 件 = 1 単位(UNIQUE shop + fulfillment_unit_id)。status(3 ステップ +cancelled)/from_source_location_id/to_source_location_id/from_inventory_location_id/to_inventory_location_id/return_tracking_number/return_label_pdf_path/reason+ 各ステップ timestamp。fulfillment_unit_id(Units)とrouting_decision_idにリンク。読み取り view:public.lm_v_fulfillment_source_changes単位の状態は
sot.lm_fulfillment_units.status(source_change_pending/source_change_in_transit、受領でallocatedに復帰)と 3 ロケーション列(引当 / 出荷元 / 現在在庫)に反映。注文集計 viewpublic.lm_v_routing_order_unit_fulfillmentはsource_changingで分類
Last updated
Was this helpful?