# 画面設計書 29-サプライヤー部品詳細画面

## 概要

本ドキュメントは、InvenTreeシステムのサプライヤー部品詳細画面(SupplierPartDetail)の設計仕様を定義するものである。

### 本画面の処理概要

サプライヤー部品詳細画面は、特定のサプライヤーから調達する部品（サプライヤー部品）の詳細情報を表示・管理するための画面である。内部部品とサプライヤー固有の情報（SKU、価格、パッケージング等）を紐付けて管理する。

**業務上の目的・背景**：調達業務において、同一の内部部品でも複数のサプライヤーから異なる条件（価格、リードタイム、最小発注数等）で調達可能なケースが多い。本画面では、サプライヤー固有の部品情報（SKU、価格、パッケージ単位等）を管理し、最適な調達先選定を支援する。また、在庫情報や発注履歴との連携により、調達状況の把握と発注計画立案を効率化する。

**画面へのアクセス方法**：購買インデックス画面のサプライヤー部品一覧から選択、サプライヤー詳細画面から選択、部品詳細画面のサプライヤー部品タブから選択、または直接URL `/purchasing/supplier-part/:id/*` にアクセスすることで本画面を表示できる。

**主要な操作・処理内容**：
1. サプライヤー部品基本情報の表示・編集（SKU、説明、パッケージング等）
2. 関連する内部部品情報の表示
3. サプライヤー価格情報（価格ブレーク）の管理
4. 受入在庫一覧の表示
5. 関連発注書一覧の表示
6. 部品の複製・削除
7. バーコード操作
8. 添付ファイル・メモの管理

**画面遷移**：
- 遷移元：購買インデックス画面、サプライヤー詳細画面、部品詳細画面
- 遷移先：部品詳細画面、サプライヤー詳細画面、メーカー部品詳細画面、発注書詳細画面、在庫アイテム詳細画面

**権限による表示制御**：
- `UserRoles.purchase_order` のView権限がない場合、本画面にアクセスできない
- `UserRoles.purchase_order` のChange権限がない場合、編集操作が無効化
- `UserRoles.purchase_order` のDelete権限がない場合、削除操作が無効化
- `UserRoles.purchase_order` のAdd権限がない場合、複製操作が無効化

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | サプライヤー部品管理 | 主機能 | サプライヤー部品の詳細表示・編集 |
| 6 | 部品価格管理 | 補助機能 | サプライヤー価格情報の表示 |

## 画面種別

