# 画面設計書 12-バーコード設定画面

## 概要

本ドキュメントは、InvenTree Flutterアプリケーションの「バーコード設定画面」について、その機能・動作・実装を詳細に記述した設計書です。

### 本画面の処理概要

バーコード設定画面は、アプリケーションのバーコードスキャン機能に関する設定を行う画面です。スキャンに使用するコントローラーの種類（内蔵カメラまたは外部スキャナー）、スキャン間隔の遅延時間、シングルスキャンモードの有効/無効を設定できます。

**業務上の目的・背景**：在庫管理業務では、バーコードスキャンによる効率的なデータ入力が不可欠です。しかし、使用環境や機器は多様であり、内蔵カメラでのスキャンが適している場合もあれば、専用のバーコードスキャナー（ウェッジスキャナー）を使用する場合もあります。また、連続スキャン時のパフォーマンス調整や誤スキャン防止のための遅延設定も重要です。この画面により、ユーザーは自身の業務環境に最適なバーコードスキャン設定を行えます。

**画面へのアクセス方法**：ドロワーメニューから「設定」を選択し、設定画面から「バーコード」設定を選択することでアクセスできます。

**主要な操作・処理内容**：
1. バーコードスキャンコントローラーの選択 - 内蔵カメラまたは外部スキャナーを選択
2. スキャン遅延時間の設定 - 連続スキャン間の待機時間をミリ秒単位で設定（100ms〜2500ms）
3. シングルスキャンモードの設定 - 1回のスキャンで自動的にスキャン画面を閉じるかどうかを設定

**画面遷移**：
- 遷移元：設定画面（`lib/settings/settings.dart`）
- 遷移先：なし（設定変更後は戻る操作のみ）

**権限による表示制御**：この画面自体への権限制御はありません。全てのユーザーがバーコード設定を変更できます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 59 | バーコード設定 | 主機能 | バーコードスキャン方式（カメラ/ウェッジ）の設定変更 |

## 画面種別

設定

## URL/ルーティング

Flutter Navigator経由でのプッシュ遷移（MaterialPageRoute）

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|---------|------|------|
| barcodeScanType | 入出力 | int | - | スキャンコントローラー種別（0:カメラ, 1:ウェッジ） |
| barcodeScanDelay | 入出力 | int | - | スキャン遅延時間（ミリ秒）、100〜2500の範囲 |
| barcodeScanSingle | 入出力 | bool | - | シングルスキャンモードフラグ |

## 表示項目

| No | 項目名 | 表示形式 | 説明 |
|----|--------|---------|------|
| 1 | AppBar | テキスト | 「バーコード設定」タイトル表示 |
| 2 | スキャンコントローラー設定 | ListTile + Icon | タイトル、説明、QRコードアイコン、現在の設定アイコン |
| 3 | スキャン遅延時間設定 | ListTile + Text | タイトル、説明、砂時計アイコン、現在値（ms） |
| 4 | シングルスキャンモード設定 | ListTile + Switch | タイトル、説明、バーコードリーダーアイコン、スイッチ |

## イベント仕様

### 1-画面初期化時

1. `initState()`で`loadSettings()`を呼び出し
2. `InvenTreeSettingsManager()`から各設定値を非同期で取得
3. 取得した値で画面の状態変数を更新し、`setState()`で再描画

### 2-スキャンコントローラー設定タップ時

1. `choiceDialog()`を呼び出し選択ダイアログを表示
2. 選択肢：「内蔵カメラ」または「外部スキャナー」
3. 選択後、`InvenTreeSettingsManager().setValue()`で設定を永続化
4. `setState()`でUI状態を更新

### 3-スキャン遅延時間タップ時

1. `_editBarcodeScanDelay()`メソッドを呼び出し
2. `AlertDialog`で数値入力フィールドを表示
3. キャンセル時：ダイアログを閉じる
4. OK時：入力値を検証（100〜2500の範囲に制限）し、設定を永続化

### 4-シングルスキャンモードスイッチ変更時

1. スイッチの`onChanged`コールバックが発火
2. `InvenTreeSettingsManager().setValue()`で設定値を永続化
3. `setState()`で即座にUI状態を更新

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 設定変更 | InvenTreeSettings.db (settings store) | UPDATE | 設定値の永続化 |

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

#### settings store (Sembast NoSQL)

| 操作 | 項目（キー） | 更新値・取得条件 | 備考 |
|-----|------------|-----------------|------|
| UPDATE | barcodeScanType | 0（カメラ）または1（ウェッジ） | スキャンコントローラー種別 |
| UPDATE | barcodeScanDelay | 100〜2500の整数値 | スキャン遅延（ミリ秒） |
| UPDATE | barcodeScanSingle | true/false | シングルスキャンモード |

## メッセージ仕様

