# 機能設計書 35-口座別レポート

## 概要

本ドキュメントは、口座ごとの残高推移やトランザクションを表示するレポート機能について記述する。

### 本機能の処理概要

**業務上の目的・背景**：資産管理において、各口座の残高がどのように変動しているかを把握することは重要である。本機能は、複数の口座を一括で管理し、口座ごとの残高推移を時系列で可視化することで、資産の全体像と個別口座の状況を同時に把握できるようにする。特に純資産レポートと連携し、資産と負債のバランスを口座単位で分析できる。

**機能の利用シーン**：
- 純資産レポートでの口座別残高推移確認
- 特定口座の残高変動分析
- オンバジェット/オフバジェット口座の分類表示
- クローズ済み口座の履歴確認
- ダッシュボードでの口座サマリー表示

**主要な処理内容**：
1. 口座一覧の取得とグループ化（オンバジェット/オフバジェット/クローズ）
2. 口座の選択・フィルタリング機能の提供
3. 選択された口座に対する残高推移の計算
4. グループ単位での選択操作
5. グラフ用データへの変換

**関連システム・外部連携**：AQL（Actual Query Language）によるデータベースクエリ、純資産レポート機能

**権限による制御**：予算ファイルへの読み取り権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 31 | 純資産レポート画面 | 補助機能 | 口座ごとの資産推移表示 |

## 機能種別

計算処理 / データ集計 / 可視化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| accounts | AccountEntity[] | Yes | 口座一覧 | - |
| selectedAccountIds | string[] | Yes | 選択された口座IDの一覧 | - |
| setSelectedAccountIds | function | Yes | 選択状態更新コールバック | - |

### 入力データソース

- accountsテーブル（口座一覧）
- transactionsテーブル（取引データ、残高計算用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| groupedAccounts.onBudget | AccountEntity[] | オンバジェット口座一覧 |
| groupedAccounts.offBudget | AccountEntity[] | オフバジェット口座一覧 |
| groupedAccounts.closed | AccountEntity[] | クローズ済み口座一覧 |
| selectedAccountMap | Set<string> | 選択状態の口座ID集合 |

### 出力先

レポート画面のサイドバー（口座セレクター）

## 処理フロー

### 処理シーケンス

```
1. 口座一覧の取得
   └─ AccountEntity配列を受け取る
2. 口座のグループ化
   └─ オンバジェット/オフバジェット/クローズに分類
3. 選択状態の管理
   └─ 全選択/全解除/グループ選択/個別選択
4. グループ単位での選択操作
   └─ グループ内全口座の一括選択/解除
5. 選択状態の親コンポーネントへの通知
   └─ setSelectedAccountIdsコールバックの呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[accounts取得]
    B --> C[useMemo: グループ化]
    C --> D[onBudget: !offbudget && !closed]
    C --> E[offBudget: offbudget && !closed]
    C --> F[closed: closed]
    D --> G[selectedAccountMap作成]
    E --> G
    F --> G
    G --> H{操作種別}
    H -->|全選択| I[全口座ID設定]
    H -->|全解除| J[空配列設定]
    H -->|グループ選択| K[グループ内口座一括操作]
    H -->|個別選択| L[単一口座追加/削除]
    I --> M[setSelectedAccountIds呼び出し]
    J --> M
    K --> M
    L --> M
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | オンバジェット判定 | offbudget=false かつ closed=false の口座 | グループ化時 |
| BR-02 | オフバジェット判定 | offbudget=true かつ closed=false の口座 | グループ化時 |
| BR-03 | クローズ判定 | closed=true の口座 | グループ化時 |
| BR-04 | グループ全選択 | グループチェックボックスで配下口座を一括選択/解除 | グループ操作時 |
| BR-05 | 選択解除表示切替 | 未選択口座を非表示にするオプション | uncheckedHidden=true時 |

### 計算ロジック

**グループ選択状態判定**:
```javascript
onBudgetSelected = groupedAccounts.onBudget.every(
  account => selectedAccountMap.has(account.id)
)
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 口座取得 | accounts | SELECT | 全口座を取得 |
| 残高計算 | transactions | SELECT | 口座ごとの取引合計を計算 |

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

