# 機能設計書 62-発注設定

## 概要

本ドキュメントは、InvenTreeモバイルアプリにおける発注設定機能の設計を記述するものである。発注（Purchase Order）関連機能の有効化やバーコードスキャン時の挙動を制御するためのユーザー設定画面の仕様を定義する。

### 本機能の処理概要

本機能は、発注機能の有効/無効、カメラ表示の有無、スキャン時の確認ダイアログ表示を制御するためのユーザー設定画面を提供する。設定値はローカルデータベースに永続化され、発注関連の全機能に反映される。

**業務上の目的・背景**：InvenTreeモバイルアプリは多様な業務シナリオに対応する必要がある。発注機能を使用しない組織や、発注受入時のスキャン確認を必須としたい管理者など、様々なニーズがある。本機能により、各組織・ユーザーの業務フローに合わせて発注関連機能をカスタマイズできる。

**機能の利用シーン**：
- 発注機能を使用しない組織がホーム画面から発注メニューを非表示にしたい場合
- 発注詳細画面でカメラボタン（添付ファイルアップロード用）の表示/非表示を切り替えたい場合
- バーコードスキャンによる発注受入時に確認ダイアログを表示するかどうかを設定したい場合

**主要な処理内容**：
1. 設定値（発注有効化、カメラ表示、スキャン確認）のローカルデータベースからの読み込み
2. 各設定項目のスイッチによるON/OFF切り替え
3. 設定変更時のローカルデータベースへの即座の永続化
4. UI状態の即時更新による視覚的フィードバック

**関連システム・外部連携**：本機能はローカル設定のみを管理し、InvenTreeサーバーとの通信は発生しない。ただし、設定値はサーバーとの連携機能（発注受入スキャン等）の挙動に影響する。

**権限による制御**：本機能に特別な権限制御はなく、すべてのユーザーが利用可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | 設定画面 | 遷移元画面 | 発注設定メニュー押下時に本画面へ遷移 |
| 15 | 購入注文設定画面 | 主画面 | 発注の有効化、カメラ表示、スキャン確認の設定変更 |

## 機能種別

設定管理 / CRUD操作（Read/Update）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| poEnable | bool | No | 発注機能を有効化するか | true/false |
| poShowCamera | bool | No | カメラボタンを表示するか | true/false |
| poConfirmScan | bool | No | スキャン時に確認を表示するか | true/false |

### 入力データソース

- 画面入力：各設定項目のSwitchウィジェットからのタップ操作
- ローカルDB：`InvenTreeSettings.db`のsettingsストアから初期値を読み込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| poEnable | bool | 発注機能有効化設定（デフォルト: true） |
| poShowCamera | bool | カメラ表示設定（デフォルト: true） |
| poConfirmScan | bool | スキャン確認表示設定（デフォルト: true） |

### 出力先

- ローカルDB：`InvenTreeSettings.db`のsettingsストア
- 画面表示：Switchウィジェットの状態更新

## 処理フロー

### 処理シーケンス

