# 画面設計書 27-購入注文詳細画面

## 概要

本ドキュメントは、InvenTree Flutterアプリケーションにおける「購入注文詳細画面」の設計仕様を定義する。購入注文（PurchaseOrder）の詳細情報を表示し、注文のライフサイクル管理（発行、完了、キャンセル）や明細行の管理、受入処理を行う画面である。

### 本画面の処理概要

購入注文詳細画面は、選択した購入注文の詳細情報を3つのタブ（詳細、ラインアイテム、受領済み）に分けて表示する画面である。ユーザーは注文の編集、明細行の追加、注文の発行・完了・キャンセルなどの操作を行える。

**業務上の目的・背景**：購買管理において、発注した注文の詳細を確認し、そのライフサイクルを管理することは必須の機能である。本画面では、注文ステータスに応じたアクション（発行、完了、キャンセル）を提供し、バーコードスキャンによる受入処理もサポートする。これにより、購買担当者は発注から受入までの一連の業務をモバイル端末で完結できる。

**画面へのアクセス方法**：
- 購入注文一覧画面から注文をタップ
- バーコードスキャンで購入注文を識別した場合

**主要な操作・処理内容**：
1. 購入注文詳細情報の表示（サプライヤー、ステータス、日付等）
2. 購入注文の編集
3. ラインアイテム（明細行）の追加
4. 注文の発行（Issue）
5. 注文の完了（Complete）
6. 注文のキャンセル
7. バーコードスキャンによる受入処理
8. 画像撮影・添付ファイルアップロード
9. ノート・パラメータ・添付ファイルの閲覧

**画面遷移**：
- 遷移元：購入注文一覧画面、バーコードスキャン画面
- 遷移先：会社詳細画面、在庫ロケーション詳細画面、追加明細一覧画面、ノート画面、パラメータ画面、添付ファイル画面、ラインアイテム詳細画面

**権限による表示制御**：
- 編集ボタンは `order.canEdit` がtrueの場合のみ表示
- 各アクションボタンは `order.canCreate` がtrueの場合のみ表示
- カメラボタンは `showCameraShortcut && order.canEdit` の場合のみ表示
- バーコード受入は `api.supportsBarcodePOReceiveEndpoint && order.isPlaced` の場合のみ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | 発注詳細表示 | 主機能 | 発注の詳細情報（サプライヤー、ステータス、ラインアイテム等）表示 |
| 25 | 発注編集 | 補助機能 | 編集ボタン押下時に発注情報編集フォーム表示 |
| 26 | 発注明細表示 | 補助機能 | ラインアイテムタブで発注明細一覧表示 |
| 27 | 発注明細追加 | 補助機能 | 明細追加ボタン押下時に明細追加フォーム表示 |
| 28 | 発注発行 | 補助機能 | 発行ボタン押下時に発注発行確認ダイアログ表示 |
| 29 | 発注完了 | 補助機能 | 完了ボタン押下時に発注完了フォーム表示 |
| 30 | 発注キャンセル | 補助機能 | キャンセルボタン押下時にキャンセル確認ダイアログ表示 |
| 31 | 追加明細行表示 | 遷移先機能 | 追加明細項目押下時に追加明細一覧画面へ遷移 |
| 47 | 発注受入スキャン | 補助機能 | バーコードスキャンで発注品を受け入れ |
| 54 | 添付ファイル表示 | 補助機能 | 添付ファイル項目押下時に添付ファイル一覧表示 |
| 55 | 添付ファイルアップロード | 補助機能 | カメラボタン押下時に画像撮影・アップロード |
| 56 | ノート表示・編集 | 遷移先機能 | ノート項目押下時にノート画面へ遷移 |
| 39 | 会社詳細表示 | 遷移先機能 | サプライヤー項目押下時に会社詳細画面へ遷移 |

## 画面種別

詳細

## URL/ルーティング

Flutter Navigator によるプッシュ遷移。`PurchaseOrderDetailWidget` ウィジェットに `InvenTreePurchaseOrder` インスタンスを渡して表示する。

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| order | 入力 | InvenTreePurchaseOrder | Yes | 表示する購入注文オブジェクト |

## 表示項目

### タブ構成