| No | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|--------------|--------------|---------|
| 1 | ダイアログタイトル | L10().barcodeScanDelay | 遅延時間設定ダイアログ表示時 |
| 2 | ダイアログヒント | L10().barcodeScanDelayDetail | 遅延時間入力フィールドのヒント |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|---------|---------|
| 1 | 設定値読み込み失敗 | デフォルト値を使用（barcodeScanDelay: 500, barcodeScanType: 0, barcodeScanSingle: false） |
| 2 | 遅延時間の不正入力 | 現在の値を維持、範囲外の場合は100または2500に補正 |

## 備考

- スキャンコントローラーの種別に応じてtrailingのアイコンが動的に変化（カメラアイコンまたはバーコードリーダーアイコン）
- 遅延時間の入力はAlertDialogによるモーダル入力で、キーボードは数値専用タイプを使用
- 設定値はSembast NoSQLデータベースにローカル保存され、サーバーには同期されない

---

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

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

### 推奨読解順序

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

まず、設定キーとスキャナータイプの定数定義を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | preferences.dart | `lib/preferences.dart` | 設定キー定数（INV_BARCODE_*）とスキャナータイプ定数の定義 |

**読解のコツ**:
- 57-59行目で`INV_BARCODE_SCAN_DELAY`, `INV_BARCODE_SCAN_TYPE`, `INV_BARCODE_SCAN_SINGLE`が定義されています
- 62-63行目で`BARCODE_CONTROLLER_CAMERA = 0`, `BARCODE_CONTROLLER_WEDGE = 1`が定義されています

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

処理の起点となるウィジェットクラスを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | barcode_settings.dart | `lib/settings/barcode_settings.dart` | `InvenTreeBarcodeSettingsWidget`クラスとStateクラスの構造 |

**主要処理フロー**:
1. **10-13行目**: `InvenTreeBarcodeSettingsWidget` StatefulWidgetの定義
2. **16-51行目**: `_InvenTreeBarcodeSettingsState`クラス - 状態変数と初期化処理
3. **28-31行目**: `initState()`で`loadSettings()`を呼び出し
4. **33-51行目**: `loadSettings()`で非同期に設定値を読み込み

#### Step 3: ダイアログ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | barcode_settings.dart | `lib/settings/barcode_settings.dart` | `_editBarcodeScanDelay()`メソッドの実装 |

**主要処理フロー**:
- **55-107行目**: `_editBarcodeScanDelay()`メソッド
- **56行目**: 現在の値をテキストコントローラーにセット
- **58-106行目**: `showDialog()`でAlertDialogを表示
- **85-91行目**: 入力値の検証と範囲制限（100〜2500）

#### Step 4: UI構築処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | barcode_settings.dart | `lib/settings/barcode_settings.dart` | `build()`メソッドでのUI構築 |

**主要処理フロー**:
- **109-196行目**: `build()`メソッド
- **112-120行目**: スキャンタイプに応じたアイコンの動的生成
- **130-162行目**: スキャンコントローラー選択（choiceDialog使用）
- **163-173行目**: スキャン遅延時間設定
- **174-191行目**: シングルスキャンモード設定

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

```
InvenTreeBarcodeSettingsWidget
    │
    └─ _InvenTreeBarcodeSettingsState
           │
           ├─ initState()
           │      └─ loadSettings()
           │             └─ InvenTreeSettingsManager().getValue/getBool()
           │
           ├─ _editBarcodeScanDelay()
           │      └─ showDialog() > AlertDialog
           │             └─ InvenTreeSettingsManager().setValue()
           │
           └─ build()
                  ├─ ListTile (スキャンコントローラー)
                  │      └─ onTap > choiceDialog()
                  │             └─ InvenTreeSettingsManager().setValue()
                  │
                  ├─ ListTile (スキャン遅延)
                  │      └─ GestureDetector > _editBarcodeScanDelay()
                  │
                  └─ ListTile (シングルスキャン) > Switch
                         └─ onChanged > setValue()
```

### データフロー図

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

スキャンコントローラー選択
      │
      ▼
choiceDialog()  ───▶  setValue(barcodeScanType)  ───▶  Sembast DB
      │
      └──────────▶  setState() ───▶ UI更新（アイコン変更）

スキャン遅延入力
      │
      ▼
AlertDialog  ───▶  値検証(100-2500)  ───▶  setValue()  ───▶  Sembast DB
      │
      └──────────▶  setState() ───▶ UI更新（表示値変更）
```

```
[初期化時]

Sembast DB  ───▶  getValue/getBool()  ───▶  状態変数  ───▶  UI表示
(settings)           (async)              (int/bool)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| barcode_settings.dart | `lib/settings/barcode_settings.dart` | ソース | 画面本体のウィジェット実装 |
| preferences.dart | `lib/preferences.dart` | ソース | 設定キー定数と設定マネージャー |
| dialogs.dart | `lib/widget/dialogs.dart` | ソース | choiceDialog関数の定義 |
| l10.dart | `lib/l10.dart` | ソース | 多言語対応テキスト定義 |
| app_colors.dart | `lib/app_colors.dart` | ソース | アプリカラー定数（COLOR_APP_BAR等） |
| settings.dart | `lib/settings/settings.dart` | ソース | 設定画面（遷移元） |
