Files
njts-accounting-core/docs/trial_balance_fix.md
2026-01-16 09:50:21 +09:00

167 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 試算表修正履歴除外対応
## 問題概要
従来、仕訳修正時に以下の流れで処理していました:
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`)の追加
- より明示的な状態管理
ただし、現在の実装でも要件は満たしており、早急な変更は不要です。