# 画面設計書 23-出荷詳細画面

## 概要

本ドキュメントは、InvenTreeシステムの出荷詳細画面(SalesOrderShipmentDetail)の設計仕様を定義するものである。

### 本画面の処理概要

出荷詳細画面は、個別の出荷（Shipment）に関する詳細情報の表示・編集・管理を行うための画面である。出荷は受注に紐づく物理的な商品発送単位であり、本画面では出荷の作成から完了までのライフサイクルを管理する。

**業務上の目的・背景**：販売業務において、受注を複数回に分けて出荷するケースや、検品後に出荷を行うケースが存在する。本画面は、個々の出荷に対する割当在庫の確認、出荷前の検品（チェック）、追跡番号・請求書番号の管理、出荷完了処理を提供する。これにより、出荷プロセスの可視化と品質管理を実現し、顧客への正確な商品配送を支援する。

**画面へのアクセス方法**：受注詳細画面の出荷タブから出荷行をクリック、または販売インデックス画面の保留出荷一覧から選択、あるいは直接URL `/sales/shipment/:id/*` にアクセスすることで本画面を表示できる。

**主要な操作・処理内容**：
1. 出荷基本情報の表示・編集（参照番号、追跡番号、請求書番号、住所等）
2. 割当在庫アイテムの確認
3. 出荷のチェック（検品）/ チェック解除
4. 出荷完了処理（送信）
5. 出荷のキャンセル
6. バーコード操作、印刷（レポート・ラベル）
7. 添付ファイル・メモの管理

**画面遷移**：
- 遷移元：受注詳細画面、販売インデックス画面
- 遷移先：受注詳細画面（出荷キャンセル後）、在庫アイテム詳細画面

**権限による表示制御**：
- `UserRoles.sales_order` のView権限がない場合、本画面にアクセスできない
- `UserRoles.salesordershipment` のChange権限がない場合、編集操作が無効化
- 出荷済みの場合、在庫割当の編集が不可

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | 出荷管理 | 主機能 | 出荷の詳細表示・編集・完了処理 |
| 16 | 販売注文明細管理 | 補助機能 | 出荷対象明細の表示 |

## 画面種別

