Files
njts-accounting-core/test_hedging_workflow.py
2026-02-20 15:47:27 +09:00

220 lines
7.7 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 psycopg2
from psycopg2.extras import RealDictCursor
import json
from datetime import datetime
conn = psycopg2.connect('host=192.168.0.61 port=55432 dbname=njts_acct user=njts_app password=njts_app2025')
cur = conn.cursor(cursor_factory=RealDictCursor)
print("=" * 100)
print("【對沖測試流程】: 登録 → 修正 → 恢復原始 → 删除逆仕訳")
print("=" * 100)
# ================== 步骤 1: 創建測試數據 ==================
print("\n【步驟 1】登錄測試數據金額10元2025年6月")
print("-" * 100)
cur.execute("""
INSERT INTO journal_entries (entry_date, description, fiscal_year, version, is_deleted, created_by)
VALUES (%s, %s, %s, 1, false, %s)
RETURNING journal_entry_id
""", (
'2025-06-15',
'【對沖測試】テスト用取引 テスト用取引',
2025,
'system'
))
test_entry_id = cur.fetchone()['journal_entry_id']
print(f"✓ 創建 Entry#{test_entry_id}")
# 添加明細行(売上高 account_id=41金額10元
cur.execute("""
INSERT INTO journal_lines (journal_entry_id, account_id, debit, credit)
VALUES (%s, %s, 0, %s)
""", (test_entry_id, 41, 10))
print(f"✓ 添加明細: 売上高 10元 貳")
conn.commit()
# 驗證
cur.execute("""
SELECT je.journal_entry_id, je.description, jl.account_id, a.account_code, jl.credit
FROM journal_entries je
LEFT JOIN journal_lines jl ON je.journal_entry_id = jl.journal_entry_id
LEFT JOIN accounts a ON jl.account_id = a.account_id
WHERE je.journal_entry_id = %s
""", (test_entry_id,))
row = cur.fetchone()
print(f"\n Entry#{row['journal_entry_id']}: {row['account_code']} {row['account_code']} | 貳: {row['credit']}")
# ================== 步驟 2: 計算修正前的試算表 ==================
print("\n【步驟 2】修正前的試算表2025年6月 account 701")
print("-" * 100)
cur.execute("""
SELECT
SUM(CASE WHEN jl.debit::numeric > 0 THEN jl.debit::numeric ELSE 0 END) as debit_total,
SUM(CASE WHEN jl.credit::numeric > 0 THEN jl.credit::numeric ELSE 0 END) as credit_total
FROM journal_lines jl
JOIN journal_entries je ON jl.journal_entry_id = je.journal_entry_id
LEFT JOIN journal_entries child ON child.parent_entry_id = je.journal_entry_id
WHERE jl.account_id = 41
AND EXTRACT(YEAR FROM je.entry_date) = 2025
AND EXTRACT(MONTH FROM je.entry_date) = 6
AND je.is_deleted = false
AND child.journal_entry_id IS NULL
""")
result = cur.fetchone()
before_debit = result['debit_total'] if result['debit_total'] else 0
before_credit = result['credit_total'] if result['credit_total'] else 0
print(f"試算表: 借: {before_debit:,.0f} | 貳: {before_credit:,.0f}")
print(f" (包含我們的測試Entry 10元)")
# ================== 步驟 3: 通過後端 /reverse API 創建對沖 ==================
print("\n【步驟 3】通過「修正」按鈕創建對沖模擬 /reverse API")
print("-" * 100)
# 手工執行 reverse 邏輯實際應該調用後端API
cur.execute("""
INSERT INTO journal_entries (
entry_date,
description,
fiscal_year,
version,
is_deleted,
created_by,
parent_entry_id
)
VALUES (%s, %s, %s, 1, false, %s, %s)
RETURNING journal_entry_id
""", (
'2025-06-15',
f'[逆仕訳] 【對沖測試】テスト用取引 テスト用取引',
2025,
'system',
test_entry_id
))
reverse_entry_id = cur.fetchone()['journal_entry_id']
print(f"✓ 創建逆仕訳 Entry#{reverse_entry_id}parent_entry_id={test_entry_id}")
# 添加逆仕訳明細(借方 10元
cur.execute("""
INSERT INTO journal_lines (journal_entry_id, account_id, debit, credit)
VALUES (%s, %s, %s, 0)
""", (reverse_entry_id, 41, 10))
print(f"✓ 添加逆仕訳明細: 売上高 10元 借")
conn.commit()
print(f"\n parent-child 關係: Entry#{test_entry_id} ←parent- Entry#{reverse_entry_id}")
# ================== 步驟 4: 計算修正後的試算表 ==================
print("\n【步驟 4】修正後的試算表両條應該都被過濾")
print("-" * 100)
cur.execute("""
SELECT
SUM(CASE WHEN jl.debit::numeric > 0 THEN jl.debit::numeric ELSE 0 END) as debit_total,
SUM(CASE WHEN jl.credit::numeric > 0 THEN jl.credit::numeric ELSE 0 END) as credit_total
FROM journal_lines jl
JOIN journal_entries je ON jl.journal_entry_id = je.journal_entry_id
LEFT JOIN journal_entries child ON child.parent_entry_id = je.journal_entry_id
WHERE jl.account_id = 41
AND EXTRACT(YEAR FROM je.entry_date) = 2025
AND EXTRACT(MONTH FROM je.entry_date) = 6
AND je.is_deleted = false
AND child.journal_entry_id IS NULL
""")
result = cur.fetchone()
after_debit = result['debit_total'] if result['debit_total'] else 0
after_credit = result['credit_total'] if result['credit_total'] else 0
print(f"試算表: 借: {after_debit:,.0f} | 貳: {after_credit:,.0f}")
# 驗證両條都被過濾
if after_debit == before_debit and after_credit == before_credit - 10:
print(f"✓ 對沖成功10元的借貸被抵消")
else:
print(f"✗ 對沖失敗期望減少10元實際減少 {before_credit - after_credit}")
# ================== 步驟 5: 恢復原始交易 ==================
print("\n【步驟 5】恢復原始交易 + 刪除逆仕訳")
print("-" * 100)
# 恢復原始交易(清除 parent 關係)
cur.execute("""
UPDATE journal_entries
SET parent_entry_id = NULL
WHERE journal_entry_id = %s
""", (test_entry_id,))
print(f"✓ 恢復 Entry#{test_entry_id}(清除 parent_entry_id")
# 刪除逆仕訳
cur.execute("""
UPDATE journal_entries
SET is_deleted = true
WHERE journal_entry_id = %s
""", (reverse_entry_id,))
print(f"✓ 刪除逆仕訳 Entry#{reverse_entry_id}is_deleted = true")
conn.commit()
# ================== 步驟 6: 計算恢復後的試算表 ==================
print("\n【步驟 6】恢復後的試算表原始交易應該重新出現")
print("-" * 100)
cur.execute("""
SELECT
SUM(CASE WHEN jl.debit::numeric > 0 THEN jl.debit::numeric ELSE 0 END) as debit_total,
SUM(CASE WHEN jl.credit::numeric > 0 THEN jl.credit::numeric ELSE 0 END) as credit_total
FROM journal_lines jl
JOIN journal_entries je ON jl.journal_entry_id = je.journal_entry_id
LEFT JOIN journal_entries child ON child.parent_entry_id = je.journal_entry_id
WHERE jl.account_id = 41
AND EXTRACT(YEAR FROM je.entry_date) = 2025
AND EXTRACT(MONTH FROM je.entry_date) = 6
AND je.is_deleted = false
AND child.journal_entry_id IS NULL
""")
result = cur.fetchone()
final_debit = result['debit_total'] if result['debit_total'] else 0
final_credit = result['credit_total'] if result['credit_total'] else 0
print(f"試算表: 借: {final_debit:,.0f} | 貳: {final_credit:,.0f}")
if final_credit == before_credit:
print(f"✓ 恢復成功!試算表回到初始狀態")
else:
print(f"✗ 恢復失敗!期望 {before_credit}, 實際 {final_credit}")
# ================== 步驟 7: 最後清理 ==================
print("\n【步驟 7】清理測試數據刪除測試 Entry")
print("-" * 100)
cur.execute("""
UPDATE journal_entries
SET is_deleted = true
WHERE journal_entry_id = %s
""", (test_entry_id,))
conn.commit()
print(f"✓ 刪除測試 Entry#{test_entry_id}")
# ================== 測試摘要 ==================
print("\n" + "=" * 100)
print("【測試摘要】")
print("=" * 100)
print(f"✓ 步驟 1: 創建 Entry#{test_entry_id}金額10元")
print(f"✓ 步驟 2: 修正前試算表: 借 {before_debit:,.0f} | 貳 {before_credit:,.0f}")
print(f"✓ 步驟 3: 創建逆仕訳 Entry#{reverse_entry_id},建立 parent-child 關係")
print(f"✓ 步驟 4: 修正後試算表: 借 {after_debit:,.0f} | 貳 {after_credit:,.0f}10元被對沖✓")
print(f"✓ 步驟 5: 恢復原始交易 + 刪除逆仕訳")
print(f"✓ 步驟 6: 恢復後試算表: 借 {final_debit:,.0f} | 貳 {final_credit:,.0f}(回到初始狀態✓)")
print(f"✓ 步驟 7: 清理測試數據")
print("\n所有步驟完成!✓")
print("=" * 100)
conn.close()