# 試算表修正履歴除外対応 ## 問題概要 従来、仕訳修正時に以下の流れで処理していました: 1. 原仕訳を保留 2. 逆仕訳を生成(`[逆仕訳]` プレフィックス付き) 3. 修正後仕訳を生成(`【修正後】` プレフィックス付き) しかし、試算表計算時に全ての仕訳を無条件に統計していたため: - 原仕訳 - 逆仕訳 - 修正後仕訳 の 3 つが全て計上され、同一取引が複数回カウントされる問題が発生していました。 ### 具体的な症状 - 銀行科目(普通預金)で借方発生額・貸方発生額が同額計上される - 期末残高が銀行通帳と一致しない - 試算表数値が実態と乖離 ## 解決方針 **方案 B:逆仕訳方式 + 試算表排除ロジック** を採用 以下の理由により、試算表 SQL で履歴データを除外する方式を選択: 1. 既存データに逆仕訳・修正後仕訳の関係性が構築済み 2. 修正履歴を保持できる 3. 最小限のコード変更で対応可能 4. データマイグレーション不要 ## 実装内容 ### 1. 試算表 SQL 修正 **ファイル**: `backend/app/modules/trial_balance/sql.py` ```python period AS ( SELECT jl.account_id, SUM(jl.debit) AS period_debit, SUM(jl.credit) AS period_credit FROM journal_entries je JOIN journal_lines jl ON jl.journal_entry_id = je.journal_entry_id LEFT JOIN journal_entries child ON child.parent_entry_id = je.journal_entry_id WHERE je.entry_date BETWEEN %(start_date)s AND %(end_date)s AND je.description <> '前期残高' AND je.is_deleted = false -- ★ 逆仕訳を除外 AND je.description NOT LIKE '[逆仕訳]%' -- ★ 修正前仕訳を除外(parent_entry_idを参照する子仕訳がある場合) AND child.journal_entry_id IS NULL GROUP BY jl.account_id ) ``` ### 2. 総勘定元帳 SQL 修正 **ファイル**: `backend/app/modules/general_ledger/sql.py` ```python SELECT j.journal_date, j.description, l.debit, l.credit FROM journal_lines l JOIN journal_entries j ON j.journal_id = l.journal_id LEFT JOIN journal_entries child ON child.parent_entry_id = j.journal_id WHERE l.account_id = %(account_id)s AND j.journal_date BETWEEN %(date_from)s AND %(date_to)s -- ★ 逆仕訳を除外 AND j.description NOT LIKE '[逆仕訳]%' -- ★ 修正前仕訳を除外 AND child.journal_id IS NULL ORDER BY j.journal_date, l.line_id; ``` ### 3. 元帳 SQL 修正 **ファイル**: `backend/app/modules/ledger/router.py` 同様に逆仕訳と修正前仕訳を除外する条件を追加。 ## 除外ロジックの説明 ### 除外対象 1:逆仕訳 ```sql AND je.description NOT LIKE '[逆仕訳]%' ``` - 説明に `[逆仕訳]` プレフィックスを持つ仕訳を除外 - これらは元仕訳を打ち消すためのもので、試算表には計上しない ### 除外対象 2:修正前仕訳 ```sql LEFT JOIN journal_entries child ON child.parent_entry_id = je.journal_entry_id ... AND child.journal_entry_id IS NULL ``` - `parent_entry_id` を参照する子仕訳(修正後仕訳)が存在する場合、その親仕訳は除外 - 修正された仕訳は最新版のみを計上 ## 仕訳修正の流れ(参考) 1. **元仕訳**: `journal_entry_id = 100`, `parent_entry_id = NULL` 2. **逆仕訳**: `journal_entry_id = 101`, `parent_entry_id = 100`, `description = "[逆仕訳] xxx"` 3. **修正後仕訳**: `journal_entry_id = 102`, `parent_entry_id = 101`, `description = "【修正後】xxx"` 試算表では: - 元仕訳(100):除外(子仕訳 101 が存在) - 逆仕訳(101):除外(`[逆仕訳]` プレフィックス) - 修正後仕訳(102):**計上**(最新版) ## 会計原則の遵守 ✅ 試算表は「当前有効的仕訳」のみを統計 ✅ 同一業務が同一期間で 1 回のみ計上 ✅ 履歴データ(逆仕訳・修正前仕訳)は除外 ✅ 試算表結果が銀行通帳・実態と一致 ## 影響範囲 ### 修正対象 - ✅ 試算表(Trial Balance) - ✅ 総勘定元帳(General Ledger) - ✅ 元帳(Ledger) ### 影響なし - 仕訳一覧表示(修正履歴表示機能は既存のまま) - 仕訳登録・修正ロジック - データベーススキーマ ## テスト項目 1. [ ] 修正前の仕訳がある状態で試算表を表示 2. [ ] 逆仕訳が正しく除外されることを確認 3. [ ] 修正後仕訳のみが計上されることを確認 4. [ ] 普通預金の期末残高が通帳と一致することを確認 5. [ ] 総勘定元帳でも同様に履歴が除外されることを確認 ## 今後の拡張性 現在は `description` の文字列マッチで逆仕訳を判定していますが、将来的には以下の改善も検討可能: - `is_reversal` フラグの追加 - `entry_type` カラム(`original`, `reversal`, `revised`)の追加 - より明示的な状態管理 ただし、現在の実装でも要件は満たしており、早急な変更は不要です。