#### accounts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id | - | 口座ID |
| SELECT | name | - | 口座名 |
| SELECT | offbudget | グループ分類条件 | オフバジェットフラグ |
| SELECT | closed | グループ分類条件 | クローズフラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | データなし | 口座が存在しない | 空のセレクターを表示 |

### リトライ仕様

特になし。

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

読み取り専用。データベースの更新は行わない。

## パフォーマンス要件

- useMemoでグループ化計算と選択状態マップを最適化

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

特になし。

## 備考

- AccountSelectorコンポーネントは純資産レポートのサイドバーで使用される
- 口座の表示/非表示切替は画面右上のトグルボタンで操作

---

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

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

### 推奨読解順序

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

口座関連の型定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.ts | `packages/loot-core/types/models/index.ts` | AccountEntity型定義 |

#### Step 2: UIコンポーネントを理解する

口座セレクターの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AccountSelector.tsx | `packages/desktop-client/src/components/reports/AccountSelector.tsx` | 口座選択UIの実装 |

**主要処理フロー**:
- **20-24行目**: `AccountSelectorProps` - コンポーネントのプロパティ定義
- **26-30行目**: コンポーネント初期化
- **35-44行目**: `groupedAccounts` - useMemoによる口座グループ化
  - **36-38行目**: onBudget - オンバジェット口座
  - **39-41行目**: offBudget - オフバジェット口座
  - **42行目**: closed - クローズ済み口座
- **46-49行目**: `selectedAccountMap` - 選択状態のSet化
- **52-64行目**: グループ選択状態の判定
- **121-141行目**: 全選択/全解除ボタン
- **155-201行目**: オンバジェットグループのUI
- **243-290行目**: オフバジェットグループのUI
- **332-379行目**: クローズ済みグループのUI

**読解のコツ**:
- `useMemo`を2箇所で使用（グループ化、選択状態マップ）
- グループ判定は`offbudget`と`closed`フラグの組み合わせ
- 各グループは同じUI構造を繰り返している

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

純資産レポートでのデータ取得を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | net-worth-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/net-worth-spreadsheet.ts` | 口座別残高計算ロジック |

**主要処理フロー**:
- **23-151行目**: `createSpreadsheet` - データ取得関数の生成
- **64-108行目**: 各口座の初期残高と期間内残高の取得
- **153-302行目**: `recalculate` - グラフデータへの変換

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

```
NetWorth (NetWorth.tsx)
    │
    └─ AccountSelector (AccountSelector.tsx:26)
           │
           ├─ groupedAccounts (useMemo:35)
           │      ├─ onBudget: !offbudget && !closed
           │      ├─ offBudget: offbudget && !closed
           │      └─ closed: closed
           │
           ├─ selectedAccountMap (useMemo:46)
           │
           ├─ GraphButton (全選択)
           │      └─ setSelectedAccountIds(all account ids)
           │
           ├─ GraphButton (全解除)
           │      └─ setSelectedAccountIds([])
           │
           ├─ Checkbox (グループ: On Budget)
           │      └─ setSelectedAccountIds(グループ一括操作)
           │
           ├─ Checkbox (グループ: Off Budget)
           │      └─ setSelectedAccountIds(グループ一括操作)
           │
           └─ Checkbox (グループ: Closed)
                  └─ setSelectedAccountIds(グループ一括操作)
```

### データフロー図

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

accounts ─────────┐
                  │
selectedAccountIds┼──▶ AccountSelector ──▶ グループ化
                  │          │                   │
setSelectedAccountIds        │                   │
                             ▼                   ▼
                       選択状態管理 ───▶ setSelectedAccountIds
                             │                   │
                             ▼                   ▼
                       チェックボックス     選択済み口座ID
                        レンダリング           配列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AccountSelector.tsx | `packages/desktop-client/src/components/reports/AccountSelector.tsx` | ソース | 口座選択UIコンポーネント |
| GraphButton.tsx | `packages/desktop-client/src/components/reports/GraphButton.tsx` | ソース | グラフ操作ボタン |
| NetWorth.tsx | `packages/desktop-client/src/components/reports/reports/NetWorth.tsx` | ソース | 純資産レポート画面 |
| net-worth-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/net-worth-spreadsheet.ts` | ソース | 純資産データ取得 |
| forms.tsx | `packages/desktop-client/src/components/forms.tsx` | ソース | Checkboxコンポーネント |