```
1. 画面初期化（initState）
   └─ loadSettings()を呼び出し
2. 設定読み込み（loadSettings）
   └─ InvenTreeSettingsManager経由で各設定値を取得
   └─ 状態変数に反映（setState）
3. ユーザー操作（Switch切替）
   └─ onChangedコールバック発火
   └─ InvenTreeSettingsManager.setValue()で永続化
   └─ setStateでUI更新
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示] --> B[initState]
    B --> C[loadSettings]
    C --> D[設定値読み込み]
    D --> E[UI状態更新]
    E --> F{ユーザー操作}
    F -->|Switch切替| G[設定値保存]
    G --> H[UI状態更新]
    H --> F
    F -->|戻る| I[画面終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-01 | デフォルト値適用 | 未設定の項目はデフォルト値を適用 | 初回起動時または設定未保存時 |
| BR-62-02 | 即時永続化 | 設定変更は即座にローカルDBに保存 | Switch切替時 |
| BR-62-03 | 発注有効化デフォルト | 発注機能はデフォルトで有効 | 初期状態 |
| BR-62-04 | カメラ表示デフォルト | カメラボタンはデフォルトで表示 | 初期状態 |
| BR-62-05 | スキャン確認デフォルト | スキャン確認はデフォルトで有効 | 初期状態 |
| BR-62-06 | 発注機能無効時の影響 | poEnable=falseの場合、発注関連メニューが非表示になる | ホーム画面等 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定読み込み | settings（sembast store） | SELECT | 各設定キーに対応する値を取得 |
| 設定保存 | settings（sembast store） | UPDATE/INSERT | キーと値のペアを保存（upsert） |

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

#### settings（sembast store）

| 操作 | 項目（キー） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT/UPDATE | poEnable | bool値 | 発注機能有効化フラグ |
| SELECT/UPDATE | poShowCamera | bool値 | カメラ表示フラグ |
| SELECT/UPDATE | poConfirmScan | bool値 | スキャン確認フラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | データベース読み込みエラー | ローカルDB破損時 | デフォルト値を使用 |
| - | データベース書き込みエラー | ストレージ容量不足等 | エラーログ出力、ユーザー操作は継続可能 |

### リトライ仕様

リトライは実装されていない。エラー発生時はデフォルト値で動作を継続する。

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

sembastデータベースの単一キー操作のため、明示的なトランザクション管理は不要。各setValue操作は原子的に実行される。

## パフォーマンス要件

- 設定読み込み：100ms以内
- 設定保存：50ms以内
- UI更新：即座（16ms以内）

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

- 設定データはローカルデバイスにのみ保存
- 機密情報は含まれないため、暗号化は不要
- 他アプリからのアクセスは標準のサンドボックス機構で保護

## 備考

- 設定キーは`preferences.dart`で定数として定義されている（INV_PO_ENABLE, INV_PO_SHOW_CAMERA, INV_PO_CONFIRM_SCAN）
- mounted チェックにより、画面破棄後の setState エラーを防止している
- すべての設定のデフォルト値がtrueである点が在庫設定と異なる

---

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

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

### 推奨読解順序

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

設定キーの定義と設定管理クラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | preferences.dart | `lib/preferences.dart` | 設定キー定数（INV_PO_ENABLE等）とInvenTreeSettingsManagerクラス |

**読解のコツ**:
- **45-47行目**: 発注関連の設定キー定数（`INV_PO_ENABLE`, `INV_PO_SHOW_CAMERA`, `INV_PO_CONFIRM_SCAN`）が定義されている
- **110-185行目**: `InvenTreeSettingsManager`クラスはシングルトンパターンで実装

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

発注設定画面のウィジェット構造を理解する。

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

**主要処理フロー**:
1. **8-11行目**: `InvenTreePurchaseOrderSettingsWidget`がStatefulWidgetとして定義
2. **14-16行目**: `_InvenTreePurchaseOrderSettingsState`がStateクラスとして定義
3. **18-20行目**: 3つの設定値を保持する状態変数の宣言（すべてデフォルトtrue）

#### Step 3: 初期化処理を理解する

画面初期化時の設定読み込み処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | purchase_order_settings.dart | `lib/settings/purchase_order_settings.dart` | initStateとloadSettingsメソッド |

**主要処理フロー**:
- **22-27行目**: `initState`で`loadSettings()`を呼び出し
- **29-43行目**: `loadSettings`メソッドで3つの設定値を非同期で読み込み
- **30行目**: `poEnable`のデフォルト値は`true`
- **31-34行目**: `poShowCamera`のデフォルト値は`true`
- **35-38行目**: `poConfirmScan`のデフォルト値は`true`
- **40-42行目**: `mounted`チェック後に`setState`でUI更新

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

buildメソッドでのUI構築とSwitch操作時の処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | purchase_order_settings.dart | `lib/settings/purchase_order_settings.dart` | buildメソッドとonChangedコールバック |

**主要処理フロー**:
- **45-107行目**: Scaffoldウィジェットによる画面構築
- **55-68行目**: 発注有効化設定のListTile（Switch付き、ショッピングカートアイコン）
- **69-85行目**: カメラ表示設定のListTile（Switch付き、カメラアイコン）
- **86-102行目**: スキャン確認設定のListTile（Switch付き、バーコードアイコン）

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

```
InvenTreePurchaseOrderSettingsWidget
    │
    └─ _InvenTreePurchaseOrderSettingsState
           │
           ├─ initState()
           │      └─ loadSettings()
           │             └─ InvenTreeSettingsManager.getBool() x 3
           │
           └─ build()
                  └─ ListView
                         ├─ ListTile (発注有効化設定)
                         │      └─ Switch.onChanged
                         │             └─ InvenTreeSettingsManager.setValue()
                         ├─ ListTile (カメラ表示設定)
                         │      └─ Switch.onChanged
                         │             └─ InvenTreeSettingsManager.setValue()
                         └─ ListTile (スキャン確認設定)
                                └─ Switch.onChanged
                                       └─ InvenTreeSettingsManager.setValue()
```

### データフロー図

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

                    ┌─────────────────────┐
ローカルDB ─────────▶│ loadSettings()      │
(sembast store)     │ - getBool() x 3     │
                    └──────────┬──────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │ 状態変数            │──────▶ Switch表示状態
                    │ - poEnable          │
                    │ - poShowCamera      │
                    │ - poConfirmScan     │
                    └──────────┬──────────┘
                               │
                               ▼
                    ┌─────────────────────┐
Switchタップ ───────▶│ onChanged()         │
                    │ - setValue()        │──────▶ ローカルDB
                    │ - setState()        │        (sembast store)
                    └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| purchase_order_settings.dart | `lib/settings/purchase_order_settings.dart` | ソース | 発注設定画面のUI・ロジック |
| preferences.dart | `lib/preferences.dart` | ソース | 設定キー定数・設定管理クラス |
| l10.dart | `lib/l10.dart` | ソース | 多言語テキスト取得ヘルパー |
| app_colors.dart | `lib/app_colors.dart` | ソース | アプリ共通カラー定義 |
| settings.dart | `lib/settings/settings.dart` | ソース | 設定画面（遷移元） |
