# 通知設計書 48-データ不足

## 概要

本ドキュメントは、InvenTreeモバイルアプリにおける「データ不足」通知の設計仕様を定義するものである。購買発注（Purchase Order）のバーコードスキャンによる受入処理時に、必要なデータ（ラインアイテム情報など）が不足している場合に表示されるエラー通知について記載する。

### 本通知の処理概要

本通知は、バーコードスキャンによる購買発注受入処理において、サーバーからのレスポンスに必要なデータが含まれていないことをユーザーに通知するためのアプリ内スナックバー通知である。

**業務上の目的・背景**：購買発注の受入処理では、どのラインアイテム（発注明細）に対して受入を行うかを特定する必要がある。バーコードスキャンによりサプライヤーバーコードを読み取った際、サーバーがラインアイテムを特定できない場合や、必要な情報が不足している場合がある。このような状況をユーザーに明確に通知することで、適切な対応（手動でのラインアイテム選択、バーコードの再確認など）を促す。

**通知の送信タイミング**：購買発注受入のバーコードスキャン処理（`onBarcodeUnhandled`メソッド）において、サーバーレスポンスの`lineitem`データに必要なキー（`pk`、`purchase_order`）が含まれていない場合にトリガーされる。

**通知の受信者**：バーコードスキャン操作を実行したユーザー本人のみ。アプリ内通知であるため、他のユーザーには通知されない。

**通知内容の概要**：「データ不足」を示すローカライズされたメッセージ（`L10().missingData`）と、失敗を示すオレンジ色の背景、警告アイコンがスナックバーとして画面下部に表示される。また、失敗音も再生される。

**期待されるアクション**：ユーザーはデータが不足していることを認識し、以下のいずれかの対応を取る：正しいバーコードを再スキャンする、手動でラインアイテムを選択する、またはサーバーのデータ設定を確認する。

## 通知種別

アプリ内通知（スナックバー）+ 音声フィードバック

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | なし（UI通知のため） |

### 送信先決定ロジック

操作を実行したユーザーのアプリ画面に直接表示。ユーザー選択や条件分岐は不要。

## 通知テンプレート

### スナックバー通知

| 項目 | 内容 |
|-----|------|
| 背景色 | `Colors.deepOrange`（失敗時） |
| アイコン | `TablerIcons.exclamation_circle` |
| 表示時間 | 5秒 |
| 形式 | スナックバー（画面下部） |

### 音声通知

| 項目 | 内容 |
|-----|------|
| 音声ファイル | `sounds/barcode_error.mp3` |
| トリガー | `barcodeFailureTone()`関数 |

### 本文テンプレート

```
{L10().missingData}
```

英語の場合: "Missing Data" または類似のメッセージ

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| missingData | データ不足メッセージ | L10()（国際化リソース） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| バーコードスキャン | PO受入APIのレスポンス | `lineitem`に`pk`または`purchase_order`キーがない | 必要データの欠落 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 必要なキーがすべて存在 | 受入処理フォームが表示される |
| action_requiredがない | 他のエラー処理に移行 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[バーコードスキャン] --> B[API POST barcode/po-receive/]
    B --> C{レスポンス確認}
    C -->|success/lineitem有| D[barcodeSuccess - 受入成功]
    C -->|action_required| E{lineitemデータ確認}
    C -->|error| F[onBarcodeUnknown - エラー]
    E -->|pk, purchase_order有| G[受入フォーム表示]
    E -->|キー欠落| H[barcodeFailureTone]
    H --> I[showSnackIcon missingData]
    D --> J[終了]
    F --> J
    G --> J
    I --> J
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| PurchaseOrder | 購買発注情報 | InvenTreeサーバー側 |
| PurchaseOrderLineItem | 発注明細情報 | InvenTreeサーバー側 |

### テーブル別参照項目詳細

#### lineitemレスポンスデータ

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| pk | ラインアイテムID | 必須 |
| purchase_order | 発注ID | 必須 |
| quantity | 数量 | オプション |
| location | 保管場所ID | オプション |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 通知のみで更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| pkキー欠落 | lineitemにpkがない | データ不足通知を表示 |
| purchase_orderキー欠落 | lineitemにpurchase_orderがない | データ不足通知を表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（ユーザー操作による再試行） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（ユーザー操作に応じて即座に表示）

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

