# 帳票設計書 5-Calendar（カレンダー）レポート

## 概要

本ドキュメントは、Actual Budgetアプリケーションにおける「Calendar（カレンダー）レポート」の設計仕様を記述したものである。カレンダー形式で収支を表示し、日ごとの収入・支出を色分けで可視化するレポート機能について詳細に解説する。

### 本帳票の処理概要

Calendar（カレンダー）レポートは、月別のカレンダー形式でトランザクションを表示するレポートである。各日の収入と支出が色分けで可視化され、日付をクリックして詳細なトランザクション一覧を表示できる。

**業務上の目的・背景**：日々の収支を直感的に把握するために、カレンダー形式での表示が有効である。本レポートは、特定の日にどれだけの収入・支出があったかを一目で確認でき、過去の支出パターンや収入日の確認に役立つ。月間の収支リズムを視覚的に把握することで、支出の偏りや収入タイミングの理解を促進する。

**帳票の利用シーン**：給料日や定期支払日の確認、特定日の支出詳細確認、月間の支出パターン分析、イベントに関連した支出の振り返りなど、日単位での収支確認場面で利用される。

**主要な出力内容**：
1. 月別カレンダー表示（複数月同時表示可能）
2. 日ごとの収入・支出の色分け表示
3. 月別の収入・支出合計
4. 選択した日のトランザクション一覧

**帳票の出力タイミング**：ユーザーがレポート画面から「Calendar」を選択した際、またはダッシュボードウィジェットとして設定された際にリアルタイムで生成される。

**帳票の利用者**：アプリケーションの全ユーザー（個人の家計管理者）

## 帳票種別

カレンダー形式ビジュアルレポート

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| R-005 | Calendarレポート | `/reports/calendar` | レポートメニューから選択 |
| R-005-W | Calendarウィジェット | `/reports/calendar/:id` | ダッシュボードウィジェットクリック |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | HTML（画面表示） |
| 表示形式 | カレンダーグリッド + トランザクションリスト |
| レスポンシブ対応 | 有（モバイル/デスクトップ） |
| データ更新 | リアルタイム（日付選択・フィルター変更時） |

### 表示固有設定

| 項目 | 内容 |
|-----|------|
| カレンダー配置 | 横スクロール可能（複数月表示） |
| 色分け | 収入:緑系、支出:赤系 |
| モバイル表示 | ドロワー式トランザクションリスト |

## 帳票レイアウト

### レイアウト概要

レポートは上部のヘッダー部、中央のカレンダー部、下部のトランザクションリスト部の3つのセクションで構成される。

```
+------------------------------------------+
|              ページヘッダー                |
|  [タイトル]                    [保存ボタン] |
+------------------------------------------+
|              フィルターヘッダー              |
| [期間選択]                    [フィルター] |
+------------------------------------------+
| サマリーカード |                          |
| [期間表示]    |  カレンダー表示エリア       |
| Income: ¥XX  |  +--------+ +--------+    |
| Expenses:¥XX |  | Jan    | | Feb    |    |
|              |  | カレンダー| | カレンダー|    |
|              |  +--------+ +--------+    |
+------------------------------------------+
|              トランザクションリスト          |
|  [ソート可能なトランザクション一覧]          |
+------------------------------------------+
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | タイトル | レポート名（編集可能） | widget.meta.name | テキスト |
| 2 | 期間選択 | 開始月・終了月の選択 | allMonths | ドロップダウン |
| 3 | フィルター | 条件フィルター | conditions | フィルターボタン |

### カレンダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 月ヘッダー | 月名と年（クリックで月選択） | calendar.start | ボタン |
| 2 | 月別収入 | 月の収入合計 | calendar.totalIncome | 緑色テキスト |
| 3 | 月別支出 | 月の支出合計 | calendar.totalExpense | 赤色テキスト |
| 4 | 日セル | 各日の収支（クリックで日選択） | calendar.data | 色分けセル |

### トランザクションリスト部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Account | 口座名 | transaction.account.name | テキスト |
| 2 | Date | 日付 | transaction.date | 日付形式 |
| 3 | Payee | 支払先 | transaction.payee.name | テキスト |
| 4 | Notes | メモ | transaction.notes | テキスト |
| 5 | Category | カテゴリ | transaction.category.name | テキスト |
| 6 | Amount | 金額 | transaction.amount | 通貨形式 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 期間（開始） | 表示開始月 | Yes |
| 期間（終了） | 表示終了月 | Yes |
| 日付フィルター | 選択した日付 | No（カレンダークリック時） |
| カスタムフィルター | ルール条件によるフィルタリング | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | ユーザー選択 | 可変（date/account/payee/category/amount） |

### 改ページ条件

該当なし（単一画面表示、カレンダーは横スクロール）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| transactions | トランザクションデータ | - |
| accounts | 口座マスタ | account.id |
| payees | 支払先マスタ | payee.id |
| categories | カテゴリマスタ | category.id |
| category_groups | カテゴリグループ | category.group_id |

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

#### transactions（カレンダー表示用）

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| date | 日別集計 | firstDayOfMonth <= date <= lastDayOfMonth | - |
| amount | 収入/支出 | - | 正:収入、負:支出 |

#### transactions（リスト表示用）

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | トランザクションID | - | リンク用 |
| account.name | Account列 | - | - |
| date | Date列 | - | - |
| payee.name | Payee列 | - | - |
| notes | Notes列 | - | - |
| category.name | Category列 | - | - |
| amount | Amount列 | - | - |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 日別収入 | SUM(amount) WHERE amount > 0 AND date = 対象日 | なし | - |
| 日別支出 | SUM(amount) WHERE amount < 0 AND date = 対象日 | なし | 絶対値で表示 |
| 月別収入合計 | SUM(日別収入) | なし | - |
| 月別支出合計 | SUM(日別支出) | なし | - |
| 期間収入合計 | SUM(月別収入合計) | なし | サマリーカード用 |
| 期間支出合計 | SUM(月別支出合計) | なし | サマリーカード用 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[レポート画面表示] --> B[パラメータ初期化]
    B --> C[最古/最新トランザクション取得]
    C --> D[月リスト生成]
    D --> E[calendarSpreadsheet呼び出し]
    E --> F[月別カレンダーデータ生成]
    F --> G[CalendarGraph描画]
    G --> H{日付クリック?}
    H -->|Yes| I[フィルター条件更新]
    I --> J[トランザクションクエリ更新]
    J --> K[TransactionList更新]
    H -->|No| L[表示完了]
    K --> L
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | トランザクションが存在しない | No transactions | 期間やフィルターを変更 |
| ウィジェット保存失敗 | 保存処理エラー | Failed to save dashboard widget. | 再試行 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数千件/月のトランザクション |
| 目標出力時間 | 3秒以内 |
| 遅延読み込み | トランザクションリストはloadMoreで追加読込 |

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

- プライバシーフィルター（PrivacyFilter）による金額のマスキング機能
- ローカルデータストレージ（サーバーへのデータ送信なし）

## 備考

- モバイル表示時はアニメーション付きのドロワーでトランザクションリストを表示
- 週の開始日はユーザー設定（firstDayOfWeekIdx）に従う
- 分割トランザクション（splits: 'grouped'）に対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.ts | `loot-core/types/models` | CalendarWidget, TimeFrame, RuleConditionEntity型 |
| 1-2 | calendar-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/calendar-spreadsheet.ts` | CalendarDataType型 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Calendar.tsx | `packages/desktop-client/src/components/reports/reports/Calendar.tsx` | メインコンポーネント（1030行） |