詳細画面（タブ切替型）

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/purchasing/supplier-part/:id/*` | サプライヤー部品詳細画面 |

## 入出力項目

### サプライヤー部品編集フォーム

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| 部品 | part | number | ○ | 内部部品ID |
| サプライヤー | supplier | number | ○ | サプライヤー会社ID |
| SKU | SKU | string | ○ | サプライヤー固有の部品番号 |
| 説明 | description | string | - | サプライヤー部品の説明 |
| メーカー | manufacturer | number | - | メーカー会社ID |
| MPN | manufacturer_part | number | - | メーカー部品ID |
| パッケージング | packaging | string | - | パッケージ形態 |
| パック数量 | pack_quantity | string | - | 1パックあたりの数量 |
| 外部リンク | link | string | - | サプライヤーの製品ページURL |
| メモ | note | string | - | メモ |
| 有効フラグ | active | boolean | - | 有効/無効 |

## 表示項目

### 詳細パネル - 部品情報

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 内部部品 | part | link | 内部部品へのリンク |
| IPN | part_detail.IPN | string | 内部部品番号 |
| 部品説明 | part_detail.description | string | 内部部品の説明 |
| 外部リンク | link | link | サプライヤーの製品ページURL |
| メモ | note | string | メモ |

### 詳細パネル - サプライヤー情報

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| サプライヤー | supplier | link | サプライヤー会社へのリンク |
| SKU | SKU | string | サプライヤー固有の部品番号 |
| 説明 | description | string | サプライヤー部品の説明 |
| メーカー | manufacturer | link | メーカー会社へのリンク |
| MPN | manufacturer_part | link | メーカー部品へのリンク |

### 詳細パネル - パッケージング情報

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| パッケージング | packaging | string | パッケージ形態 |
| パック数量 | pack_quantity | string | 1パックあたりの数量 |

### 詳細パネル - 可用性情報

| 項目名 | フィールド | データ型 | 説明 |
|--------|-----------|----------|------|
| 在庫数 | in_stock | number | 現在の在庫数量 |
| 発注中数量 | on_order | number | 発注中の数量 |
| サプライヤー在庫 | available | number | サプライヤー側の在庫数 |
| 可用性更新日 | availability_updated | date | 可用性情報の最終更新日 |

### ステータスバッジ

| バッジ名 | 表示条件 | 色 |
|---------|---------|-----|
| Inactive | active == false | red |
| In Stock | active && in_stock > 0 | green |
| No Stock | active && in_stock == 0 | red |
| On Order | on_order > 0 | blue |

### タブ構成

| タブ名 | 内容 |
|--------|------|
| Supplier Part Details | サプライヤー部品の詳細情報 |
| Received Stock | 受入在庫一覧 |
| Purchase Orders | 関連発注書一覧 |
| Supplier Pricing | サプライヤー価格情報（価格ブレーク） |
| Parameters | パラメータ一覧 |
| Attachments | 添付ファイル一覧 |
| Notes | メモ |

## イベント仕様

### 01-サプライヤー部品編集ボタン押下

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

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

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

### 02-サプライヤー部品複製ボタン押下

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

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

**処理フロー**：
1. 複製フォームモーダルを表示（現在のデータで初期化）
2. 必要に応じて編集
3. 保存ボタン押下で `POST /api/company/part/` を実行
4. 成功時、新規作成されたサプライヤー部品の詳細画面に遷移

### 03-サプライヤー部品削除ボタン押下

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

**前提条件**：`UserRoles.purchase_order` のDelete権限を保持

**処理フロー**：
1. 削除確認モーダルを表示
2. 確認後、`DELETE /api/company/part/:id/` を実行
3. 成功時、関連する内部部品の詳細画面に遷移

### 04-価格ブレーク追加

**トリガー**：価格タブ内の「Add Price Break」ボタンをクリック

**処理フロー**：
1. 価格ブレーク追加フォームモーダルを表示
2. 数量、価格等を入力
3. 保存ボタン押下で `POST /api/company/price-break/` を実行
4. 成功時、価格一覧をリフレッシュ

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| サプライヤー部品編集 | SupplierPart | UPDATE | サプライヤー部品情報の更新 |
| サプライヤー部品複製 | SupplierPart | INSERT | 新規サプライヤー部品の作成 |
| サプライヤー部品削除 | SupplierPart | DELETE | サプライヤー部品の削除 |
| 価格ブレーク追加 | SupplierPriceBreak | INSERT | 価格ブレークの追加 |
| 価格ブレーク編集 | SupplierPriceBreak | UPDATE | 価格ブレークの更新 |
| 価格ブレーク削除 | SupplierPriceBreak | DELETE | 価格ブレークの削除 |

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

#### SupplierPart（サプライヤー部品編集時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | part | フォーム選択値 | 内部部品ID |
| UPDATE | supplier | フォーム選択値 | サプライヤー会社ID |
| UPDATE | SKU | フォーム入力値 | サプライヤー部品番号 |
| UPDATE | description | フォーム入力値 | 説明 |
| UPDATE | manufacturer_part | フォーム選択値 | メーカー部品ID |
| UPDATE | packaging | フォーム入力値 | パッケージング |
| UPDATE | pack_quantity | フォーム入力値 | パック数量 |
| UPDATE | link | フォーム入力値 | 外部リンク |
| UPDATE | note | フォーム入力値 | メモ |
| UPDATE | active | フォーム入力値 | 有効フラグ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-SP-001 | 成功 | Supplier part updated | 編集成功時 |
| MSG-SP-002 | 成功 | Supplier part created | 複製成功時 |
| MSG-SP-003 | 成功 | Supplier part deleted | 削除成功時 |
| MSG-SP-004 | 成功 | Price break added | 価格ブレーク追加成功時 |

## 例外処理

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

## 備考

- サプライヤー部品は内部部品とサプライヤーの組み合わせで一意
- SKUはサプライヤー内で一意であることが推奨される
- メーカー部品との関連付けにより、同一のメーカー部品を複数のサプライヤーから調達する場合の紐付けが可能
- 削除後の遷移先は、元の内部部品の詳細画面

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | supplier_part_list, supplier_part_pricing_list（133-134行目） |
| 1-2 | ModelType.ts | `src/frontend/lib/enums/ModelType.ts` | supplierpartモデルタイプ |

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

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

**主要処理フロー**:
1. **59-72行目**: useInstanceフックでサプライヤー部品データを取得
2. **74-241行目**: 詳細パネルの定義（部品情報、サプライヤー情報、パッケージング、可用性）
3. **243-302行目**: タブパネル定義
4. **304-331行目**: アクションボタン定義
5. **333-361行目**: フォームモーダル定義
6. **363-374行目**: パンくずリスト定義
7. **376-406行目**: ステータスバッジ定義

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SupplierPriceBreakTable.tsx | `src/frontend/src/tables/purchasing/SupplierPriceBreakTable.tsx` | 価格ブレーク一覧 |
| 3-2 | PurchaseOrderTable.tsx | `src/frontend/src/tables/purchasing/PurchaseOrderTable.tsx` | 発注書一覧 |
| 3-3 | StockItemTable.tsx | `src/frontend/src/tables/stock/StockItemTable.tsx` | 在庫アイテム一覧 |

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

```
SupplierPartDetail.tsx
    │
    ├─ useInstance (サプライヤー部品データ取得)
    │      └─ GET /api/company/part/:id/
    │
    ├─ PageDetail (ページヘッダー)
    │      ├─ DetailsBadge × 4 (ステータス表示)
    │      └─ Actions
    │             ├─ AdminButton
    │             ├─ BarcodeActionDropdown
    │             └─ OptionsActionDropdown
    │
    └─ PanelGroup
           │
           ├─ Panel (details)
           │      └─ ItemDetailsGrid
           │             ├─ DetailsImage
           │             └─ DetailsTable × 4
           │
           ├─ Panel (stock)
           │      └─ StockItemTable
           │
           ├─ Panel (purchaseorders)
           │      └─ PurchaseOrderTable
           │
           ├─ Panel (pricing)
           │      └─ SupplierPriceBreakTable
           │
           ├─ ParametersPanel
           ├─ AttachmentPanel
           └─ NotesPanel
```

### データフロー図

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

URL /:id ────────────────────▶ useInstance ────────────────────▶ 詳細表示
                                GET /api/company/part/:id/

Edit ────────────────────────▶ useEditApiFormModal ────────────▶ 更新
                                PATCH /api/company/part/:id/

Duplicate ───────────────────▶ useCreateApiFormModal ──────────▶ 新規作成
                                POST /api/company/part/            → 詳細画面遷移

Delete ──────────────────────▶ useDeleteApiFormModal ──────────▶ 削除
                                DELETE /api/company/part/:id/      → 部品詳細遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SupplierPartDetail.tsx | `src/frontend/src/pages/company/SupplierPartDetail.tsx` | ソース | メイン画面コンポーネント |
| SupplierPriceBreakTable.tsx | `src/frontend/src/tables/purchasing/SupplierPriceBreakTable.tsx` | ソース | 価格ブレーク一覧 |
| PurchaseOrderTable.tsx | `src/frontend/src/tables/purchasing/PurchaseOrderTable.tsx` | ソース | 発注書一覧 |
| StockItemTable.tsx | `src/frontend/src/tables/stock/StockItemTable.tsx` | ソース | 在庫アイテム一覧 |
| CompanyForms.tsx | `src/frontend/src/forms/CompanyForms.tsx` | ソース | useSupplierPartFieldsフォーム定義 |
| formatDecimal.ts | `src/frontend/lib/functions/Formatting.ts` | ソース | 数値フォーマット関数 |
