# 機能設計書 35-受注引当表示

## 概要

本ドキュメントは、InvenTreeモバイルアプリにおける受注引当（Sales Order Allocation）表示機能の設計を定義する。受注引当は、受注明細行に対して在庫アイテムを割り当て、出荷準備状態を管理するための機能である。

### 本機能の処理概要

この機能では、受注または出荷に対する在庫引当情報を一覧表示し、どの在庫アイテムがどの受注明細に割り当てられているかを確認できる。

**業務上の目的・背景**：受注を出荷するためには、まず在庫を受注明細行に引き当てる必要がある。引当とは、特定の在庫アイテムを特定の受注のために予約することである。引当一覧を通じて、どの在庫が受注に割り当てられているか、どこのロケーションにあるかを把握でき、ピッキング作業や出荷準備を効率的に行うことができる。また、引当状況を確認することで、在庫不足や引当漏れを早期に発見できる。

**機能の利用シーン**：
- 出荷詳細画面で引当済み在庫を確認したい場合
- 引当された在庫アイテムの詳細を確認したい場合
- ピッキング作業のために引当リストを参照したい場合

**主要な処理内容**：
1. 受注IDまたは出荷IDに紐づく引当情報をAPIから取得
2. 各引当のパーツ情報、在庫アイテム情報、ロケーション情報を表示
3. 引当タップで在庫アイテム詳細画面へ遷移

**関連システム・外部連携**：InvenTree REST API (`/api/order/so-allocation/`)

**権限による制御**：受注の閲覧権限（`sales_order` ロール）が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | 販売注文詳細画面 | 遷移元画面 | 受注に対する在庫引当情報の表示 |

## 機能種別

データ表示（CRUD操作のRead）/ 一覧表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filters | Map<String, String> | Yes | フィルタ条件（order, shipment等） | - |

### 入力データソース

- 出荷詳細画面からのフィルタ条件
- InvenTree REST API (`/api/order/so-allocation/`)

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| part.fullname | String | パーツのフルネーム |
| part.thumbnail | String | パーツサムネイル画像URL |
| location.pathstring | String | ロケーションのパス文字列 |
| stockItem | InvenTreeStockItem | 在庫アイテムオブジェクト |
| stockItem.serialOrQuantityDisplay | String | シリアル番号または数量表示 |

### 出力先

画面表示（ListTileのリスト形式）

## 処理フロー

### 処理シーケンス

