# 画面設計書 21-販売インデックス画面

## 概要

本ドキュメントは、InvenTreeシステムの販売インデックス画面(SalesIndex)の設計仕様を定義するものである。

### 本画面の処理概要

販売インデックス画面は、販売管理業務の中核となる画面であり、受注、出荷、返品オーダー、顧客情報を一元的に管理・閲覧するためのダッシュボード的な役割を果たす。

**業務上の目的・背景**：企業の販売活動において、受注状況の把握、出荷管理、返品処理、顧客管理は業務効率と顧客満足度に直結する重要な業務である。本画面は、これらの情報を統合的に表示することで、販売担当者が迅速に状況を把握し、適切なアクションを取れるようにすることを目的としている。各種オーダーのステータス管理、期日管理、顧客別の取引履歴把握が可能となり、販売プロセス全体の可視化と効率化を実現する。

**画面へのアクセス方法**：サイドナビゲーションメニューから「Sales」をクリック、またはホーム画面から「販売」リンクを選択することで本画面にアクセスできる。URLパスは `/sales/index/*` となる。

**主要な操作・処理内容**：
1. 受注一覧の表示・検索・フィルタリング（テーブル/カレンダー/パラメトリック表示の切り替え）
2. 保留中の出荷一覧の確認
3. 返品オーダー一覧の表示・検索・フィルタリング（テーブル/カレンダー/パラメトリック表示の切り替え）
4. 顧客一覧の表示・検索・フィルタリング（テーブル/パラメトリック表示の切り替え）
5. 新規受注の作成
6. 新規返品オーダーの作成
7. 各詳細画面への遷移

**画面遷移**：
- 遷移元：ホーム画面、サイドナビゲーション
- 遷移先：受注詳細画面、出荷詳細画面、返品オーダー詳細画面、顧客詳細画面

**権限による表示制御**：
- `UserRoles.sales_order` のView権限がない場合、本画面にアクセスできず`PermissionDenied`画面が表示される
- `UserRoles.return_order` のView権限がない場合、返品オーダータブが非表示となる
- 受注作成には `UserRoles.sales_order` のAdd権限が必要
- 返品オーダー作成には `UserRoles.return_order` のAdd権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | 販売注文管理 | 主機能 | 販売注文の一覧表示（テーブル/カレンダー/パラメトリック） |
| 17 | 出荷管理 | 補助機能 | 保留出荷一覧の表示 |
| 18 | 返品注文管理 | 補助機能 | 返品オーダー一覧の表示 |
| 23 | 会社マスタ管理 | 補助機能 | 顧客一覧の表示 |

## 画面種別

