# 画面設計書 30-メーカー部品詳細画面

## 概要

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

### 本画面の処理概要

メーカー部品詳細画面は、部品製造元（メーカー）が製造する特定部品の詳細情報を表示・管理するための画面である。InvenTree内部の部品とメーカーの製造品番（MPN: Manufacturer Part Number）を紐付け、製造元情報の追跡とサプライヤー部品との関連付けを可能にする。

**業務上の目的・背景**：部品管理において、同一の内部部品が複数のメーカーから異なる品番で製造されることがある。メーカー部品管理により、各メーカーの製造品番（MPN）と内部部品の対応関係を管理し、調達時の部品選定や製造元追跡を効率的に行うことができる。特に品質問題発生時の製造ロット追跡や、代替品検討時のメーカー比較に有用である。

**画面へのアクセス方法**：メーカー詳細画面のメーカー部品一覧から対象のメーカー部品を選択、または部品詳細画面のサプライヤータブから関連するメーカー部品へリンク、あるいは直接URL `/purchasing/manufacturer-part/:id/*` にアクセスすることで本画面を表示できる。

**主要な操作・処理内容**：
1. メーカー部品基本情報の表示・編集
2. 関連する在庫アイテム一覧の表示
3. 関連するサプライヤー部品一覧の表示・管理
4. パラメータの管理
5. 添付ファイル・メモの管理

**画面遷移**：
- 遷移元：メーカー詳細画面、部品詳細画面
- 遷移先：部品詳細画面、メーカー詳細画面、サプライヤー部品詳細画面

**権限による表示制御**：
- `UserRoles.purchase_order` のAdd権限がない場合、複製操作が無効化
- `UserRoles.purchase_order` のChange権限がない場合、編集操作が無効化
- `UserRoles.purchase_order` のDelete権限がない場合、削除操作が無効化
- `UserRoles.stock` のView権限がない場合、在庫タブが非表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|-------------------|
| 25 | 製造元部品管理 | 主機能 | メーカー部品情報の詳細表示・編集・削除処理 |
| 24 | 仕入先部品管理 | 関連機能 | サプライヤー部品一覧の表示 |
| 6 | 部品マスタ管理 | 遷移先機能 | 内部部品へのリンク |

## 画面種別