| タブ名 | 内容 | ウィジェット |
|--------|------|-------------|
| Details | 注文詳細情報 | ListView(orderTiles) |
| Line Items | 明細行一覧 | PaginatedPOLineList |
| Received | 受領済み在庫 | PaginatedStockItemList |

### 詳細タブ表示項目

| 項目名 | 表示位置 | データ型 | 条件 | 説明 |
|--------|----------|----------|------|------|
| リファレンス | headerTile.title | String | 常時 | 注文リファレンス番号 |
| 説明 | headerTile.subtitle | String | 常時 | 注文の説明 |
| サプライヤーサムネイル | headerTile.leading | Image | supplier != null | サプライヤー会社画像 |
| ステータス | headerTile.trailing | String | 常時 | ステータスラベル（色付き） |
| プロジェクトコード | ListTile | String | supportProjectCodes && hasProjectCode | プロジェクトコード情報 |
| サプライヤー | ListTile | String | supplier != null | サプライヤー会社名 |
| サプライヤーリファレンス | ListTile | String | supplierReference.isNotEmpty | サプライヤー側の注文番号 |
| 配送先 | ListTile | String | destination != null | 配送先ロケーション |
| ラインアイテム進捗 | ListTile + ProgressBar | String | 常時 | 完了/総数と進捗バー |
| 追加明細行 | ListTile | int | 常時 | 追加明細行の件数 |
| 合計金額 | ListTile | String | 常時 | 注文の合計金額 |
| 発行日 | ListTile | String | issueDate.isNotEmpty | 注文発行日 |
| 開始日 | ListTile | String | startDate.isNotEmpty | 注文開始日 |
| 目標日 | ListTile | String | targetDate.isNotEmpty | 目標完了日 |
| 完了日 | ListTile | String | completionDate.isNotEmpty | 実際の完了日 |
| 責任者 | ListTile | String | responsibleName.isNotEmpty | 担当者/グループ |
| ノート | ListTile | - | 常時 | ノート画面へのリンク |
| パラメータ | ListTile | int | parameterCount > 0 | パラメータ件数と画面リンク |
| 添付ファイル | ListTile | int | attachmentCount > 0 | 添付ファイル件数と画面リンク |

## イベント仕様

### 1-編集ボタン押下

AppBarの編集ボタンをタップすると、購入注文編集フォームが表示される。

**処理フロー**：
1. `IconButton.onPressed` で `editOrder(context)` を呼び出し
2. `order.formFields()` でフォームフィールドを取得
3. supplierフィールドを除外（サプライヤーは編集不可）
4. contact、project_codeフィールドをAPIサポート状況に応じて除外
5. `order.editForm()` で編集フォームを表示
6. 成功時に画面をリフレッシュし、成功メッセージを表示

### 2-明細追加ボタン押下

SpeedDialの「明細追加」ボタンをタップすると、ラインアイテム追加フォームが表示される。

**表示条件**：`order.canCreate && order.isPending`

**処理フロー**：
1. `SpeedDialChild.onTap` で `_addLineItem(context)` を呼び出し
2. `InvenTreePOLineItem().formFields()` でフォームフィールドを取得
3. partフィールドにサプライヤーフィルタを設定
4. orderフィールドに現在の注文PKを設定
5. `InvenTreePOLineItem().createForm()` で作成フォームを表示
6. 成功時に画面をリフレッシュし、成功メッセージを表示

### 3-発行ボタン押下

SpeedDialの「発行」ボタンをタップすると、注文発行確認ダイアログが表示される。

**表示条件**：`order.canCreate && order.isPending`

**処理フロー**：
1. `SpeedDialChild.onTap` で `_issueOrder(context)` を呼び出し
2. `confirmationDialog()` で確認ダイアログを表示
3. 承認時に `order.issueOrder()` を呼び出し（POST `${url}issue/`）
4. 成功時に画面をリフレッシュ

### 4-完了ボタン押下

SpeedDialの「完了」ボタンをタップすると、注文完了フォームが表示される。

**表示条件**：`order.canCreate && order.isOpen && !order.isPending`

**処理フロー**：
1. `SpeedDialChild.onTap` で `_completeOrder(context)` を呼び出し
2. `launchApiForm()` で完了フォームを表示（accept_incompleteオプション付き）
3. POST `order/po/${order.pk}/complete/` を実行
4. 成功時に画面をリフレッシュ

