修正
This commit is contained in:
174
backend/app/core/revision_manager.py
Normal file
174
backend/app/core/revision_manager.py
Normal file
@@ -0,0 +1,174 @@
|
||||
"""
|
||||
修正版本追踪管理器
|
||||
記錄日記條目的修正歷史,追踪原始交易和修正版本
|
||||
"""
|
||||
|
||||
from decimal import Decimal
|
||||
from datetime import date
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
def mark_old_version_as_outdated(conn, original_entry_id: int) -> None:
|
||||
"""
|
||||
將舊版本標記為非最新版本 (is_latest = false)
|
||||
"""
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("""
|
||||
UPDATE journal_entries
|
||||
SET is_latest = false
|
||||
WHERE original_entry_id = %s OR journal_entry_id = %s
|
||||
ORDER BY created_at DESC
|
||||
OFFSET 1
|
||||
""", (original_entry_id, original_entry_id))
|
||||
|
||||
|
||||
def create_new_revision(
|
||||
conn,
|
||||
entry_date: date,
|
||||
description: str,
|
||||
fiscal_year: int,
|
||||
lines: list,
|
||||
created_by: str = "system",
|
||||
original_entry_id: Optional[int] = None
|
||||
) -> int:
|
||||
"""
|
||||
創建新的修正版本
|
||||
|
||||
返回: 新創建的 journal_entry_id
|
||||
"""
|
||||
|
||||
with conn.cursor() as cur:
|
||||
# ① 如果是修正交易,獲取最新版本的 revision_count
|
||||
revision_count = 1
|
||||
if original_entry_id:
|
||||
# 获取原始交易 ID(可能已有多個版本)
|
||||
cur.execute("""
|
||||
SELECT revision_count FROM journal_entries
|
||||
WHERE (journal_entry_id = %s OR original_entry_id = %s)
|
||||
AND is_latest = true
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
""", (original_entry_id, original_entry_id))
|
||||
|
||||
row = cur.fetchone()
|
||||
if row:
|
||||
revision_count = row["revision_count"] + 1
|
||||
else:
|
||||
# 如果找不到最新版本,說明 original_entry_id 是第一個版本
|
||||
revision_count = 2
|
||||
|
||||
# ② 如果是修正,標記舊版本
|
||||
if original_entry_id:
|
||||
cur.execute("""
|
||||
UPDATE journal_entries
|
||||
SET is_latest = false
|
||||
WHERE (journal_entry_id = %s OR original_entry_id = %s)
|
||||
AND is_latest = true
|
||||
""", (original_entry_id, original_entry_id))
|
||||
|
||||
# ③ 創建新版本
|
||||
normalized_original_id = original_entry_id if original_entry_id else None
|
||||
|
||||
cur.execute("""
|
||||
INSERT INTO journal_entries (
|
||||
entry_date,
|
||||
description,
|
||||
fiscal_year,
|
||||
is_latest,
|
||||
revision_count,
|
||||
original_entry_id,
|
||||
is_deleted,
|
||||
created_by
|
||||
)
|
||||
VALUES (%s, %s, %s, true, %s, %s, false, %s)
|
||||
RETURNING journal_entry_id
|
||||
""", (
|
||||
entry_date,
|
||||
description,
|
||||
fiscal_year,
|
||||
revision_count,
|
||||
normalized_original_id,
|
||||
created_by
|
||||
))
|
||||
|
||||
entry_id = cur.fetchone()["journal_entry_id"]
|
||||
|
||||
# ④ 插入交易明細
|
||||
for line in lines:
|
||||
# 轉換 tax_direction
|
||||
tax_dir_db = None
|
||||
if line.get("tax_direction"):
|
||||
if line["tax_direction"] == 'paid':
|
||||
tax_dir_db = 'INPUT'
|
||||
elif line["tax_direction"] == 'received':
|
||||
tax_dir_db = 'OUTPUT'
|
||||
else:
|
||||
tax_dir_db = line["tax_direction"].upper()
|
||||
|
||||
cur.execute("""
|
||||
INSERT INTO journal_lines (
|
||||
journal_entry_id,
|
||||
account_id,
|
||||
debit,
|
||||
credit,
|
||||
tax_rate,
|
||||
tax_direction
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s)
|
||||
""", (
|
||||
entry_id,
|
||||
line.get("account_id"),
|
||||
line.get("debit", Decimal("0")),
|
||||
line.get("credit", Decimal("0")),
|
||||
line.get("tax_rate"),
|
||||
tax_dir_db
|
||||
))
|
||||
|
||||
return entry_id
|
||||
|
||||
|
||||
def get_current_version(conn, journal_entry_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
取得指定交易的最新版本資訊
|
||||
"""
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("""
|
||||
SELECT
|
||||
journal_entry_id,
|
||||
entry_date,
|
||||
description,
|
||||
revision_count,
|
||||
original_entry_id,
|
||||
is_latest,
|
||||
created_at,
|
||||
created_by
|
||||
FROM journal_entries
|
||||
WHERE journal_entry_id = %s
|
||||
""", (journal_entry_id,))
|
||||
|
||||
row = cur.fetchone()
|
||||
if row:
|
||||
return dict(row)
|
||||
return None
|
||||
|
||||
|
||||
def get_revision_history(conn, original_entry_id: int) -> list:
|
||||
"""
|
||||
取得某個交易的所有修正版本歷史
|
||||
"""
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("""
|
||||
SELECT
|
||||
journal_entry_id,
|
||||
entry_date,
|
||||
description,
|
||||
revision_count,
|
||||
is_latest,
|
||||
created_at,
|
||||
created_by
|
||||
FROM journal_entries
|
||||
WHERE original_entry_id = %s OR journal_entry_id = %s
|
||||
ORDER BY created_at ASC
|
||||
""", (original_entry_id, original_entry_id))
|
||||
|
||||
rows = cur.fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
Reference in New Issue
Block a user