一覧画面（タブ切替型ダッシュボード）

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/sales/index/*` | 販売インデックス画面 |

## 入出力項目

### 検索・フィルター項目（受注一覧）

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| ステータス | status | enum | - | 受注のステータスでフィルタ |
| 未処理 | outstanding | boolean | - | 未処理の注文のみ表示 |
| 期限超過 | overdue | boolean | - | 期限超過の注文のみ表示 |
| 担当者（自分） | assigned_to_me | boolean | - | 自分が担当の注文のみ表示 |
| 作成日（以前） | created_before | date | - | 指定日以前に作成された注文 |
| 作成日（以後） | created_after | date | - | 指定日以後に作成された注文 |
| 目標日（以前） | target_date_before | date | - | 目標日が指定日以前の注文 |
| 目標日（以後） | target_date_after | date | - | 目標日が指定日以後の注文 |
| 開始日（以前） | start_date_before | date | - | 開始日が指定日以前の注文 |
| 開始日（以後） | start_date_after | date | - | 開始日が指定日以後の注文 |
| 完了日（以前） | completed_before | date | - | 完了日が指定日以前の注文 |
| 完了日（以後） | completed_after | date | - | 完了日が指定日以後の注文 |
| プロジェクトコード有無 | has_project_code | boolean | - | プロジェクトコードの有無 |
| プロジェクトコード | project_code | number | - | 特定のプロジェクトコード |
| 担当者 | responsible | number | - | 担当者ID |
| 作成者 | created_by | number | - | 作成者ID |

## 表示項目

### 受注一覧テーブル

| 項目名 | フィールド | データ型 | ソート | 説明 |
|--------|-----------|----------|--------|------|
| 参照番号 | reference | string | 可 | 受注の参照番号 |
| 顧客 | customer__name | string | 可 | 顧客会社名 |
| 顧客参照 | customer_reference | string | - | 顧客側の参照番号 |
| 説明 | description | string | - | 受注の説明 |
| 明細進捗 | line_items | progress | - | 明細アイテムの完了進捗 |
| 出荷進捗 | shipments_count | progress | - | 出荷の完了進捗 |
| ステータス | status | status | - | 受注ステータス |
| プロジェクトコード | project_code | string | - | プロジェクトコード（デフォルト非表示） |
| 作成日 | creation_date | date | 可 | 作成日（デフォルト非表示） |
| 作成者 | created_by | string | - | 作成者（デフォルト非表示） |
| 開始日 | start_date | date | 可 | 開始日（デフォルト非表示） |
| 目標日 | target_date | date | 可 | 目標日 |
| 出荷日 | shipment_date | date | 可 | 出荷完了日 |
| 担当者 | responsible | string | - | 担当者 |
| 合計金額 | total_price | currency | 可 | 受注合計金額 |

### 保留出荷一覧テーブル

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 出荷参照 | reference | string | 出荷の参照番号 |
| 受注参照 | order_reference | string | 関連受注の参照番号 |
| 割当アイテム数 | allocated_items | number | 割り当てられたアイテム数 |
| ステータス | status | status | 出荷ステータス |

### 返品オーダー一覧テーブル

| 項目名 | フィールド | データ型 | ソート | 説明 |
|--------|-----------|----------|--------|------|
| 参照番号 | reference | string | 可 | 返品オーダーの参照番号 |
| 顧客 | customer__name | string | 可 | 顧客会社名 |
| 顧客参照 | customer_reference | string | - | 顧客側の参照番号 |
| 説明 | description | string | - | 返品オーダーの説明 |
| 明細進捗 | line_items | progress | - | 明細アイテムの完了進捗 |
| ステータス | status | status | - | 返品オーダーステータス |
| 目標日 | target_date | date | 可 | 目標日 |
| 完了日 | complete_date | date | 可 | 完了日 |
| 担当者 | responsible | string | - | 担当者 |
| 合計金額 | total_price | currency | 可 | 返品合計金額 |

### 顧客一覧テーブル

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 会社名 | name | string | 顧客会社名 |
| 説明 | description | string | 会社の説明 |
| Webサイト | website | string | 会社のWebサイト |
| 電話番号 | phone | string | 電話番号 |
| メールアドレス | email | string | メールアドレス |

## イベント仕様

### 01-受注追加ボタン押下

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

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

**処理フロー**：
1. 受注作成フォームモーダルを表示
2. 必要項目を入力
3. 保存ボタン押下で `POST /api/order/so/` を実行
4. 作成成功時、作成された受注の詳細画面に遷移

### 02-返品オーダー追加ボタン押下

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

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

**処理フロー**：
1. 返品オーダー作成フォームモーダルを表示
2. 必要項目を入力
3. 保存ボタン押下で `POST /api/order/ro/` を実行
4. 作成成功時、作成された返品オーダーの詳細画面に遷移

### 03-表示切替（テーブル/カレンダー/パラメトリック）

**トリガー**：セグメントコントロールで表示形式を選択

**処理フロー**：
1. 選択された表示形式をLocalStorageに保存
2. 対応するコンポーネント（テーブル/カレンダー/パラメトリックテーブル）を表示

### 04-一覧行クリック

**トリガー**：テーブル行をクリック

**処理フロー**：
1. クリックされたレコードのIDを取得
2. 対応する詳細画面に遷移
   - 受注 → `/sales/sales-order/:id`
   - 出荷 → `/sales/shipment/:id`
   - 返品オーダー → `/sales/return-order/:id`
   - 顧客 → `/sales/customer/:id`

### 05-フィルター適用

**トリガー**：フィルター条件を変更

**処理フロー**：
1. 選択されたフィルター条件をAPIパラメータに変換
2. 該当APIエンドポイントを再クエリ
3. 結果をテーブルに反映

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 受注追加 | SalesOrder | INSERT | 新規受注レコードの作成 |
| 返品オーダー追加 | ReturnOrder | INSERT | 新規返品オーダーレコードの作成 |
| 一覧表示 | SalesOrder, ReturnOrder, SalesOrderShipment, Company | SELECT | 各種一覧データの取得 |

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

#### SalesOrder（受注作成時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | reference | フォーム入力値 または 自動採番 | 参照番号パターンから自動生成可能 |
| INSERT | customer | フォーム選択値 | 顧客会社ID |
| INSERT | customer_reference | フォーム入力値 | 顧客側の参照番号 |
| INSERT | description | フォーム入力値 | 説明 |
| INSERT | target_date | フォーム入力値 | 目標日 |
| INSERT | status | PENDING (10) | 初期ステータス |
| INSERT | creation_date | 現在日時 | 自動設定 |
| INSERT | created_by | 現在ユーザーID | 自動設定 |

#### ReturnOrder（返品オーダー作成時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | reference | フォーム入力値 または 自動採番 | 参照番号パターンから自動生成可能 |
| INSERT | customer | フォーム選択値 | 顧客会社ID |
| INSERT | customer_reference | フォーム入力値 | 顧客側の参照番号 |
| INSERT | description | フォーム入力値 | 説明 |
| INSERT | target_date | フォーム入力値 | 目標日 |
| INSERT | status | PENDING (10) | 初期ステータス |
| INSERT | creation_date | 現在日時 | 自動設定 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-SO-001 | 成功 | Sales order created successfully | 受注作成成功時 |
| MSG-SO-002 | エラー | Failed to create sales order | 受注作成失敗時 |
| MSG-RO-001 | 成功 | Return order created successfully | 返品オーダー作成成功時 |
| MSG-RO-002 | エラー | Failed to create return order | 返品オーダー作成失敗時 |

## 例外処理

| 例外条件 | 表示内容 | 処理 |
|----------|---------|------|
| 権限不足 | PermissionDenied画面 | `UserRoles.sales_order`のView権限がない場合 |
| API通信エラー | エラー通知 | 一覧取得失敗時、エラーメッセージをトースト表示 |
| データ取得失敗 | 空のテーブル表示 | データが0件の場合、空状態メッセージを表示 |

## 備考

- 各一覧の表示形式（テーブル/カレンダー/パラメトリック）の選択状態はLocalStorageに保存され、次回アクセス時に復元される
- カレンダー表示では、目標日/期日を基準にオーダーをカレンダー上に配置
- パラメトリック表示では、パラメータ値によるフィルタリング・ソートが可能
- 出荷一覧は `shipped: false, order_outstanding: true` のフィルタが常時適用され、保留中の出荷のみ表示

---

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

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

### 推奨読解順序

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

まず、販売オーダー・返品オーダー・会社のデータ型定義を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | 販売関連のAPIエンドポイント定義（174-197行目） |
| 1-2 | ModelType.ts | `src/frontend/lib/enums/ModelType.ts` | salesorder, returnorder等のモデルタイプ定義 |
| 1-3 | Roles.ts | `src/frontend/lib/enums/Roles.ts` | sales_order, return_order等の権限ロール定義 |

**読解のコツ**: TypeScriptのenum定義を確認し、APIパスやモデルタイプの命名規則を把握する。

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

処理の起点となるメインコンポーネントを確認する。

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

**主要処理フロー**:
1. **31-32行目**: ユーザー状態の取得と権限チェック準備
2. **34-47行目**: LocalStorageを使用した表示形式の状態管理
3. **49-160行目**: パネル（タブ）定義 - 受注、出荷、返品オーダー、顧客の4パネル
4. **162-164行目**: 権限チェック - sales_order権限がなければPermissionDenied
5. **166-176行目**: レンダリング - PageDetailとPanelGroupで構成

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SalesOrderTable.tsx | `src/frontend/src/tables/sales/SalesOrderTable.tsx` | 受注一覧テーブルの定義 |
| 3-2 | ReturnOrderTable.tsx | `src/frontend/src/tables/sales/ReturnOrderTable.tsx` | 返品オーダー一覧テーブルの定義 |
| 3-3 | SalesOrderShipmentTable.tsx | `src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx` | 出荷一覧テーブルの定義 |
| 3-4 | CompanyTable.tsx | `src/frontend/src/tables/company/CompanyTable.tsx` | 顧客一覧テーブルの定義 |

**主要処理フロー（SalesOrderTable.tsx）**:
- **63-102行目**: フィルター定義（ステータス、期日、プロジェクトコード等）
- **104-115行目**: 新規受注作成モーダルの定義
- **128-184行目**: テーブルカラム定義

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SalesOrderForms.tsx | `src/frontend/src/forms/SalesOrderForms.tsx` | 受注フォームフィールド定義 |
| 4-2 | ReturnOrderForms.tsx | `src/frontend/src/forms/ReturnOrderForms.tsx` | 返品オーダーフォームフィールド定義 |

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

```
SalesIndex.tsx
    │
    ├─ PageDetail (ページヘッダー)
    │
    └─ PanelGroup
           │
           ├─ SegmentedControlPanel (salesorders)
           │      ├─ SalesOrderTable
           │      ├─ OrderCalendar
           │      └─ SalesOrderParametricTable
           │
           ├─ Panel (shipments)
           │      └─ SalesOrderShipmentTable
           │
           ├─ SegmentedControlPanel (returnorders)
           │      ├─ ReturnOrderTable
           │      ├─ OrderCalendar
           │      └─ ReturnOrderParametricTable
           │
           └─ SegmentedControlPanel (customers)
                  ├─ CompanyTable
                  └─ ParametricCompanyTable
```

### データフロー図

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

ユーザー操作
    │
    ├─ タブ選択 ──────────────▶ PanelGroup ─────────────────────▶ 選択タブの表示
    │
    ├─ 表示切替 ──────────────▶ LocalStorage保存 ───────────────▶ 表示形式変更
    │                           useLocalStorage
    │
    ├─ フィルター適用 ─────────▶ API呼び出し ────────────────────▶ テーブル更新
    │                           GET /api/order/so/
    │                           GET /api/order/ro/
    │
    ├─ 新規作成ボタン ─────────▶ フォームモーダル表示 ───────────▶ 詳細画面遷移
    │                           POST /api/order/so/
    │                           POST /api/order/ro/
    │
    └─ 行クリック ─────────────▶ navigate() ─────────────────────▶ 詳細画面遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SalesIndex.tsx | `src/frontend/src/pages/sales/SalesIndex.tsx` | ソース | メイン画面コンポーネント |
| SalesOrderTable.tsx | `src/frontend/src/tables/sales/SalesOrderTable.tsx` | ソース | 受注一覧テーブル |
| ReturnOrderTable.tsx | `src/frontend/src/tables/sales/ReturnOrderTable.tsx` | ソース | 返品オーダー一覧テーブル |
| SalesOrderShipmentTable.tsx | `src/frontend/src/tables/sales/SalesOrderShipmentTable.tsx` | ソース | 出荷一覧テーブル |
| CompanyTable.tsx | `src/frontend/src/tables/company/CompanyTable.tsx` | ソース | 顧客一覧テーブル |
| SalesOrderForms.tsx | `src/frontend/src/forms/SalesOrderForms.tsx` | ソース | 受注フォーム定義 |
| ReturnOrderForms.tsx | `src/frontend/src/forms/ReturnOrderForms.tsx` | ソース | 返品オーダーフォーム定義 |
| ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | ソース | APIエンドポイント定義 |
| SegmentedControlPanel.tsx | `src/frontend/src/components/panels/SegmentedControlPanel.tsx` | ソース | 表示切替パネルコンポーネント |
| PanelGroup.tsx | `src/frontend/src/components/panels/PanelGroup.tsx` | ソース | タブパネルグループ |
| OrderCalendar.tsx | `src/frontend/src/components/calendar/OrderCalendar.tsx` | ソース | カレンダー表示コンポーネント |
| router.tsx | `src/frontend/src/router.tsx` | ソース | ルーティング定義 |
