Files
njts-accounting-core/backend/verify_trial_balance.py
2026-01-16 09:50:21 +09:00

151 lines
4.8 KiB
Python
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.
import os
os.environ['DB_HOST'] = '192.168.0.61'
os.environ['DB_PORT'] = '55432'
os.environ['DB_NAME'] = 'njts_acct'
os.environ['DB_USER'] = 'njts_app'
os.environ['DB_PASSWORD'] = 'njts_app2025'
import sys
sys.path.insert(0, os.path.dirname(__file__))
from app.core.database import get_connection
conn = get_connection()
cur = conn.cursor()
print("\n" + "="*120)
print("試算表ロジック検証 - 普通預金(102) 2025年6月")
print("="*120)
# 試算表SQLと同じロジックで集計
cur.execute("""
SELECT
jl.account_id,
SUM(jl.debit) as total_debit,
SUM(jl.credit) as total_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
JOIN accounts a ON jl.account_id = a.account_id
WHERE je.entry_date BETWEEN '2025-06-01' AND '2025-06-30'
AND je.description <> '前期残高'
AND je.is_deleted = false
AND child.journal_entry_id IS NULL
AND a.account_code = '102'
GROUP BY jl.account_id
""")
result = cur.fetchone()
print(f"\n【試算表の集計結果】")
print(f"借方発生額: {result['total_debit']:>15,.0f}")
print(f"貸方発生額: {result['total_credit']:>15,.0f}")
# 詳細な内訳を確認
print(f"\n{'='*120}")
print("【集計対象の仕訳詳細】")
print(f"{'='*120}")
cur.execute("""
SELECT
je.journal_entry_id,
je.entry_date,
je.description,
jl.debit,
jl.credit,
je.parent_entry_id,
CASE WHEN child.journal_entry_id IS NOT NULL THEN 'Y' ELSE 'N' END as has_child
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
JOIN accounts a ON jl.account_id = a.account_id
WHERE je.entry_date BETWEEN '2025-06-01' AND '2025-06-30'
AND je.description <> '前期残高'
AND je.is_deleted = false
AND a.account_code = '102'
ORDER BY je.journal_entry_id
""")
rows = cur.fetchall()
debit_sum = 0
credit_sum = 0
debit_included = 0
credit_included = 0
print(f"\n{'ID':>3} {'日付':10} {'借方':>13} {'貸方':>13} {'親ID':>5} {'':3} {'集計':4} 摘要")
print("-" * 120)
for r in rows:
is_included = r['has_child'] == 'N'
status = "" if is_included else "×"
debit_sum += r['debit']
credit_sum += r['credit']
if is_included:
debit_included += r['debit']
credit_included += r['credit']
parent_str = str(r['parent_entry_id']) if r['parent_entry_id'] else "-"
# 逆仕訳・修正後をマーク
desc = r['description'][:60]
if '[逆仕訳]' in desc:
desc = f"🔄 {desc}"
elif '【修正後】' in desc:
desc = f"✏️ {desc}"
print(f"{r['journal_entry_id']:3d} {r['entry_date']} {r['debit']:>13,.0f} {r['credit']:>13,.0f} {parent_str:>5} {r['has_child']:3} {status:4} {desc}")
print("-" * 120)
print(f"{'全仕訳合計':62} {debit_sum:>13,.0f} {credit_sum:>13,.0f}")
print(f"{'集計対象(子なし)':60} {debit_included:>13,.0f} {credit_included:>13,.0f}")
# parent_entry_idの問題を確認
print(f"\n{'='*120}")
print("【parent_entry_idチェーン確認】")
print(f"{'='*120}")
cur.execute("""
SELECT
je.journal_entry_id as id,
je.description,
je.parent_entry_id as parent,
(SELECT description FROM journal_entries WHERE journal_entry_id = je.parent_entry_id) as parent_desc,
(SELECT COUNT(*) FROM journal_entries child WHERE child.parent_entry_id = je.journal_entry_id) as child_count
FROM journal_entries je
WHERE (je.description LIKE '%社会保険%' OR je.description LIKE '%遠達ビル%')
AND je.entry_date BETWEEN '2025-06-01' AND '2025-06-30'
ORDER BY je.journal_entry_id
""")
print(f"\n{'ID':>3} {'親ID':>5} {'子数':>4} 摘要 → 親の摘要")
print("-" * 120)
rows = cur.fetchall()
for r in rows:
parent_str = str(r['parent']) if r['parent'] else "-"
parent_desc_str = r['parent_desc'][:40] if r['parent_desc'] else "-"
print(f"{r['id']:3d} {parent_str:>5} {r['child_count']:>4} {r['description'][:50]}")
if r['parent_desc']:
print(f" └→ 親: {parent_desc_str}")
cur.close()
conn.close()
print(f"\n{'='*120}")
print("【結論】")
print(f"{'='*120}")
print("""
正しい集計方法:
1. parent_entry_idチェーンが正しく設定されている場合
→ 最後の修正版のみが「子を持たない」状態になり、それのみが集計される
2. parent_entry_idの設定ミスがある場合
→ 逆仕訳や途中の修正版も「子を持たない」と判定され、重複集計される
対策:
- すべてのparent_entry_idを正しく設定する
- チェーン: 元 → 逆仕訳 → 修正後 → 逆仕訳 → 修正後 → ...
""")