### 5-キャンセルボタン押下

SpeedDialの「キャンセル」ボタンをタップすると、キャンセル確認ダイアログが表示される。

**表示条件**：`order.canCreate && order.isOpen`

**処理フロー**：
1. `SpeedDialChild.onTap` で `_cancelOrder(context)` を呼び出し
2. `confirmationDialog()` で確認ダイアログを表示
3. 承認時に `order.cancelOrder()` を呼び出し（POST `${url}cancel/`）
4. 成功時に画面をリフレッシュ

### 6-カメラボタン押下

SpeedDialのカメラボタンをタップすると、画像撮影・アップロード処理が実行される。

**表示条件**：`showCameraShortcut && order.canEdit`

**処理フロー**：
1. `SpeedDialChild.onTap` で `_uploadImage(context)` を呼び出し
2. `InvenTreeAttachment().uploadImage()` で画像撮影・アップロード
3. 成功時に画面をリフレッシュ

### 7-バーコード受入スキャン

バーコードボタンをタップすると、発注品受入スキャンモードが起動する。

**表示条件**：`api.supportsBarcodePOReceiveEndpoint && order.isPlaced`

**処理フロー**：
1. `SpeedDialChild.onTap` で `scanBarcode()` を呼び出し
2. `POReceiveBarcodeHandler(purchaseOrder: order)` をハンドラとして設定
3. スキャン完了後に画面をリフレッシュ

### 8-バーコード明細追加スキャン

バーコードボタンをタップすると、明細追加スキャンモードが起動する。

**表示条件**：`order.isPending && api.supportsBarcodePOAddLineEndpoint`

**処理フロー**：
1. `SpeedDialChild.onTap` で `scanBarcode()` を呼び出し
2. `POAllocateBarcodeHandler(purchaseOrder: order)` をハンドラとして設定

### 9-サプライヤータップ

サプライヤーListTileをタップすると、会社詳細画面へ遷移する。

**処理フロー**：
1. `ListTile.onTap` で `supplier.goToDetailPage(context)` を呼び出し
2. `Navigator.push` で会社詳細画面へ遷移

### 10-配送先タップ

配送先ListTileをタップすると、在庫ロケーション詳細画面へ遷移する。

**処理フロー**：
1. `ListTile.onTap` で `destination.goToDetailPage(context)` を呼び出し
2. `Navigator.push` で在庫ロケーション詳細画面へ遷移

### 11-追加明細行タップ

追加明細行ListTileをタップすると、追加明細一覧画面へ遷移する。

**処理フロー**：
1. `ListTile.onTap` で `Navigator.push` を呼び出し
2. `POExtraLineListWidget` へ遷移

### 12-ノートタップ

ノートListTileをタップすると、ノート画面へ遷移する。

**処理フロー**：
1. `ListTile.onTap` で `Navigator.push` を呼び出し
2. `NotesWidget(order)` へ遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 詳細表示 | PurchaseOrder | SELECT | 購入注文データの取得 |
| 詳細表示 | POLineItem | SELECT | 明細行データの取得 |
| 詳細表示 | StockLocation | SELECT | 配送先ロケーションの取得 |
| 編集 | PurchaseOrder | UPDATE | 購入注文データの更新 |
| 明細追加 | POLineItem | INSERT | 新規明細行の作成 |
| 発行 | PurchaseOrder | UPDATE | ステータスをPLACEDに更新 |
| 完了 | PurchaseOrder | UPDATE | ステータスをCOMPLETEに更新 |
| キャンセル | PurchaseOrder | UPDATE | ステータスをCANCELLEDに更新 |
| 画像アップロード | Attachment | INSERT | 添付ファイルの作成 |

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

#### PurchaseOrder テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | pk, reference, description, supplier, status, issue_date, start_date, target_date, completion_date, total_price, responsible | pk指定 | APIエンドポイント: /api/order/po/{pk}/ |
| UPDATE（編集） | reference, description, project_code, destination, start_date, target_date, link, responsible, contact | フォーム入力値 | editForm()経由 |
| UPDATE（発行） | status | PLACED | POST /api/order/po/{pk}/issue/ |
| UPDATE（完了） | status | COMPLETE | POST /api/order/po/{pk}/complete/ |
| UPDATE（キャンセル） | status | CANCELLED | POST /api/order/po/{pk}/cancel/ |

