# 画面設計書 22-受注詳細画面

## 概要

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

### 本画面の処理概要

受注詳細画面は、個別の販売注文（Sales Order）に関する詳細情報の表示・編集・管理を行うための画面である。受注のライフサイクル全体（作成から完了まで）を管理し、明細、出荷、在庫割当、関連製造オーダーなどの情報を統合的に表示する。

**業務上の目的・背景**：販売業務において、個々の受注を詳細に管理することは、顧客満足度の維持と業務効率の向上に不可欠である。本画面では、受注の進捗状況、明細アイテム、出荷状況、在庫割当状況を一元的に把握でき、発行、保留、キャンセル、完了といったステータス遷移操作も提供する。これにより、受注から出荷完了までのプロセスを効率的に管理し、顧客への納期遵守を実現する。

**画面へのアクセス方法**：販売インデックス画面の受注一覧から対象の受注行をクリック、または直接URL `/sales/sales-order/:id/*` にアクセスすることで本画面を表示できる。他の画面（部品詳細、顧客詳細等）からもリンクで遷移可能。

**主要な操作・処理内容**：
1. 受注基本情報の表示・編集（顧客、参照番号、説明、日付等）
2. 明細アイテムの追加・編集・削除
3. 追加明細（Extra Line Items）の管理
4. 出荷の作成・管理
5. 在庫の割当・割当解除
6. 製造オーダーとの連携確認
7. 受注のステータス管理（発行、保留、キャンセル、出荷、完了）
8. バーコード操作、印刷（レポート・ラベル）
9. 添付ファイル・メモの管理

**画面遷移**：
- 遷移元：販売インデックス画面、顧客詳細画面、部品詳細画面
- 遷移先：顧客詳細画面、出荷詳細画面、在庫アイテム詳細画面、製造オーダー詳細画面

**権限による表示制御**：
- `UserRoles.sales_order` のView権限がない場合、本画面にアクセスできない
- `UserRoles.sales_order` のChange権限がない場合、編集操作が無効化
- `UserRoles.sales_order` のAdd権限がない場合、複製操作が無効化
- `UserRoles.build` のView権限がない場合、製造オーダータブが非表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | 販売注文管理 | 主機能 | 販売注文の詳細表示・編集・発行・完了処理 |
| 16 | 販売注文明細管理 | 補助機能 | 販売明細行の表示・編集・追加・削除 |
| 17 | 出荷管理 | 補助機能 | 出荷の作成・管理 |
| 8 | 在庫アイテム管理 | API連携 | 在庫割当処理 |
| 19 | 製造オーダー管理 | 遷移先機能 | 関連製造オーダー一覧の表示 |
| 47 | 添付ファイル管理 | 補助機能 | 添付ファイルの表示・アップロード・削除 |
| 48 | メモ・ノート管理 | 補助機能 | 受注メモの表示・編集 |

## 画面種別

