For the complete documentation index, see llms.txt. This page is also available as Markdown.

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)

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(梱包→出荷完了)の既存フローに合流します。

エンドポイント

Method
Path
用途

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 になります(重複適用はされません)。

エラー

エンドポイント固有:

Status
条件
レスポンス例

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 ロケーション列(引当 / 出荷元 / 現在在庫)に反映。注文集計 view public.lm_v_routing_order_unit_fulfillment は source_changing で分類

Last updated

Was this helpful?