#### POLineItem テーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | pk, order, part, quantity, received, reference, purchase_price | order={pk}フィルタ | APIエンドポイント: /api/order/po-line/ |
| INSERT | order, part, reference, quantity, purchase_price, destination, notes, link | フォーム入力値 | createForm()経由 |

## メッセージ仕様

| メッセージID | メッセージ種別 | 表示条件 | メッセージ内容 |
|-------------|---------------|----------|---------------|
| MSG_EDIT_SUCCESS | 成功 | 編集成功時 | L10().purchaseOrderUpdated |
| MSG_LINE_UPDATED | 成功 | 明細追加成功時 | L10().lineItemUpdated |
| MSG_ISSUE_CONFIRM | 確認 | 発行ボタン押下時 | L10().issueOrder |
| MSG_CANCEL_CONFIRM | 確認 | キャンセルボタン押下時 | L10().cancelOrder |
| MSG_COMPLETE | フォーム | 完了ボタン押下時 | L10().completeOrder |

## 例外処理

| 例外条件 | 処理内容 | ユーザーへの表示 |
|---------|---------|-----------------|
| APIエラー | エラーをSentryに報告 | フォームエラーメッセージを表示 |
| 発行失敗（非Pending状態） | issueOrder()が早期リターン | 処理されない（ボタン非表示で回避） |
| キャンセル失敗（非Open状態） | cancelOrder()が早期リターン | 処理されない（ボタン非表示で回避） |
| サプライヤー部品未定義 | エラータイルを表示 | "supplier part not defined" |

## 備考

- タブは3つ：Details（詳細）、Line Items（明細）、Received（受領済み）
- ステータス色は `api.PurchaseOrderStatus.color()` で取得
- ラインアイテム進捗は ProgressBar で視覚化（完了数/総数）
- カメラショートカット表示は `INV_PO_SHOW_CAMERA` 設定で制御
- プロジェクトコード対応は `api.supportsProjectCodes` と `PROJECT_CODES_ENABLED` グローバル設定で判定
- 配送先対応は `api.supportsPurchaseOrderDestination` で判定
- 注文ステータスの判定：
  - isOpen: PENDING, PLACED, ON_HOLD のいずれか
  - isPending: PENDING, ON_HOLD のいずれか
  - isPlaced: PLACED のみ
- 編集時にsupplierフィールドは編集不可（除外）
- contactフィールドは `api.supportsContactModel` の場合のみ表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | purchase_order.dart | `lib/inventree/purchase_order.dart` | InvenTreePurchaseOrderクラス（18-157行）。URL="order/po/"、isOpen, isPending, isPlaced判定、issueOrder(), cancelOrder()メソッド |
| 1-2 | purchase_order.dart | `lib/inventree/purchase_order.dart` | InvenTreePOLineItemクラス（159-313行）。URL="order/po-line/"、received, isComplete, progressString、receive()メソッド |
| 1-3 | orders.dart | `lib/inventree/orders.dart` | InvenTreeOrder基底クラス。共通フィールド（reference, description, status等）と機能 |

**読解のコツ**: `InvenTreePurchaseOrder` は `InvenTreeOrder` を継承している。ステータス判定メソッド（isOpen, isPending, isPlaced）はAPI側のステータスコードをチェックしている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | purchase_order_detail.dart | `lib/widget/order/purchase_order_detail.dart` | PurchaseOrderDetailWidget（36-43行）の定義。orderをコンストラクタで受け取る |
| 2-2 | purchase_order_detail.dart | `lib/widget/order/purchase_order_detail.dart` | _PurchaseOrderDetailState（45-632行）。RefreshableStateを継承 |

**主要処理フロー**:
1. **36-43行**: `PurchaseOrderDetailWidget` StatefulWidgetの定義
2. **62-70行**: `getAppBarTitle()` で "Purchase Order - {reference}" を返す
3. **72-89行**: `appBarActions()` で編集ボタンを構築
4. **91-156行**: `actionButtons()` でカメラ、明細追加、発行、完了、キャンセルボタンを構築
5. **240-277行**: `barcodeButtons()` でバーコード受入、明細追加スキャンボタンを構築
6. **614-621行**: `getTabIcons()` でタブアイコンを定義
7. **623-631行**: `getTabs()` で各タブのコンテンツを定義

