This commit is contained in:
admin
2026-02-20 15:47:27 +09:00
parent c60cbf2d9a
commit 584530937b
108 changed files with 12112 additions and 416 deletions

View 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]