// ============================================================================ // 【前端集成指南】 - 修正版本追踪系統 // ============================================================================ /** * 【API 變更概要】 * * 舊 API: * - POST /journal-entries (parent_entry_id) // 創建逆仕訳 * - 複雜的逆仕訳生成邏輯 * * 新 API: * - POST /journal-entries (original_entry_id) // 直接創建修正版本 * - GET /journal-entries/{id}/revision-history // 查看修正歷史 */ // ============================================================================ // 【1】創建新交易(無修正)- 基本用法 // ============================================================================ async function createJournalEntry(entryData) { const payload = { entry_date: entryData.date, // "2025-01-15" description: entryData.description, // "銷售收入" lines: entryData.lines, // 交易明細 tax_paid_account_id: entryData.taxPaidId, tax_received_account_id: entryData.taxReceivedId, rounding_mode: "round" // 注意:這裡 original_entry_id 沒有指定,表示這是新交易 }; const response = await fetch("/journal-entries", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }); if (response.ok) { const result = await response.json(); console.log("✓ 交易創建成功:", result.journal_entry_id); return result; } else { alert("❌ 創建失敗"); } } // ============================================================================ // 【2】創建修正版本 - 關鍵變更 // ============================================================================ async function createRevisionEntry(originalEntryId, entryData) { const payload = { entry_date: entryData.date, description: `【修正】${entryData.description}`, // 添加【修正】標記 lines: entryData.lines, tax_paid_account_id: entryData.taxPaidId, tax_received_account_id: entryData.taxReceivedId, rounding_mode: "round", // ✨ 新參數:指向原始交易 original_entry_id: originalEntryId }; const response = await fetch("/journal-entries", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }); if (response.ok) { const result = await response.json(); console.log("✓ 修正版本創建成功:"); console.log(` 原始交易 ID: ${originalEntryId}`); console.log(` 新版本 ID: ${result.journal_entry_id}`); console.log(` 版本: ${result.revision_created ? "新版本" : "覆蓋"}`); return result; } } // ============================================================================ // 【3】查看修正歷史 - 新功能 // ============================================================================ async function viewRevisionHistory(journalId) { const response = await fetch(`/journal-entries/${journalId}/revision-history`); if (response.ok) { const data = await response.json(); console.log(`修正歷史 (原始交易 ID: ${data.original_entry_id}):`); console.log(`總版本數: ${data.total_versions}`); data.versions.forEach(version => { const status = version.is_latest ? "【最新】" : "【已過時】"; console.log(` 版本 ${version.revision_count}: ${status} - 交易 ID: ${version.journal_entry_id} - 摘要: ${version.description} - 建立時間: ${version.created_at} `); }); return data; } } // ============================================================================ // 【4】前端修正流程 - 完整示例 // ============================================================================ async function handleEditTransaction(originalEntryId) { // 步驟 1: 顯示修正對話框 const originalData = await fetchJournalEntry(originalEntryId); // 現有的 API const editedData = showEditDialog(originalData); // 用户編緬 if (!editedData) { console.log("⚠️ 編輯已取消"); return; } // 步驟 2: 檢查是否有實際變更 if (areEntriesEqual(originalData, editedData)) { console.log("⚠️ 沒有任何變更"); return; } // 步驟 3: 創建修正版本 const result = await createRevisionEntry(originalEntryId, editedData); if (result && result.status === "ok") { // 步驟 4: 更新頁面 refreshJournalList(); // 重新加載列表 alert(`✓ 交易已修正。新版本 ID: ${result.journal_entry_id}`); // 步驟 5: 可選 - 顯示修正歷史 // await showRevisionHistory(originalEntryId); } } // ============================================================================ // 【5】試算表查詢 - 前端優化 // ============================================================================ /** * 舊做法(不需要): * const entries = await fetchAllJournalEntries(); * const latestOnly = entries.filter(e => e.parent_entry_id === null); * * 新做法(推薦): * 後端已經自動過濾, 返回的都是 is_latest = true 的交易 */ async function fetchTrialBalance(fromDate, toDate) { // 不需要任何客戶端過濾邏輯 // 後端已確保只返回 is_latest = true 的交易 const response = await fetch( `/journal-entries?from_date=${fromDate}&to_date=${toDate}`, { method: "GET" } ); if (response.ok) { const entries = await response.json(); // entries 已經只包含最新版本 // 直接計算試算表 return calculateTrialBalance(entries); } } // ============================================================================ // 【6】修正歷史界面 - UI 示例 // ============================================================================ function displayRevisionHistory(journalId) { // HTML 結構 const html = `
摘要: ${version.description}
日期: ${version.entry_date}
建立: ${new Date(version.created_at).toLocaleString()}
操作員: ${version.created_by}