**主要処理フロー**:
1. **行85-98**: Calendar関数 - ウィジェット・パラメータ読み込み
2. **行105-143**: CalendarInner - 状態初期化
3. **行183-195**: params - スプレッドシートパラメータ
4. **行200-230**: クエリ生成 - フィルター条件からトランザクションクエリ生成
5. **行248**: useReport - カレンダーデータ取得
6. **行599-609**: CalendarWithHeader - 月別カレンダー描画
7. **行641-693**: TransactionList - トランザクション一覧

#### Step 3: スプレッドシートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | calendar-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/calendar-spreadsheet.ts` | カレンダーデータ生成 |

#### Step 4: グラフ・UI部品を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CalendarGraph.tsx | `packages/desktop-client/src/components/reports/graphs/CalendarGraph.tsx` | カレンダーグリッド描画 |

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

```
Calendar.tsx
    |
    +-- useWidget<CalendarWidget>() --> ウィジェットデータ取得
    |
    +-- CalendarInner
            |
            +-- useRuleConditionFilters() --> フィルター条件管理
            |
            +-- calendarSpreadsheet() --> calendar-spreadsheet.ts
            |       |
            |       +-- 月別・日別の収支集計
            |
            +-- useReport('calendar', params) --> カレンダーデータ取得
            |
            +-- useTransactions({ query }) --> トランザクションリスト取得
            |
            +-- CalendarWithHeader (map)
            |       |
            |       +-- CalendarGraph --> カレンダーグリッド描画
            |       |
            |       +-- onDayClick --> 日付フィルター適用
            |
            +-- TransactionList / TransactionListMobile --> トランザクション一覧
```

### データフロー図

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

トランザクション ────+
                    |
期間設定 ───────────+──> calendarSpreadsheet ──> calendarData
                    |         |                      |
フィルター条件 ──────+         v                      v
                    |    月別・日別集計         [CalendarWithHeader]
                    |         |                      |
                    |         v                      v
                    |    CalendarDataType[]    月別カレンダー表示
                    |                               |
日付クリック ───────+                               v
                    |                          フィルター更新
                    |                               |
                    +──────────────────────────────+
                                                    |
                                                    v
                                             [TransactionList]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Calendar.tsx | `packages/desktop-client/src/components/reports/reports/Calendar.tsx` | ソース | メインコンポーネント |
| calendar-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/calendar-spreadsheet.ts` | ソース | カレンダーデータ生成 |
| CalendarGraph.tsx | `packages/desktop-client/src/components/reports/graphs/CalendarGraph.tsx` | ソース | カレンダーグリッド描画 |
| TransactionList.tsx | `packages/desktop-client/src/components/transactions/TransactionList.tsx` | ソース | トランザクション一覧（デスクトップ） |
| TransactionList.tsx | `packages/desktop-client/src/components/mobile/transactions/TransactionList.tsx` | ソース | トランザクション一覧（モバイル） |
| Header.tsx | `packages/desktop-client/src/components/reports/Header.tsx` | ソース | ヘッダーUI |
| DateRange.tsx | `packages/desktop-client/src/components/reports/DateRange.tsx` | ソース | 期間表示 |