- バーコードスキャン操作は認証済みユーザーのみ実行可能
- 購買発注へのアクセスには適切な権限が必要

## 備考

- バーコードスキャナーは通知後も継続して使用可能
- サーバー側でのバーコードとラインアイテムのマッピング設定が適切でない場合にこのエラーが発生する可能性がある
- 国際化対応済み（L10()による多言語サポート）
- API version 139以上でサポートされる機能

---

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

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

### 推奨読解順序

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

PO受入レスポンスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | purchase_order.dart | `lib/barcode/purchase_order.dart` | POReceiveBarcodeHandlerクラスの構造 |

**読解のコツ**: `onBarcodeUnhandled`で期待されるlineitemデータの構造を確認する。

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

データ不足検知処理の起点を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | purchase_order.dart | `lib/barcode/purchase_order.dart` | POReceiveBarcodeHandler.onBarcodeUnhandled（64-116行目） |

**主要処理フロー**:
1. **66-68行目**: `action_required`と`lineitem`の存在確認
2. **70-71行目**: `lineitem`から`pk`と`purchase_order`キーの確認
3. **72-75行目**: キー欠落時の処理（通知表示）

#### Step 3: 通知表示処理を理解する

失敗時のスナックバーと音声フィードバックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tones.dart | `lib/barcode/tones.dart` | barcodeFailureTone関数 |
| 3-2 | snacks.dart | `lib/widget/snacks.dart` | showSnackIcon関数のsuccess=false時の処理 |

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

```
POReceiveBarcodeHandler (purchase_order.dart line 22)
    │
    ├─ processBarcode() (line 33-51)
    │      │
    │      └─ super.processBarcode() - バーコードAPIリクエスト
    │             url: "barcode/po-receive/"
    │
    ├─ onBarcodeMatched() (line 54-62)
    │      └─ barcodeSuccess(L10().receivedItem) - 成功時
    │
    └─ onBarcodeUnhandled() (line 64-116)
           │
           ├─ [action_required & lineitem あり]
           │      │
           │      ├─ lineitemData = data["lineitem"]
           │      │
           │      └─ [pkまたはpurchase_orderキー欠落]
           │             │
           │             ├─ barcodeFailureTone() - 失敗音
           │             │
           │             └─ showSnackIcon(L10().missingData, success: false)
           │
           └─ [キー有効]
                  └─ receive() - 受入フォーム表示
```

### データフロー図

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

バーコード       ┌─────────────────┐
スキャン ───────▶│processBarcode() │
                 └────────┬────────┘
                          │
                          ▼
                 ┌─────────────────┐     API Request
                 │barcode/         │────────────────▶ InvenTreeサーバー
                 │po-receive/      │◀────────────────
                 └────────┬────────┘     API Response
                          │
                          ▼
                 ┌─────────────────┐
                 │onBarcode        │
                 │Unhandled()      │
                 └────────┬────────┘
                          │
                          ▼
                 ┌─────────────────┐
                 │lineitemData確認 │
                 │pk, purchase_order│
                 └────────┬────────┘
                          │
                          ▼ (キー欠落)
                 ┌─────────────────┐
                 │barcodeFailure  │───▶ 失敗音再生
                 │Tone()          │
                 └────────┬────────┘
                          │
                          ▼
                 ┌─────────────────┐
                 │showSnackIcon() │───▶ エラースナックバー
                 │missingData     │     (オレンジ背景)
                 └─────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| purchase_order.dart | `lib/barcode/purchase_order.dart` | ソース | PO受入バーコードハンドラー |
| tones.dart | `lib/barcode/tones.dart` | ソース | 失敗音再生 |
| snacks.dart | `lib/widget/snacks.dart` | ソース | スナックバー通知の表示関数 |
| handler.dart | `lib/barcode/handler.dart` | ソース | バーコードハンドラー基底クラス |
| l10.dart | `lib/l10.dart` | ソース | 国際化ヘルパー関数 |