詳細画面

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/purchasing/manufacturer-part/:id/*` | メーカー部品詳細画面 |

## 入出力項目

### フォーム項目（編集モーダル）

| No | 項目名 | 項目ID | データ型 | 入力形式 | 必須 | 桁数 | 初期値 | バリデーション | 説明 |
|----|--------|--------|----------|----------|------|------|--------|----------------|------|
| 1 | 内部部品 | part | number | 検索選択 | Yes | - | 現在値 | 存在する部品 | 関連付ける内部部品 |
| 2 | メーカー | manufacturer | number | 検索選択 | Yes | - | 現在値 | is_manufacturer=trueの会社 | 製造元企業 |
| 3 | 製造品番 | MPN | string | テキスト | No | 100 | 現在値 | - | メーカーの製造品番 |
| 4 | 説明 | description | string | テキスト | No | 250 | 現在値 | - | メーカー部品の説明 |
| 5 | 外部リンク | link | string | URL | No | 200 | 現在値 | URL形式 | 外部参照URL |

## 表示項目

### 詳細パネル（Details）

**Part Detailsセクション（左上）**

| No | 項目名 | 項目ID | データ型 | 表示形式 | 説明 |
|----|--------|--------|----------|----------|------|
| 1 | 内部部品 | part | link | リンク | 関連付けられた内部部品へのリンク |
| 2 | IPN | part_detail.IPN | string | テキスト（コピー可） | 内部部品番号 |
| 3 | 説明 | part_detail.description | string | テキスト（コピー可） | 内部部品の説明 |

**Manufacturer Detailsセクション（右）**

| No | 項目名 | 項目ID | データ型 | 表示形式 | 説明 |
|----|--------|--------|----------|----------|------|
| 4 | メーカー | manufacturer | link | リンク | 製造元企業へのリンク |
| 5 | 製造品番 | MPN | string | テキスト（コピー可） | メーカーの製造品番 |
| 6 | 説明 | description | string | テキスト（コピー可） | メーカー部品の説明 |
| 7 | 外部リンク | link | link | 外部リンク（コピー可） | 外部参照URL |

### タブパネル

| No | タブ名 | タブID | 表示条件 | 説明 |
|----|--------|--------|----------|------|
| 1 | Manufacturer Part Details | details | 常時 | メーカー部品詳細情報 |
| 2 | Received Stock | stock | UserRoles.stock View権限あり | 関連在庫アイテム一覧 |
| 3 | Suppliers | suppliers | 常時 | 関連サプライヤー部品一覧 |
| 4 | Parameters | parameters | 常時 | パラメータ一覧 |
| 5 | Attachments | attachments | 常時 | 添付ファイル一覧 |
| 6 | Notes | notes | 常時 | メモ |

### ヘッダー情報

| No | 項目名 | データ型 | 表示形式 | 説明 |
|----|--------|----------|----------|------|
| 1 | タイトル | string | 固定テキスト | "Manufacturer Part" |
| 2 | サブタイトル | string | 動的テキスト | "{MPN} - {部品名}" |
| 3 | 画像 | image | サムネイル | 関連部品のサムネイル画像 |

### パンくずリスト

| No | 項目名 | リンク先 | 説明 |
|----|--------|----------|------|
| 1 | Purchasing | /purchasing/ | 購買インデックス画面 |
| 2 | {メーカー名} | /purchasing/manufacturer/{id}/ | メーカー詳細画面 |
| 3 | {MPN} | 現在のURL | 現在のメーカー部品 |

### アクションボタン

| No | ボタン名 | アイコン | 表示条件 | 操作 |
|----|----------|----------|----------|------|
| 1 | Admin | - | 管理者 | 管理画面への遷移 |
| 2 | Duplicate | - | purchase_order Add権限あり | 複製モーダル表示 |
| 3 | Edit | - | purchase_order Change権限あり | 編集モーダル表示 |
| 4 | Delete | - | purchase_order Delete権限あり | 削除確認モーダル表示 |

## イベント仕様

### 画面表示時

| No | イベント | トリガー | 処理内容 |
|----|----------|----------|----------|
| 1 | データ取得 | 画面表示 | useInstanceでメーカー部品データを取得（part_detail, manufacturer_detail含む） |
| 2 | タブ初期化 | データ取得完了 | 最初のタブ（Details）を表示 |

### ボタン操作

| No | イベント | トリガー | 処理内容 |
|----|----------|----------|----------|
| 1 | 編集 | Editボタンクリック | 編集モーダルを表示 |
| 2 | 複製 | Duplicateボタンクリック | 複製モーダルを表示（現在のデータを初期値として設定、follow=true） |
| 3 | 削除 | Deleteボタンクリック | 削除確認モーダルを表示 |
| 4 | Admin | Adminボタンクリック | Django管理画面へ遷移 |

### 編集モーダル

| No | イベント | トリガー | 処理内容 |
|----|----------|----------|----------|
| 1 | 保存 | 保存ボタンクリック | APIでメーカー部品を更新し、画面をリフレッシュ |
| 2 | キャンセル | キャンセルボタンクリック | モーダルを閉じる |

### 複製モーダル

| No | イベント | トリガー | 処理内容 |
|----|----------|----------|----------|
| 1 | 作成 | 保存ボタンクリック | 新規メーカー部品を作成し、作成された部品の詳細画面へ遷移（follow=true） |
| 2 | キャンセル | キャンセルボタンクリック | モーダルを閉じる |

### 削除モーダル

| No | イベント | トリガー | 処理内容 |
|----|----------|----------|----------|
| 1 | 確定 | 削除ボタンクリック | APIでメーカー部品を削除し、関連する内部部品詳細画面へ遷移 |
| 2 | キャンセル | キャンセルボタンクリック | モーダルを閉じる |

## API仕様

### 使用するAPI

| No | API | メソッド | 用途 |
|----|-----|----------|------|
| 1 | `/api/company/part/manufacturer/` | GET | メーカー部品一覧取得 |
| 2 | `/api/company/part/manufacturer/{id}/` | GET | メーカー部品詳細取得 |
| 3 | `/api/company/part/manufacturer/{id}/` | PATCH | メーカー部品更新 |
| 4 | `/api/company/part/manufacturer/` | POST | メーカー部品作成（複製時） |
| 5 | `/api/company/part/manufacturer/{id}/` | DELETE | メーカー部品削除 |

### データ取得パラメータ

```json
{
  "part_detail": true,
  "manufacturer_detail": true
}
```

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

### 編集時

| No | テーブル | 操作 | 更新カラム |
|----|----------|------|------------|
| 1 | company_manufacturerpart | UPDATE | part, manufacturer, MPN, description, link |

### 複製時

| No | テーブル | 操作 | 挿入カラム |
|----|----------|------|------------|
| 1 | company_manufacturerpart | INSERT | part, manufacturer, MPN, description, link |

### 削除時

| No | テーブル | 操作 | 条件 |
|----|----------|------|------|
| 1 | company_manufacturerpart | DELETE | pk = 対象ID |

## メッセージ仕様

| No | メッセージID | メッセージ内容 | 表示タイミング |
|----|--------------|----------------|----------------|
| 1 | MSG-MP-001 | Edit Manufacturer Part | 編集モーダルタイトル |
| 2 | MSG-MP-002 | Add Manufacturer Part | 複製モーダルタイトル |
| 3 | MSG-MP-003 | Delete Manufacturer Part | 削除確認モーダルタイトル |
| 4 | MSG-MP-004 | Manufacturer Part Actions | アクションドロップダウンツールチップ |

## 例外処理

| No | 例外 | 処理 |
|----|------|------|
| 1 | データ取得失敗 | エラーメッセージを表示、InstanceDetailコンポーネントがエラー状態を管理 |
| 2 | 更新失敗 | APIエラーメッセージをモーダル内に表示 |
| 3 | 削除失敗 | APIエラーメッセージをモーダル内に表示 |
| 4 | 権限エラー | InstanceDetailのrequiredPermissionチェックでアクセス拒否 |

## 備考

- メーカー部品は、内部部品（Part）とメーカー（is_manufacturer=trueのCompany）を紐付けるエンティティである
- 1つの内部部品に対して複数のメーカー部品を登録可能（複数メーカーからの同一部品）
- サプライヤー部品（SupplierPart）はメーカー部品への参照を持つことができ、サプライヤーが扱う部品の製造元情報を追跡可能
- 削除時は関連する内部部品の詳細画面に遷移する（サプライヤー部品詳細と同じパターン）
- 複製時はfollow=trueにより、作成された新しいメーカー部品の詳細画面に自動遷移する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | manufacturer_part_listエンドポイント定義（135行目付近） |
| 1-2 | ModelType.ts | `src/frontend/lib/enums/ModelType.ts` | manufacturerpart型定義 |

**主要データ構造**:
- `manufacturerPart`: メーカー部品データ
  - `pk`: 主キー
  - `part`: 関連内部部品ID
  - `part_detail`: 内部部品詳細（name, IPN, description, image, thumbnail）
  - `manufacturer`: メーカーID
  - `manufacturer_detail`: メーカー詳細（name, pk）
  - `MPN`: 製造品番
  - `description`: 説明
  - `link`: 外部リンク

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ManufacturerPartDetail.tsx | `src/frontend/src/pages/company/ManufacturerPartDetail.tsx` | メイン画面コンポーネント |

**主要処理フロー**:
1. **47-64行目**: useInstanceでメーカー部品データを取得（part_detail, manufacturer_detail含む）
2. **66-153行目**: detailsPanelの構築（Part Details, Manufacturer Details）
3. **155-205行目**: タブパネルの定義（6つのタブ）
4. **207-235行目**: 編集・複製・削除モーダルの設定
5. **237-263行目**: アクションボタンの権限制御
6. **265-276行目**: パンくずリスト構築
7. **278-317行目**: InstanceDetail/PageDetail/PanelGroupによるレンダリング

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

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

**フォームフィールド定義**:
- part: 部品選択（必須）
- manufacturer: メーカー選択（必須）
- MPN: 製造品番（任意）
- description: 説明（任意）
- link: 外部リンク（任意）

#### Step 4: 子コンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SupplierPartTable.tsx | `src/frontend/src/tables/purchasing/SupplierPartTable.tsx` | サプライヤー部品一覧テーブル |
| 4-2 | StockItemTable.tsx | `src/frontend/src/tables/stock/StockItemTable.tsx` | 在庫アイテムテーブル |
| 4-3 | ParametersPanel.tsx | `src/frontend/src/components/panels/ParametersPanel.tsx` | パラメータパネル |
| 4-4 | AttachmentPanel.tsx | `src/frontend/src/components/panels/AttachmentPanel.tsx` | 添付ファイルパネル |
| 4-5 | NotesPanel.tsx | `src/frontend/src/components/panels/NotesPanel.tsx` | メモパネル |

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

```
ManufacturerPartDetail.tsx
    │
    ├─ useInstance (52-64行目)
    │      └─ ApiEndpoints.manufacturer_part_list
    │              パラメータ: part_detail=true, manufacturer_detail=true
    │
    ├─ detailsPanel (66-153行目)
    │      ├─ DetailsImage (137-145行目)
    │      │      └─ 部品画像を表示
    │      │
    │      └─ DetailsTable x 2
    │             ├─ Part Details (tl: 73-97行目)
    │             └─ Manufacturer Details (tr: 99-132行目)
    │
    ├─ panels (155-205行目)
    │      ├─ details: detailsPanel
    │      ├─ stock: StockItemTable (168-175行目)
    │      │      └─ params: { manufacturer_part: id }
    │      ├─ suppliers: SupplierPartTable (181-189行目)
    │      │      └─ props: partId, manufacturerId, manufacturerPartId
    │      ├─ parameters: ParametersPanel (191-194行目)
    │      ├─ attachments: AttachmentPanel (195-198行目)
    │      └─ notes: NotesPanel (199-203行目)
    │
    ├─ useManufacturerPartFields (207行目)
    │
    ├─ useEditApiFormModal (209-215行目)
    │      └─ ApiEndpoints.manufacturer_part_list (PATCH)
    │
    ├─ useCreateApiFormModal (217-226行目)
    │      └─ ApiEndpoints.manufacturer_part_list (POST)
    │              follow=true で新規作成後に遷移
    │
    ├─ useDeleteApiFormModal (228-235行目)
    │      └─ ApiEndpoints.manufacturer_part_list (DELETE)
    │              削除後は内部部品詳細へ遷移
    │
    └─ render (278-317行目)
           ├─ InstanceDetail
           │      └─ requiredPermission: ModelType.manufacturerpart
           │
           ├─ PageDetail
           │      ├─ title: "Manufacturer Part"
           │      ├─ subtitle: "{MPN} - {部品名}"
           │      ├─ breadcrumbs
           │      └─ actions: manufacturerPartActions
           │
           └─ PanelGroup
                  └─ pageKey: 'manufacturerpart'
```

### データフロー図

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

URL /purchasing/manufacturer-part/:id
        │
        ▼
    useParams()
        │ id
        ▼
    useInstance ──────────────────▶ API GET
        │                          /api/company/part/manufacturer/{id}/
        │                          ?part_detail=true
        │                          &manufacturer_detail=true
        │
        ▼
    manufacturerPart ─────────────▶ detailsPanel ──────────────────▶ 詳細表示
        │                              │
        │                              ├─ DetailsImage (部品画像)
        │                              ├─ Part Details (部品情報)
        │                              └─ Manufacturer Details (メーカー情報)
        │
        ├────────────────────────▶ StockItemTable ─────────────────▶ 在庫一覧
        │                              └─ manufacturer_part: id
        │
        ├────────────────────────▶ SupplierPartTable ──────────────▶ サプライヤー部品一覧
        │                              ├─ partId: part
        │                              ├─ manufacturerId: manufacturer
        │                              └─ manufacturerPartId: pk
        │
        └────────────────────────▶ ParametersPanel, AttachmentPanel, NotesPanel


[ユーザー操作]                      [処理]                              [結果]

    Edit ─────────────────────────▶ useEditApiFormModal
                                        │
                                        ▼
                                   PATCH /api/company/part/manufacturer/{id}/
                                        │
                                        ▼
                                   refreshInstance() ─────────────▶ 画面リフレッシュ


    Duplicate ────────────────────▶ useCreateApiFormModal
                                        │ initialData: {...manufacturerPart}
                                        │ follow: true
                                        ▼
                                   POST /api/company/part/manufacturer/
                                        │
                                        ▼
                                   navigate(新規メーカー部品詳細)


    Delete ───────────────────────▶ useDeleteApiFormModal
                                        │
                                        ▼
                                   DELETE /api/company/part/manufacturer/{id}/
                                        │
                                        ▼
                                   navigate(内部部品詳細) ─────────▶ 部品詳細画面へ遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ManufacturerPartDetail.tsx | `src/frontend/src/pages/company/ManufacturerPartDetail.tsx` | ソース | メイン画面コンポーネント |
| CompanyForms.tsx | `src/frontend/src/forms/CompanyForms.tsx` | ソース | useManufacturerPartFieldsフック |
| SupplierPartTable.tsx | `src/frontend/src/tables/purchasing/SupplierPartTable.tsx` | ソース | サプライヤー部品一覧テーブル |
| StockItemTable.tsx | `src/frontend/src/tables/stock/StockItemTable.tsx` | ソース | 在庫アイテムテーブル |
| ParametersPanel.tsx | `src/frontend/src/components/panels/ParametersPanel.tsx` | ソース | パラメータパネル |
| AttachmentPanel.tsx | `src/frontend/src/components/panels/AttachmentPanel.tsx` | ソース | 添付ファイルパネル |
| NotesPanel.tsx | `src/frontend/src/components/panels/NotesPanel.tsx` | ソース | メモパネル |
| ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | ソース | APIエンドポイント定義 |
| InstanceDetail.tsx | `src/frontend/src/components/nav/InstanceDetail.tsx` | ソース | インスタンス詳細ラッパー |
| PageDetail.tsx | `src/frontend/src/components/nav/PageDetail.tsx` | ソース | ページヘッダー |
| PanelGroup.tsx | `src/frontend/src/components/panels/PanelGroup.tsx` | ソース | タブパネル管理 |