詳細画面（タブ切替型）

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/sales/sales-order/:id/*` | 受注詳細画面（:idは受注のPK） |

## 入出力項目

### 受注編集フォーム

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| 参照番号 | reference | string | ○ | 受注の参照番号（自動採番可） |
| 顧客 | customer | number | ○ | 顧客会社ID |
| 顧客参照 | customer_reference | string | - | 顧客側の参照番号 |
| 説明 | description | string | - | 受注の説明 |
| プロジェクトコード | project_code | number | - | プロジェクトコードID |
| 担当者 | responsible | number | - | 担当者（オーナー）ID |
| 配送先住所 | address | number | - | 配送先住所ID |
| 連絡先 | contact | number | - | 連絡先ID |
| 目標日 | target_date | date | - | 目標完了日 |
| 開始日 | start_date | date | - | 開始日 |
| 外部リンク | link | string | - | 外部参照URL |

### 明細アイテム追加フォーム

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| 部品 | part | number | ○ | 部品ID |
| 数量 | quantity | number | ○ | 注文数量 |
| 単価 | sale_price | number | - | 販売単価 |
| 参照 | reference | string | - | 明細の参照番号 |
| メモ | notes | string | - | 明細のメモ |
| 目標日 | target_date | date | - | 明細の目標日 |

## 表示項目

### 詳細パネル - 左上（基本情報）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 参照番号 | reference | string | 受注の参照番号（コピー可能） |
| 顧客参照 | customer_reference | string | 顧客側の参照番号 |
| 顧客 | customer | link | 顧客会社へのリンク |
| 説明 | description | string | 受注の説明 |
| ステータス | status | status | 受注ステータス |
| カスタムステータス | status_custom_key | status | カスタムステータス（異なる場合のみ表示） |

### 詳細パネル - 右上（進捗・金額）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 完了明細 | completed_lines | progressbar | 明細アイテムの完了進捗 |
| 完了出荷 | completed_shipments_count | progressbar | 出荷の完了進捗 |
| 注文通貨 | order_currency | string | 注文の通貨 |
| 合計金額 | total_price | currency | 受注合計金額 |

### 詳細パネル - 左下（連絡先・プロジェクト）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 外部リンク | link | link | 外部参照URL |
| 配送先住所 | address_detail | address | 配送先住所 |
| 連絡先 | contact_detail.name | string | 連絡先名 |
| 連絡先メール | contact_detail.email | string | 連絡先メールアドレス |
| 連絡先電話 | contact_detail.phone | string | 連絡先電話番号 |
| プロジェクトコード | project_code_label | string | プロジェクトコード |
| 担当者 | responsible | badge | 担当者 |

### 詳細パネル - 右下（日付）

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 作成日 | creation_date | date | 作成日 |
| 発行日 | issue_date | date | 発行日 |
| 開始日 | start_date | date | 開始日 |
| 目標日 | target_date | date | 目標完了日 |
| 完了日 | shipment_date | date | 出荷完了日 |

### タブ構成

| タブ名 | 内容 |
|--------|------|
| Order Details | 受注の詳細情報 |
| Line Items | 明細アイテム一覧と追加明細 |
| Shipments | 出荷一覧 |
| Allocated Stock | 割当済み在庫一覧 |
| Build Orders | 関連製造オーダー一覧 |
| Parameters | パラメータ一覧 |
| Attachments | 添付ファイル一覧 |
| Notes | メモ |

## イベント仕様

### 01-受注発行ボタン押下

**トリガー**：「Issue Order」ボタンをクリック

**前提条件**：
- `UserRoles.sales_order` のChange権限を保持
- 受注ステータスがPENDINGまたはON_HOLD

**処理フロー**：
1. 確認モーダルを表示（「Issue this order」）
2. 確認後、`POST /api/order/so/:id/issue/` を実行
3. 成功時、ステータスがIN_PROGRESSに変更
4. 画面をリフレッシュ

### 02-受注出荷ボタン押下

**トリガー**：「Ship Order」ボタンをクリック

**前提条件**：
- `UserRoles.sales_order` のChange権限を保持
- 受注ステータスがIN_PROGRESS
- SALESORDER_SHIP_COMPLETE設定が無効

**処理フロー**：
1. 出荷確認モーダルを表示
2. accept_incompleteオプションを選択可能
3. `POST /api/order/so/:id/complete/` を実行
4. 成功時、ステータスがSHIPPEDに変更

### 03-受注完了ボタン押下

**トリガー**：「Complete Order」ボタンをクリック

**前提条件**：
- `UserRoles.sales_order` のChange権限を保持
- 受注ステータスがSHIPPEDまたは（SALESORDER_SHIP_COMPLETE設定有効時のIN_PROGRESS）

**処理フロー**：
1. 完了確認モーダルを表示
2. accept_incompleteオプションを選択可能
3. `POST /api/order/so/:id/complete/` を実行
4. 成功時、ステータスがCOMPLETEに変更

### 04-受注保留ボタン押下

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

**前提条件**：
- `UserRoles.sales_order` のChange権限を保持
- 受注ステータスがPENDINGまたはIN_PROGRESS

**処理フロー**：
1. 保留確認モーダルを表示
2. `POST /api/order/so/:id/hold/` を実行
3. 成功時、ステータスがON_HOLDに変更

### 05-受注キャンセルボタン押下

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

**前提条件**：
- `UserRoles.sales_order` のChange権限を保持
- 受注ステータスがPENDING、ON_HOLD、またはIN_PROGRESS

**処理フロー**：
1. キャンセル確認モーダルを表示
2. `POST /api/order/so/:id/cancel/` を実行
3. 成功時、ステータスがCANCELLEDに変更

### 06-受注編集ボタン押下

**トリガー**：「Edit」ボタン/メニューをクリック

**前提条件**：`UserRoles.sales_order` のChange権限を保持

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

### 07-受注複製ボタン押下

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

**前提条件**：`UserRoles.sales_order` のAdd権限を保持

**処理フロー**：
1. 複製フォームモーダルを表示（参照番号以外を複製）
2. 必要に応じて編集
3. 保存ボタン押下で `POST /api/order/so/` を実行
4. 成功時、新規作成された受注の詳細画面に遷移

### 08-明細アイテム追加

**トリガー**：明細タブ内の「Add line item」ボタンをクリック

**処理フロー**：
1. 明細追加フォームモーダルを表示
2. 部品、数量等を入力
3. 保存ボタン押下で `POST /api/order/so-line/` を実行
4. 成功時、明細一覧をリフレッシュ

### 09-出荷作成

**トリガー**：出荷タブ内の「Add Shipment」ボタンをクリック

**処理フロー**：
1. 出荷作成フォームモーダルを表示
2. 出荷情報を入力
3. 保存ボタン押下で `POST /api/order/so/shipment/` を実行
4. 成功時、出荷一覧をリフレッシュ

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 受注編集 | SalesOrder | UPDATE | 受注情報の更新 |
| 受注発行 | SalesOrder | UPDATE | ステータスをIN_PROGRESSに更新 |
| 受注保留 | SalesOrder | UPDATE | ステータスをON_HOLDに更新 |
| 受注キャンセル | SalesOrder | UPDATE | ステータスをCANCELLEDに更新 |
| 受注出荷 | SalesOrder | UPDATE | ステータスをSHIPPEDに更新 |
| 受注完了 | SalesOrder | UPDATE | ステータスをCOMPLETEに更新 |
| 受注複製 | SalesOrder | INSERT | 新規受注の作成 |
| 明細追加 | SalesOrderLineItem | INSERT | 明細アイテムの追加 |
| 明細編集 | SalesOrderLineItem | UPDATE | 明細アイテムの更新 |
| 明細削除 | SalesOrderLineItem | DELETE | 明細アイテムの削除 |
| 出荷作成 | SalesOrderShipment | INSERT | 出荷の作成 |
| 在庫割当 | SalesOrderAllocation | INSERT | 在庫割当の作成 |

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

#### SalesOrder（受注編集時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | reference | フォーム入力値 | 参照番号 |
| UPDATE | customer | フォーム選択値 | 顧客会社ID |
| UPDATE | customer_reference | フォーム入力値 | 顧客参照番号 |
| UPDATE | description | フォーム入力値 | 説明 |
| UPDATE | target_date | フォーム入力値 | 目標日 |
| UPDATE | start_date | フォーム入力値 | 開始日 |
| UPDATE | project_code | フォーム選択値 | プロジェクトコードID |
| UPDATE | responsible | フォーム選択値 | 担当者ID |
| UPDATE | address | フォーム選択値 | 住所ID |
| UPDATE | contact | フォーム選択値 | 連絡先ID |
| UPDATE | link | フォーム入力値 | 外部リンク |

#### SalesOrder（ステータス更新時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | status | 10:PENDING, 20:ON_HOLD, 30:IN_PROGRESS, 40:SHIPPED, 50:COMPLETE, 60:CANCELLED | API実行による自動更新 |
| UPDATE | issue_date | 現在日時（発行時） | 発行処理時に設定 |
| UPDATE | shipment_date | 現在日時（出荷/完了時） | 出荷/完了処理時に設定 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-SO-010 | 成功 | Order issued | 受注発行成功時 |
| MSG-SO-011 | 成功 | Order placed on hold | 受注保留成功時 |
| MSG-SO-012 | 成功 | Order cancelled | 受注キャンセル成功時 |
| MSG-SO-013 | 成功 | Order shipped | 受注出荷成功時 |
| MSG-SO-014 | 成功 | Order completed | 受注完了成功時 |
| MSG-SO-015 | 警告 | Issue this order | 発行確認時 |
| MSG-SO-016 | 警告 | Place this order on hold | 保留確認時 |
| MSG-SO-017 | 警告 | Cancel this order | キャンセル確認時 |
| MSG-SO-018 | 警告 | Ship this order? | 出荷確認時 |
| MSG-SO-019 | 警告 | Mark this order as complete | 完了確認時 |

## 例外処理

| 例外条件 | 表示内容 | 処理 |
|----------|---------|------|
| 権限不足 | InstanceDetail権限チェック | sales_order権限がない場合 |
| 受注未存在 | 404エラー | 指定IDの受注が存在しない場合 |
| API通信エラー | エラー通知 | 各種操作失敗時 |
| 明細編集不可 | 編集ボタン非表示 | ステータスがCOMPLETEまたはCANCELLEDかつSALESOODER_EDIT_COMPLETED_ORDERS設定が無効の場合 |

## 備考

- SALESORDER_EDIT_COMPLETED_ORDERS設定により、完了済み受注の明細編集可否が制御される
- SALESORDER_SHIP_COMPLETE設定により、「出荷」ステップをスキップして直接「完了」に遷移可能
- 受注通貨は、受注設定 > 顧客設定 > グローバルデフォルトの優先順位で決定
- 複製時、参照番号は参照番号パターンに基づいて自動生成される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | sales_order関連エンドポイント（174-188行目） |
| 1-2 | ModelType.ts | `src/frontend/lib/enums/ModelType.ts` | salesorderモデルタイプ定義 |

**読解のコツ**: APIエンドポイントの命名規則（issue, hold, cancel, complete等）を把握する。

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

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

**主要処理フロー**:
1. **64-80行目**: useInstanceフックで受注データを取得
2. **82-88行目**: 通貨の決定ロジック
3. **90-297行目**: 詳細パネルの定義（DetailsField配列）
4. **299-310行目**: 明細編集可能判定（ステータスと設定による）
5. **346-445行目**: タブパネル定義
6. **447-491行目**: ステータス変更モーダルの定義
7. **493-580行目**: アクションボタンの定義（権限とステータスによる表示制御）
8. **605-643行目**: レンダリング

#### Step 3: 関連テーブルコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SalesOrderLineItemTable.tsx | `src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx` | 明細一覧テーブル |
| 3-2 | SalesOrderShipmentTable.tsx | `src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx` | 出荷一覧テーブル |
| 3-3 | SalesOrderAllocationTable.tsx | `src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx` | 割当在庫一覧 |
| 3-4 | BuildOrderTable.tsx | `src/frontend/src/tables/build/BuildOrderTable.tsx` | 製造オーダー一覧 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SalesOrderForms.tsx | `src/frontend/src/forms/SalesOrderForms.tsx` | useSalesOrderFieldsフック |

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

```
SalesOrderDetail.tsx
    │
    ├─ useInstance (受注データ取得)
    │      └─ GET /api/order/so/:id/
    │
    ├─ PageDetail (ページヘッダー)
    │      ├─ StatusRenderer (ステータスバッジ)
    │      └─ Actions
    │             ├─ PrimaryActionButton (Issue/Ship/Complete)
    │             ├─ AdminButton
    │             ├─ BarcodeActionDropdown
    │             ├─ PrintingActions
    │             └─ OptionsActionDropdown
    │
    └─ PanelGroup
           │
           ├─ Panel (detail)
           │      └─ ItemDetailsGrid
           │             └─ DetailsTable × 4
           │
           ├─ Panel (line-items)
           │      ├─ SalesOrderLineItemTable
           │      └─ ExtraLineItemTable
           │
           ├─ Panel (shipments)
           │      └─ SalesOrderShipmentTable
           │
           ├─ Panel (allocations)
           │      └─ SalesOrderAllocationTable
           │
           ├─ Panel (build-orders)
           │      └─ BuildOrderTable
           │
           ├─ ParametersPanel
           ├─ AttachmentPanel
           └─ NotesPanel
```

### データフロー図

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

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

Issue/Ship/Complete ─────────▶ useCreateApiFormModal ──────────▶ ステータス更新
                                POST /api/order/so/:id/issue/
                                POST /api/order/so/:id/hold/
                                POST /api/order/so/:id/cancel/
                                POST /api/order/so/:id/complete/

Edit ────────────────────────▶ useEditApiFormModal ────────────▶ 受注更新
                                PATCH /api/order/so/:id/

Duplicate ───────────────────▶ useCreateApiFormModal ──────────▶ 新規受注作成
                                POST /api/order/so/                → 詳細画面遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SalesOrderDetail.tsx | `src/frontend/src/pages/sales/SalesOrderDetail.tsx` | ソース | メイン画面コンポーネント |
| SalesOrderLineItemTable.tsx | `src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx` | ソース | 明細一覧テーブル |
| SalesOrderShipmentTable.tsx | `src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx` | ソース | 出荷一覧テーブル |
| SalesOrderAllocationTable.tsx | `src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx` | ソース | 割当在庫一覧テーブル |
| SalesOrderForms.tsx | `src/frontend/src/forms/SalesOrderForms.tsx` | ソース | フォーム定義 |
| BuildOrderTable.tsx | `src/frontend/src/tables/build/BuildOrderTable.tsx` | ソース | 製造オーダー一覧 |
| ExtraLineItemTable.tsx | `src/frontend/src/tables/general/ExtraLineItemTable.tsx` | ソース | 追加明細一覧 |
| UseInstance.tsx | `src/frontend/src/hooks/UseInstance.tsx` | ソース | インスタンスデータ取得フック |
| UseStatusCodes.tsx | `src/frontend/src/hooks/UseStatusCodes.tsx` | ソース | ステータスコード取得フック |
| SettingsStates.ts | `src/frontend/src/states/SettingsStates.ts` | ソース | グローバル設定状態 |
| DetailsTable.tsx | `src/frontend/src/components/details/Details.tsx` | ソース | 詳細テーブルコンポーネント |
| StatusRenderer.tsx | `src/frontend/src/components/render/StatusRenderer.tsx` | ソース | ステータス表示コンポーネント |
