# 画面設計書 97-在庫調整画面

## 概要

本ドキュメントは、Medusa Admin Dashboardの在庫調整画面の設計仕様を定義するものです。

### 本画面の処理概要

在庫調整画面は、特定のロケーションにおける在庫アイテムの在庫数量を調整するためのドロワー形式の画面です。

**業務上の目的・背景**：在庫管理において、実地棚卸による在庫数の訂正、入荷処理、破損・紛失による減算など、様々な理由で在庫数量を調整する必要があります。本画面では、特定のロケーションの在庫数量を直接設定でき、予約数量との関係も確認しながら調整を行えます。

**画面へのアクセス方法**：在庫詳細画面のロケーション別在庫セクションから特定のロケーションの調整ボタンをクリックすることでドロワー形式で表示されます。URL `/inventory/{id}/locations/{location_id}/adjust` に直接アクセスすることも可能です。

**主要な操作・処理内容**：
1. 現在の在庫情報の表示（タイトル、SKU、ロケーション名、予約数、利用可能数）
2. 在庫数量の入力
3. 保存処理の実行

**画面遷移**：
- 遷移元：在庫詳細画面
- 遷移先：保存成功時は在庫詳細画面に戻る（ドロワークローズ）

**権限による表示制御**：認証済みユーザーであれば全機能を利用可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | 在庫レベル管理 | 主機能 | 在庫数量の調整 |

## 画面種別

編集（モーダル形式 / ドロワー）

## URL/ルーティング

`/inventory/{id}/locations/{location_id}/adjust`

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | バリデーション | 説明 |
|--------|--------|-----|------|--------------|------|
| 在庫数 | stocked_quantity | number | ○ | 予約数以上 | 新しい在庫数量 |

## 表示項目

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|-----|------|
| タイトル | item.title | string | 在庫アイテムのタイトル |
| SKU | item.sku | string | 在庫管理単位コード |
| ロケーション名 | location.name | string | 対象ロケーションの名前 |
| 予約数 | level.reserved_quantity | number | 予約済み数量（変更不可） |
| 利用可能数 | available_quantity | number | 利用可能数量（入力値から動的計算） |

## イベント仕様

### 1-Saveボタン押下

入力内容でバリデーションを実行し、在庫レベルを更新します。

**処理フロー**:
1. フォームのバリデーション実行（在庫数 >= 予約数 を検証）
2. バリデーション成功時、`useUpdateInventoryLevel` で API 呼び出し
3. 成功時、トースト通知（inventory.toast.updateLevel）を表示しドロワーをクローズ
4. エラー時、エラーメッセージをトースト表示

### 2-Cancelボタン押下

入力内容を破棄してドロワーをクローズします。

### 3-在庫数入力

在庫数を入力すると、利用可能数がリアルタイムで再計算されます。

**計算式**: 利用可能数 = 在庫数 - 予約数

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 初期表示 | inventory_item | SELECT | 在庫アイテム情報の取得 |
| 初期表示 | inventory_level | SELECT | 在庫レベル情報の取得 |
| 初期表示 | stock_location | SELECT | ロケーション情報の取得 |
| Save押下 | inventory_level | UPDATE | 在庫数量の更新 |

### テーブル別更新項目詳細

#### inventory_level

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | stocked_quantity | フォーム入力値 | 予約数以上である必要あり |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| inventory.toast.updateLevel | 成功 | 在庫レベルが正常に更新されました | 更新成功時 |
| inventory.adjustInventory.errors.stockedQuantity | エラー | 在庫数は予約数（{quantity}）以上である必要があります | バリデーションエラー時 |
| - | エラー | エラーメッセージ（API エラー内容） | API 呼び出しエラー時 |

## 例外処理

| 例外条件 | 対応 | 画面表示 |
|---------|------|----------|
| 在庫アイテムが存在しない | エラーをスロー | エラー画面を表示 |
| ロケーションが存在しない | エラーをスロー | エラー画面を表示 |
| 在庫レベルが存在しない | エラーをスロー | エラー画面を表示 |
| 在庫数 < 予約数 | フォームエラー表示 | バリデーションエラーメッセージを表示 |
| APIエラー | トースト通知 | エラーメッセージを表示 |

## 備考

- RouteDrawer形式で実装
- useWatchで在庫数入力をリアルタイム監視し、利用可能数を動的計算
- castNumberで数値変換を実行
- 在庫数は予約数以上である必要がある（予約は保持される）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | adjust-inventory-form.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-detail/components/adjust-inventory/components/adjust-inventory-form.tsx` | AdjustInventorySchemaのバリデーションルール（superRefineによるカスタムバリデーション）を確認 |

**読解のコツ**: superRefineで在庫数が予約数以上であることを検証している。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | adjust-inventory-drawer.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-detail/components/adjust-inventory/adjust-inventory-drawer.tsx` | ドロワーコンポーネント。inventory_item, inventory_level, stock_locationの3つのデータを取得 |
| 2-2 | adjust-inventory-form.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-detail/components/adjust-inventory/components/adjust-inventory-form.tsx` | フォームコンポーネント |

**主要処理フロー**:
1. **11行目（drawer）**: `useParams` でid, location_idを取得
2. **14-19行目（drawer）**: `useInventoryItem` でアイテム取得
3. **21-24行目（drawer）**: `inventoryLevel` をlocation_levelsから抽出
4. **26-28行目（drawer）**: `useStockLocation` でロケーション取得
5. **47-76行目（form）**: AdjustInventorySchemaの定義（superRefineでバリデーション）
6. **85-92行目（form）**: useWatchで在庫数入力を監視
7. **90-92行目（form）**: 利用可能数の動的計算

### プログラム呼び出し階層図

```
AdjustInventoryDrawer (adjust-inventory-drawer.tsx)
    │
    ├─ useInventoryItem (inventory.tsx)
    │      └─ sdk.admin.inventoryItem.retrieve()
    │
    ├─ useStockLocation (stock-locations.tsx)
    │      └─ sdk.admin.stockLocation.retrieve()
    │
    └─ AdjustInventoryForm (adjust-inventory-form.tsx)
           │
           └─ useUpdateInventoryLevel (inventory.tsx)
                  └─ sdk.admin.inventoryItem.updateLevel()
```

### データフロー図

```
[入力]                          [処理]                          [出力]

在庫数入力 ──────────────▶ useWatch ──▶ 利用可能数計算 ──▶ 画面表示
                    │
                    ▼
              zodバリデーション
           (stocked >= reserved)
                    │
                    ▼
         useUpdateInventoryLevel ──▶ inventory_level UPDATE
                    │
                    ▼
              handleSuccess ──▶ ドロワークローズ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| adjust-inventory-drawer.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-detail/components/adjust-inventory/adjust-inventory-drawer.tsx` | ソース | ドロワーコンポーネント |
| adjust-inventory-form.tsx | `packages/admin/dashboard/src/routes/inventory/inventory-detail/components/adjust-inventory/components/adjust-inventory-form.tsx` | ソース | フォームコンポーネント |
| inventory.tsx | `packages/admin/dashboard/src/hooks/api/inventory.tsx` | ソース | API フック |