詳細画面（タブ切替型）

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/sales/shipment/:id/*` | 出荷詳細画面（:idは出荷のPK） |

## 入出力項目

### 出荷編集フォーム（保留中の場合）

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| 参照番号 | reference | string | ○ | 出荷の参照番号 |
| 追跡番号 | tracking_number | string | - | 運送会社の追跡番号 |
| 請求書番号 | invoice_number | string | - | 請求書番号 |
| 配送先住所 | shipment_address | number | - | 配送先住所ID |
| 外部リンク | link | string | - | 外部参照URL |

### 出荷完了フォーム

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| 追跡番号 | tracking_number | string | - | 運送会社の追跡番号 |
| 請求書番号 | invoice_number | string | - | 請求書番号 |
| 出荷日 | shipment_date | date | - | 出荷日（デフォルト：当日） |
| 配達日 | delivery_date | date | - | 配達予定日/実績日 |

## 表示項目

### 詳細パネル - 左上（受注・顧客情報）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 受注 | order | link | 受注詳細へのリンク |
| 顧客 | customer | link | 顧客詳細へのリンク |
| 外部リンク | link | link | 外部参照URL |

### 詳細パネル - 右上（出荷情報）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 顧客参照 | customer_reference | string | 顧客側の参照番号 |
| 出荷参照 | reference | string | 出荷の参照番号 |
| 追跡番号 | tracking_number | string | 運送会社の追跡番号 |
| 請求書番号 | invoice_number | string | 請求書番号 |

### 詳細パネル - 左下（住所）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 配送先住所 | shipment_address_detail / order_detail.address_detail | address | 配送先住所 |

### 詳細パネル - 右下（ステータス・日付）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 割当アイテム数 | allocated_items | number | 割り当てられたアイテム数 |
| チェック担当者 | checked_by_detail | user | チェック（検品）した担当者 |
| 出荷日 | shipment_date | date | 出荷日 |
| 配達日 | delivery_date | date | 配達日 |

### ステータスバッジ

| バッジ名 | 表示条件 | 色 |
|---------|---------|-----|
| Pending | 出荷未完了 | gray |
| Checked | 保留中かつチェック済み | green |
| Not Checked | 保留中かつ未チェック | red |
| Shipped | 出荷完了 | green |
| Delivered | 配達日が設定済み | blue |

### タブ構成

| タブ名 | 内容 |
|--------|------|
| Shipment Details | 出荷の詳細情報 |
| Allocated Stock | 割当済み在庫一覧 |
| Attachments | 添付ファイル一覧 |
| Notes | メモ |

## イベント仕様

### 01-出荷送信ボタン押下

**トリガー**：「Send Shipment」ボタンをクリック

**前提条件**：出荷が保留中（shipment_dateがnull）

**処理フロー**：
1. 出荷完了フォームモーダルを表示
2. 追跡番号、請求書番号、出荷日等を入力
3. 保存ボタン押下で `POST /api/order/so/shipment/:id/ship/` を実行
4. 成功時、出荷が完了状態に変更
5. 画面をリフレッシュ

### 02-出荷編集ボタン押下

**トリガー**：「Edit」メニューをクリック

**前提条件**：`ModelType.salesordershipment` のChange権限を保持

**処理フロー**：
1. 編集フォームモーダルを表示
2. 各項目を編集
3. 保存ボタン押下で `PATCH /api/order/so/shipment/:id/` を実行
4. 成功時、画面をリフレッシュ

### 03-チェック（検品）ボタン押下

**トリガー**：「Check」メニューをクリック

**前提条件**：
- 出荷が保留中
- 現在未チェック状態

**処理フロー**：
1. チェック確認モーダルを表示
2. 確認後、チェック処理を実行
3. checked_byフィールドに現在ユーザーが設定される
4. 画面をリフレッシュ

### 04-チェック解除ボタン押下

**トリガー**：「Uncheck」メニューをクリック

**前提条件**：
- 出荷が保留中
- 現在チェック済み状態

**処理フロー**：
1. チェック解除確認モーダルを表示
2. 確認後、チェック解除処理を実行
3. checked_byフィールドがnullに設定される
4. 画面をリフレッシュ

### 05-出荷キャンセルボタン押下

**トリガー**：「Cancel Shipment」メニューをクリック

**前提条件**：出荷が保留中

**処理フロー**：
1. キャンセル確認モーダルを表示
2. 確認後、`DELETE /api/order/so/shipment/:id/` を実行
3. 成功時、関連する受注詳細画面に遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 出荷編集 | SalesOrderShipment | UPDATE | 出荷情報の更新 |
| 出荷送信 | SalesOrderShipment | UPDATE | shipment_date等の更新 |
| 出荷チェック | SalesOrderShipment | UPDATE | checked_byの更新 |
| 出荷チェック解除 | SalesOrderShipment | UPDATE | checked_byをnullに更新 |
| 出荷キャンセル | SalesOrderShipment | DELETE | 出荷レコードの削除 |

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

#### SalesOrderShipment（出荷編集時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | reference | フォーム入力値 | 参照番号 |
| UPDATE | tracking_number | フォーム入力値 | 追跡番号 |
| UPDATE | invoice_number | フォーム入力値 | 請求書番号 |
| UPDATE | shipment_address | フォーム選択値 | 配送先住所ID |
| UPDATE | link | フォーム入力値 | 外部リンク |

#### SalesOrderShipment（出荷完了時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | shipment_date | フォーム入力値（デフォルト：当日） | 出荷日 |
| UPDATE | delivery_date | フォーム入力値 | 配達日 |
| UPDATE | tracking_number | フォーム入力値 | 追跡番号 |
| UPDATE | invoice_number | フォーム入力値 | 請求書番号 |

#### SalesOrderShipment（チェック時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | checked_by | 現在ユーザーID | チェック担当者 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-SH-001 | 成功 | Shipment completed | 出荷完了成功時 |
| MSG-SH-002 | 成功 | Shipment updated | 出荷編集成功時 |
| MSG-SH-003 | 成功 | Shipment checked | チェック成功時 |
| MSG-SH-004 | 成功 | Shipment unchecked | チェック解除成功時 |
| MSG-SH-005 | 成功 | Shipment cancelled | キャンセル成功時 |

## 例外処理

| 例外条件 | 表示内容 | 処理 |
|----------|---------|------|
| 権限不足 | InstanceDetail権限チェック | sales_order権限がない場合 |
| 出荷未存在 | 404エラー | 指定IDの出荷が存在しない場合 |
| API通信エラー | エラー通知 | 各種操作失敗時 |

## 備考

- 出荷の配送先住所は、出荷固有の設定がない場合、親受注の住所が使用される
- チェック機能は、出荷前の検品プロセスを管理するためのもの
- 出荷完了時、デフォルトで当日の日付が出荷日として設定される
- 出荷キャンセル後は、元の受注詳細画面に自動的に遷移する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | sales_order_shipment関連（187-188行目） |
| 1-2 | ModelType.ts | `src/frontend/lib/enums/ModelType.ts` | salesordershipmentモデルタイプ |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SalesOrderShipmentDetail.tsx | `src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx` | 画面全体の構成 |

**主要処理フロー**:
1. **63-73行目**: useInstanceで出荷データを取得
2. **75-79行目**: useInstanceで顧客データを取得
3. **81-83行目**: isPending, isCheckedの判定
4. **85-247行目**: 詳細パネルの定義
5. **249-282行目**: タブパネル定義
6. **284-330行目**: 各種フォームモーダル定義
7. **332-369行目**: ステータスバッジ定義
8. **371-431行目**: アクションボタン定義

#### Step 3: フォーム定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SalesOrderForms.tsx | `src/frontend/src/forms/SalesOrderForms.tsx` | useSalesOrderShipmentFields, useSalesOrderShipmentCompleteFields |

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

```
SalesOrderShipmentDetail.tsx
    │
    ├─ useInstance (出荷データ取得)
    │      └─ GET /api/order/so/shipment/:id/
    │
    ├─ useInstance (顧客データ取得)
    │      └─ GET /api/company/:customerId/
    │
    ├─ PageDetail (ページヘッダー)
    │      ├─ DetailsBadge × 5 (ステータス表示)
    │      └─ Actions
    │             ├─ PrimaryActionButton (Send Shipment)
    │             ├─ BarcodeActionDropdown
    │             ├─ PrintingActions
    │             └─ OptionsActionDropdown
    │                    ├─ Edit
    │                    ├─ Check / Uncheck
    │                    └─ Cancel
    │
    └─ PanelGroup
           │
           ├─ Panel (detail)
           │      └─ ItemDetailsGrid
           │
           ├─ Panel (items)
           │      └─ SalesOrderAllocationTable
           │
           ├─ AttachmentPanel
           └─ NotesPanel
```

### データフロー図

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

URL /:id ────────────────────▶ useInstance ────────────────────▶ 詳細表示
                                GET /api/order/so/shipment/:id/

Send Shipment ───────────────▶ useCreateApiFormModal ──────────▶ 出荷完了
                                POST /api/order/so/shipment/:id/ship/

Edit ────────────────────────▶ useEditApiFormModal ────────────▶ 出荷更新
                                PATCH /api/order/so/shipment/:id/

Cancel ──────────────────────▶ useDeleteApiFormModal ──────────▶ 出荷削除
                                DELETE /api/order/so/shipment/:id/   → 受注画面遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SalesOrderShipmentDetail.tsx | `src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx` | ソース | メイン画面コンポーネント |
| SalesOrderAllocationTable.tsx | `src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx` | ソース | 割当在庫一覧テーブル |
| SalesOrderForms.tsx | `src/frontend/src/forms/SalesOrderForms.tsx` | ソース | フォーム定義 |
| RenderAddress.tsx | `src/frontend/src/components/render/Company.tsx` | ソース | 住所表示コンポーネント |
| RenderUser.tsx | `src/frontend/src/components/render/User.tsx` | ソース | ユーザー表示コンポーネント |
| DetailsBadge.tsx | `src/frontend/src/components/details/DetailsBadge.tsx` | ソース | ステータスバッジコンポーネント |
| formatters.ts | `src/frontend/src/defaults/formatters.ts` | ソース | 日付フォーマット関数 |
