> For the complete documentation index, see [llms.txt](https://lmile.gitbook.io/lmile-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lmile.gitbook.io/lmile-docs/oversell-api/cases.md).

# Oversell Cases — 売越しケース

[Units](/lmile-docs/fulfillment-api/units.md) の単位が売越し（在庫が引き当て先に無く、別ロケーションから調達して出荷する）になったとき、その現場オペを **8 ステップ**で追うケース管理です。1 単位につき 1 ケースを起票し、単一の **advance エンドポイント**で状態を前進させます。

> **Base URL** `https://api.lmile.io` · **認証** `x-ingest-secret` ヘッダー または operator JWT（`Authorization: Bearer`）（[詳細](/lmile-docs/getting-started/authentication.md)） · `shop` はリクエストボディに含めます（API キーで呼ぶ場合は省略できます）

> `/api/routing/oversell-case` は機械間 secret（`x-ingest-secret`）と倉庫スタッフの operator JWT のどちらでも呼べます（系統はヘッダの有無で明示判別。[詳細](https://lmile.gitbook.io/lmile-docs/oversell-api/pages/7cB70I8yeRnMpvcdLkNu#routing-write-の-2-系統認証)）。operator JWT 経由は起票者 / 前進操作者を記録します。

> [Oversell / Reallocate](/lmile-docs/oversell-api/oversell-reallocate.md)（LM-498）の**同一出荷元内の自動再引き当て**とは別経路です。売越しケースは「別ロケーションを探して連絡・確保・出庫・追跡番号・MFC 受付」という現場フローを追うもので、`lm_routing_decisions.oversold` フラグは触りません（両者は独立して共存）。

## ステップ（status）

| status               | ステップ                         | 自動記録                                                           |
| -------------------- | ---------------------------- | -------------------------------------------------------------- |
| `case_opened`        | 1: 売越発生（起票）                  | unit → `oversell_pending`                                      |
| `locating`           | 2: 在庫があるロケーションを探す            | `found_location_id`（任意）                                        |
| `contacted`          | 3: 在庫があるロケーションに連絡            | `contacted_at`                                                 |
| `stock_secured`      | 4: 在庫確保（無ければ `locating` へ戻る） | `secured_at` / unit → `oversell_secured`                       |
| `dispatch_requested` | 5: 出庫依頼を立てる                  | `dispatch_requested_at`                                        |
| `dispatched`         | 6: 出庫処理を現場で行う                | `dispatched_at` / unit → `oversell_returning`                  |
| `tracking_reported`  | 7: 追跡番号を現場が連絡                | `tracking_number`（必須）                                          |
| `warehouse_received` | 8: MFC センターで受付完了             | `warehouse_received_at` / unit → `oversell_warehouse_received` |
| `wont_do`            | 中止（確保不能等）                    | `wont_do_at` / `wont_do_reason`                                |

遷移は **1 ステップ前進**が基本。`stock_secured → locating` の**戻り**（再探索）と、`warehouse_received` 以外からの **`wont_do`**（中止）のみ追加で許可します。それ以外のジャンプは `409 invalid_transition`。

## エンドポイント

| Method | Path                         | 用途                         |
| ------ | ---------------------------- | -------------------------- |
| `POST` | `/api/routing/oversell-case` | 売越しケースの起票 + 前進（単一 advance） |

***

## `POST` /api/routing/oversell-case

対象単位のケースが無ければ**起票**（`case_opened`）し、あれば指定 status へ前進します。`toStatus` 省略時は 1 ステップ前進。

### リクエスト

```http
POST https://api.lmile.io/api/routing/oversell-case
x-ingest-secret: {INGEST_SECRET}
Content-Type: application/json
```

```json
{
  "shop": "demo-store.myshopify.com",
  "sourceSystem": "shopify",
  "externalOrderRef": "1001",
  "barcode": "1234567890123",
  "lineInstanceNo": 1,
  "toStatus": "stock_secured",
  "fields": {
    "foundLocationId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "note": "大阪MFCに在庫あり"
  }
}
```

### ボディパラメータ

| パラメータ                               | 型               |  必須 | 説明                                                |
| ----------------------------------- | --------------- | :-: | ------------------------------------------------- |
| `shop`                              | string          |  ✓  | 店舗ドメイン（API キーで呼ぶ場合は省略できます）                        |
| `routingOrderId`                    | string (uuid)   |  △  | 対象注文。無ければ `sourceSystem` + `externalOrderRef` で特定 |
| `sourceSystem` / `externalOrderRef` | string          |  △  | `routingOrderId` 未指定時に必須                          |
| `fulfillmentUnitId`                 | string (uuid)   |  △  | 対象単位。無ければ `barcode` + `lineInstanceNo` で特定        |
| `barcode` / `lineInstanceNo`        | string / number |  △  | `fulfillmentUnitId` 未指定時に必須                       |
| `toStatus`                          | string          |     | 目標 status（省略 = 1 ステップ前進）                          |
| `fields.foundLocationId`            | string (uuid)   |     | 在庫が見つかった/確保した出庫元ロケーション                            |
| `fields.trackingNumber`             | string          |     | 追跡番号（`tracking_reported` で必須）                     |
| `fields.externalShipmentRef`        | string          |     | 出庫元の外部出荷 ID（smaregi 出荷 ID 等）                      |
| `fields.wontDoReason`               | string          |     | 中止理由（`wont_do` 用）                                 |
| `fields.note`                       | string          |     | 任意メモ                                              |

### レスポンス

```json
{
  "ok": true,
  "caseId": "c3d4e5f6-a7b8-9012-cdef-345678901234",
  "status": "stock_secured",
  "unitStatus": "oversell_secured",
  "opened": false,
  "changed": true
}
```

| フィールド        | 説明                                    |
| ------------ | ------------------------------------- |
| `caseId`     | 売越しケース id（`sot.lm_oversell_cases.id`） |
| `status`     | 更新後のケース status                        |
| `unitStatus` | 連動して更新された単位の売越サブ状態（`wont_do` 時は変化なし）  |
| `opened`     | この呼び出しで起票したか                          |
| `changed`    | 状態が変化したか（同一 status への再呼び出しは `false`）  |

### 挙動・冪等性

* 初回呼び出しでケースが無ければ起票し、単位を `oversell_pending` にします。
* 各ステップの timestamp / フィールドを自動記録し、対応する単位の売越サブ状態を更新します（`wont_do` は単位を変更しません）。
* 同一 status への再呼び出しは `changed: false` の no-op（timestamp 再設定なし）。
* `tracking_reported` は `fields.trackingNumber` 必須（無ければ `400`）。
* LM-498 の `oversold` フラグ・`/api/routing/reallocate` には影響しません（`routing_decision_id` は traceability のため保持するのみ）。

## エラー

エンドポイント固有:

| Status | 条件                                         | レスポンス例                                                                                                                     |
| :----: | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
|  `400` | 注文・単位の特定情報なし / `tracking_reported` で追跡番号欠落 | `{ "ok": false, "error_kind": "invalid_input", "error": "fields.trackingNumber required for tracking_reported" }`          |
|  `404` | 注文・単位が存在しない                                | `{ "ok": false, "error_kind": "unit_not_found", "error": "fulfillment unit not found for order" }`                         |
|  `409` | 不正なステップ遷移                                  | `{ "ok": false, "error_kind": "invalid_transition", "error": "cannot move oversell case from case_opened to dispatched" }` |

共通エラー（`401` / `400` / `403` / `405` / `500` / `503`）は [Error Codes](/lmile-docs/reference/error-codes.md) を参照。

## データモデル

* `sot.lm_oversell_cases` — 1 ケース = 1 単位（`UNIQUE shop + fulfillment_unit_id`）。`status`（8 ステップ + `wont_do`）/ `found_location_id` / `tracking_number` / `external_shipment_ref` / `wont_do_reason` + 各ステップ timestamp。`fulfillment_unit_id`（[Units](/lmile-docs/fulfillment-api/units.md)）と `routing_decision_id` にリンク。読み取り view: `public.lm_v_oversell_cases`
* 単位の売越サブ状態は `sot.lm_fulfillment_units.status`（`oversell_pending` / `oversell_secured` / `oversell_returning` / `oversell_warehouse_received`）に反映


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://lmile.gitbook.io/lmile-docs/oversell-api/cases.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