```
1. ウィジェット初期化
   └─ PaginatedSOAllocationListがフィルタを受け取る
2. ページデータ取得
   └─ InvenTreeSalesOrderAllocation().listPaginated()でAPIリクエスト
3. 一覧表示
   └─ 各引当をListTileとして描画
4. アイテムタップ時
   └─ 在庫アイテム詳細画面へ遷移
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示開始] --> B[フィルタ条件受け取り]
    B --> C[APIからデータ取得]
    C --> D{データあり?}
    D -->|Yes| E[ListTileとして一覧表示]
    D -->|No| F[結果なしメッセージ表示]
    E --> G{ユーザー操作}
    G -->|アイテムタップ| H[在庫アイテム詳細画面へ遷移]
    G -->|スクロール| I[次ページ取得]
    H --> J[終了]
    I --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-035-01 | デフォルトフィルタ | part_detail, order_detail, item_detail, location_detailを含めて取得 | 常時 |
| BR-035-02 | ロケーション表示 | ロケーションが設定されていない場合は"Location not set"と表示 | location == null |
| BR-035-03 | ページサイズ | 1ページあたり25件を取得 | 常時 |
| BR-035-04 | 在庫詳細遷移 | タップ時はstockItem.goToDetailPage()で在庫詳細へ遷移 | stockItem != null |

### 計算ロジック

該当なし

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧取得 | order_salesorderallocation | SELECT | フィルタ条件に基づく引当一覧取得 |

### テーブル別操作詳細

#### order_salesorderallocation

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, order_id, line_id, item_id, shipment_id, quantity | フィルタ条件適用 | 各種detail含む |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 401 | 認証エラー | APIトークンが無効 | ログイン画面へ遷移 |
| 403 | 権限エラー | 閲覧権限がない | エラーメッセージ表示 |
| 500 | サーバーエラー | サーバー側の問題 | リトライを促すメッセージ表示 |

### リトライ仕様

プルダウンによるリフレッシュ操作で再取得可能

## トランザクション仕様

読み取り専用のため、トランザクション管理は不要

## パフォーマンス要件

- 1ページあたり25件のデータを取得
- 無限スクロールによる段階的データ読み込み

## セキュリティ考慮事項

- APIアクセスには認証トークンが必要
- 受注の閲覧権限（sales_order）が必要

## 備考

- 引当一覧は主に出荷詳細画面（SOShipmentDetailWidget）から利用される
- 出荷に対する引当のみを表示するため、shipmentフィルタが設定される

---

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

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

### 推奨読解順序

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

引当のデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sales_order.dart | `lib/inventree/sales_order.dart` | InvenTreeSalesOrderAllocationクラスの構造（337-430行目） |

**読解のコツ**: InvenTreeSalesOrderAllocationはInvenTreeModelを継承している。order, stockItem, part, location, shipmentの各プロパティは、対応するdetailフィールドからオブジェクトを生成する。defaultFilters()で必要な詳細情報を指定している。

#### Step 2: 一覧ウィジェットを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | so_allocation_list.dart | `lib/widget/order/so_allocation_list.dart` | PaginatedSOAllocationListの構造全体 |

**主要処理フロー**:
1. **11-21行目**: PaginatedSOAllocationListクラス定義
2. **23-48行目**: _PaginatedSOAllocationListStateクラス
3. **37-48行目**: requestPage()メソッド。APIからページデータ取得
4. **50-68行目**: buildItem()メソッド。引当情報のListTile構築

#### Step 3: 利用箇所を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | so_shipment_detail.dart | `lib/widget/order/so_shipment_detail.dart` | PaginatedSOAllocationListの利用箇所（371-379行目） |

**主要処理フロー**:
- **367-369行目**: タブアイコン定義（Details, Allocated Stock）
- **371-379行目**: PaginatedSOAllocationListの使用（order, shipmentフィルタ付き）

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

```
SOShipmentDetailWidget
    │
    └─ getTabs()
           └─ PaginatedSOAllocationList
                  │
                  └─ _PaginatedSOAllocationListState
                         ├─ prefix → "so_allocation_"
                         ├─ orderingOptions → {} (なし)
                         ├─ filterOptions → {} (なし)
                         ├─ requestPage()
                         │      └─ InvenTreeSalesOrderAllocation().listPaginated()
                         └─ buildItem()
                                ├─ allocation.part取得
                                ├─ allocation.stockItem取得
                                ├─ allocation.location取得
                                └─ onTap → stockItem.goToDetailPage()
```

### データフロー図

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

フィルタ条件 ───────▶ PaginatedSOAllocationList
(order, shipment)           │
                            ▼
                    requestPage()
                            │
                            ▼
                    InvenTreeAPI
                    /api/order/so-allocation/
                    ?part_detail=true
                    &order_detail=true
                    &item_detail=true
                    &location_detail=true
                            │
                            ▼
                    InvenTreePageResponse
                            │
                            ▼
                    buildItem()
                            │
                    ┌───────┼───────┐
                    ▼       ▼       ▼
                パーツ   ロケ    在庫数量
                サムネ   ーション
                            │
                            ▼
                    ListTile一覧表示
                            │
                            ▼
                    onTap → 在庫詳細画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| so_allocation_list.dart | `lib/widget/order/so_allocation_list.dart` | ソース | 引当一覧ウィジェット |
| sales_order.dart | `lib/inventree/sales_order.dart` | ソース | 引当データモデル |
| so_shipment_detail.dart | `lib/widget/order/so_shipment_detail.dart` | ソース | 出荷詳細（利用箇所） |
| stock.dart | `lib/inventree/stock.dart` | ソース | 在庫アイテムデータモデル |
| part.dart | `lib/inventree/part.dart` | ソース | パーツデータモデル |
| paginator.dart | `lib/widget/paginator.dart` | ソース | ページネーション共通処理 |
| api.dart | `lib/api.dart` | ソース | API通信・サムネイル取得 |
| link_icon.dart | `lib/widget/link_icon.dart` | ソース | LargeTextウィジェット |