#### Step 3: データ取得処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | purchase_order_detail.dart | `lib/widget/order/purchase_order_detail.dart` | request()メソッド（279-361行）。注文リロード、ステータスロード、ラインアイテム取得、設定読込 |

**主要処理フロー**:
- **281行**: `widget.order.reload()` で注文データを再取得
- **283行**: `api.PurchaseOrderStatus.load()` でステータスマスタをロード
- **285行**: `widget.order.getLineItems()` でラインアイテムを取得
- **287-296行**: 設定値（カメラショートカット、プロジェクトコード対応）を読み込み
- **298-304行**: 完了済みラインアイテム数をカウント
- **306-324行**: パラメータ数、添付ファイル数を非同期で取得
- **326-349行**: 配送先ロケーションを取得
- **351-360行**: 追加明細行数を取得

#### Step 4: タイル構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | purchase_order_detail.dart | `lib/widget/order/purchase_order_detail.dart` | headerTile()（391-405行）とorderTiles()（407-612行）。詳細タブの各タイルを構築 |

**主要処理フロー**:
- **391-405行**: ヘッダーカード（リファレンス、説明、サムネイル、ステータス）
- **414-424行**: プロジェクトコードタイル
- **426-438行**: サプライヤータイル（タップで会社詳細へ遷移）
- **450-461行**: 配送先タイル（タップでロケーション詳細へ遷移）
- **467-480行**: ラインアイテム進捗タイル（ProgressBar付き）
- **483-500行**: 追加明細行タイル（タップで一覧へ遷移）
- **502-513行**: 合計金額タイル
- **515-553行**: 日付タイル群（発行日、開始日、目標日、完了日）
- **555-569行**: 責任者タイル
- **571-584行**: ノートタイル（タップでノート画面へ遷移）
- **586-609行**: パラメータ・添付ファイルタイル

#### Step 5: アクション処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | purchase_order_detail.dart | `lib/widget/order/purchase_order_detail.dart` | _addLineItem()（158-177行）、_issueOrder()（190-204行）、_completeOrder()（206-222行）、_cancelOrder()（224-238行） |

**主要処理フロー**:
- **158-177行**: 明細追加フォーム。partフィールドにサプライヤーフィルタ設定
- **190-204行**: 発行確認ダイアログ。承認時に `order.issueOrder()` 呼び出し
- **206-222行**: 完了フォーム。`accept_incomplete` オプション付きで `/complete/` にPOST
- **224-238行**: キャンセル確認ダイアログ。承認時に `order.cancelOrder()` 呼び出し

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

```
PurchaseOrderDetailWidget (StatefulWidget)
    |
    +-- _PurchaseOrderDetailState (RefreshableState)
           |
           +-- request()
           |      |
           |      +-- widget.order.reload()
           |      +-- api.PurchaseOrderStatus.load()
           |      +-- widget.order.getLineItems()
           |      +-- InvenTreeSettingsManager().getBool()
           |      +-- api.getGlobalBooleanSetting()
           |      +-- InvenTreeParameter().countParameters()
           |      +-- InvenTreeAttachment().countAttachments()
           |      +-- InvenTreeStockLocation().get()
           |      +-- InvenTreePOExtraLineItem().count()
           |
           +-- getTabs()
           |      |
           |      +-- ListView(orderTiles())
           |      |      |
           |      |      +-- headerTile()
           |      |      +-- supplier.goToDetailPage() --> CompanyDetailWidget
           |      |      +-- destination.goToDetailPage() --> LocationDisplayWidget
           |      |      +-- POExtraLineListWidget
           |      |      +-- NotesWidget
           |      |      +-- ShowParametersItem --> ParameterListWidget
           |      |      +-- ShowAttachmentsItem --> AttachmentWidget
           |      |
           |      +-- PaginatedPOLineList
           |      |      |
           |      |      +-- requestPage() --> InvenTreePOLineItem().listPaginated()
           |      |      +-- buildItem() --> POLineDetailWidget
           |      |
           |      +-- PaginatedStockItemList
           |             |
           |             +-- requestPage() --> InvenTreeStockItem().listPaginated()
           |
           +-- appBarActions()
           |      |
           |      +-- editOrder() --> widget.order.editForm()
           |
           +-- actionButtons()
           |      |
           |      +-- _uploadImage() --> InvenTreeAttachment().uploadImage()
           |      +-- _addLineItem() --> InvenTreePOLineItem().createForm()
           |      +-- _issueOrder() --> widget.order.issueOrder()
           |      +-- _completeOrder() --> launchApiForm() POST /complete/
           |      +-- _cancelOrder() --> widget.order.cancelOrder()
           |
           +-- barcodeButtons()
                  |
                  +-- scanBarcode(POReceiveBarcodeHandler)
                  +-- scanBarcode(POAllocateBarcodeHandler)
```

### データフロー図

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

InvenTreePurchaseOrder
        |
        +-----------> PurchaseOrderDetailWidget
                              |
                              +-- request()
                              |      |
                              |      +-- reload() --> API GET /api/order/po/{pk}/
                              |      |
                              |      +-- getLineItems() --> API GET /api/order/po-line/?order={pk}
                              |      |
                              |      +-- countParameters() --> parameterCount
                              |      |
                              |      +-- countAttachments() --> attachmentCount
                              |      |
                              |      +-- StockLocation.get() --> destination
                              |
                              +-- getTabs()
                                     |
                                     +-- Tab 0: orderTiles() --> ListView
                                     |          |
                                     |          +-- headerTile (reference, status, supplier thumbnail)
                                     |          +-- supplier tile --> onTap --> CompanyDetailWidget
                                     |          +-- line items progress (ProgressBar)
                                     |          +-- extra lines --> onTap --> POExtraLineListWidget
                                     |          +-- total price (renderCurrency)
                                     |          +-- dates (issue, start, target, completion)
                                     |          +-- notes --> onTap --> NotesWidget
                                     |
                                     +-- Tab 1: PaginatedPOLineList
                                     |          |
                                     |          +-- API GET /api/order/po-line/?order={pk}
                                     |          +-- ListTile per line item
                                     |          +-- onTap --> POLineDetailWidget
                                     |
                                     +-- Tab 2: PaginatedStockItemList
                                                |
                                                +-- API GET /api/stock/?purchase_order={pk}
                                                +-- ListTile per stock item
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| purchase_order_detail.dart | `lib/widget/order/purchase_order_detail.dart` | ソース | 購入注文詳細画面のメインウィジェット |
| purchase_order.dart | `lib/inventree/purchase_order.dart` | ソース | 購入注文・明細行データモデル |
| orders.dart | `lib/inventree/orders.dart` | ソース | 注文基底クラス |
| po_line_list.dart | `lib/widget/order/po_line_list.dart` | ソース | 明細行一覧ウィジェット |
| po_line_detail.dart | `lib/widget/order/po_line_detail.dart` | ソース | 明細行詳細画面 |
| po_extra_line_list.dart | `lib/widget/order/po_extra_line_list.dart` | ソース | 追加明細行一覧 |
| stock_list.dart | `lib/widget/stock/stock_list.dart` | ソース | 在庫アイテム一覧（受領済みタブ） |
| company.dart | `lib/inventree/company.dart` | ソース | 会社データモデル（サプライヤー） |
| refreshable_state.dart | `lib/widget/refreshable_state.dart` | ソース | リフレッシュ可能なState基底クラス |
| notes_widget.dart | `lib/widget/notes_widget.dart` | ソース | ノート表示・編集ウィジェット |
| attachment_widget.dart | `lib/widget/attachment_widget.dart` | ソース | 添付ファイル一覧ウィジェット |
| parameter_widget.dart | `lib/widget/parameter_widget.dart` | ソース | パラメータ一覧ウィジェット |
| barcode.dart | `lib/barcode/barcode.dart` | ソース | バーコードスキャン基盤 |
| purchase_order.dart | `lib/barcode/purchase_order.dart` | ソース | 発注関連バーコードハンドラ |
| api_form.dart | `lib/api_form.dart` | ソース | APIフォームランチャー |
| dialogs.dart | `lib/widget/dialogs.dart` | ソース | 確認ダイアログ |
| progress.dart | `lib/widget/progress.dart` | ソース | 進捗バーウィジェット |
| preferences.dart | `lib/preferences.dart` | ソース | 設定管理（INV_PO_SHOW_CAMERA等） |
