// =============================================== // trial-balance.js - 試算表データ読み込みスクリプト // =============================================== console.log("🔧 trial-balance.js ファイルが読み込まれました"); // 防止重复初始化 let trialBalanceInitialized = false; // 初期読込関数 function initTrialBalance() { // 已经初始化过就直接返回 if (trialBalanceInitialized) { console.log("⚠️ initTrialBalance() はすでに実行済みです"); return; } trialBalanceInitialized = true; console.log("✓ initTrialBalance() 関数が実行されました"); const API_URL = `/trial-balance`; // デフォルト期間を計算(5/31決算:6月開始~現在月末) function getDefaultPeriod() { const today = new Date(); const currentYear = today.getFullYear(); const currentMonth = today.getMonth() + 1; // 1-12 let fiscalStartYear, fiscalEndYear; // 6月~5月が1会計年度 if (currentMonth >= 6) { // 6月以降:当年6月1日から fiscalStartYear = currentYear; fiscalEndYear = currentYear; } else { // 1-5月:前年6月1日から fiscalStartYear = currentYear - 1; fiscalEndYear = currentYear; } const dateFrom = `${fiscalStartYear}-06-01`; // 現在月の末日を計算 const lastDayOfMonth = new Date(fiscalEndYear, currentMonth, 0).getDate(); const dateTo = `${fiscalEndYear}-${String(currentMonth).padStart( 2, "0", )}-${String(lastDayOfMonth).padStart(2, "0")}`; return { dateFrom, dateTo }; } // 試算表データを読み込む関数 function loadTrialBalance(dateFrom, dateTo) { const url = `${API_URL}?date_from=${dateFrom}&date_to=${dateTo}`; console.log("読み込み URL:", url); // 加載中のステータス表示 const loadingEl = document.getElementById("loadingStatus"); if (loadingEl) loadingEl.style.display = "inline"; fetch(url) .then((r) => { console.log("API Response Status:", r.status); if (!r.ok) throw new Error("API 返回错误: " + r.status); return r.json(); }) .then((data) => { console.log("試算表 API データ:", data); // 期間情報を更新 updatePeriodInfo(dateFrom, dateTo); const tbody = document.querySelector("#trialBalanceTable tbody"); if (!tbody) { console.error("未找到 #trialBalanceTable tbody"); return; } tbody.innerHTML = ""; // ========================================= // 科目タイプ判定関数(日本企業損益計算書対応) // ========================================= function getAccountType(accountCode) { if (!accountCode) return "unknown"; const code = parseInt(accountCode); // 営業収益(売上高) if (code === 701) return "operating_revenue"; // 非営業収益(受取利息、雑収入) if (code === 702 || code === 709) return "non_operating_revenue"; // 売上原価(仕入高) if (code === 801) return "cogs"; // 営業費用(仕入高以外の800-899、ただし520-599は除外) if (code >= 802 && code <= 899) return "operating_expense"; // 法人税等(504)- 損益計算に含めない if (code === 504) return "corporate_tax"; // 消費税等(505)- 損益計算に含めない if (code === 505) return "consumption_tax"; // その他は貸借科目 return "balance_sheet"; } // ========================================= // 各タイプの合計集計(日本企業損益計算書対応) // ========================================= let operatingRevenue = 0; // 701: 売上高(貸方) let cogs = 0; // 801: 売上原価(借方) let operatingExpenses = 0; // 802-820: 営業費用(借方) let nonOperatingRevenue = 0; // 702, 709: 営業外収益(貸方) let corporateTax = 0; // 504: 法人税等(貸方) let consumptionTax = 0; // 505: 消費税(貸方) // 税理士資料形式:P/L科目の原始借方・貸方合計 let plTotalDebit = 0; // 全費用科目の借方合計(801-820) let plTotalCredit = 0; // 全収益科目の貸方合計(701-709) let bsDebit = 0; // 貸借科目合計(借方) let bsCredit = 0; // 貸借科目合計(貸方) data.accounts.forEach((row) => { const code = row.account_code; const debit = Number(row.debit ?? 0); const credit = Number(row.credit ?? 0); const type = getAccountType(code); if (type === "operating_revenue") { operatingRevenue += credit - debit; plTotalCredit += credit; } else if (type === "non_operating_revenue") { nonOperatingRevenue += credit - debit; plTotalCredit += credit; } else if (type === "cogs") { cogs += debit - credit; plTotalDebit += debit; } else if (type === "operating_expense") { operatingExpenses += debit - credit; plTotalDebit += debit; } else if (type === "balance_sheet") { bsDebit += debit; bsCredit += credit; } }); // 日本企業損益計算書の標準フロー // ※ 504(未払法人税等)、505(未払消費税等) は負債科目のため損益計算に含めない const grossProfit = operatingRevenue - cogs; // 売上総利益 = 売上高 - 売上原価 const operatingProfit = grossProfit - operatingExpenses; // 営業利益 = 売上総利益 - 営業費用 const ordinaryProfit = operatingProfit + nonOperatingRevenue; // 経常利益 = 営業利益 + 営業外収益 // 801-820科目の合計を計算用の変量 let operatingExpense801_820Debit = 0; let operatingExpense801_820Credit = 0; // 税引前当期純利益 = 経常利益(特別損益の分類がないため) const netProfit = ordinaryProfit; // 当期純利益 = 経常利益(法人税等は損益計算に含めない) data.accounts.forEach((row) => { const code = row.account_code; const debit = Number(row.debit ?? 0); const credit = Number(row.credit ?? 0); const opening = Number(row.opening_balance ?? 0); const closing = Number(row.closing_balance ?? 0); // ========================= // 行タイプ判定 // ========================= const isTotalRow = !row.account_code; // null / "" / undefined 全覆盖 const tr = document.createElement("tr"); if (isTotalRow) { tr.classList.add("total-row"); } // indent フラグに基づくクラス追加 if (row.indent) { tr.classList.add("indent-row"); } const ratio = row.ratio ?? "0.00"; // ========================= // 借方・貸方は全科目共通でそのまま表示 // ========================= const displayDebit = debit ? debit.toLocaleString() : ""; const displayCredit = credit ? credit.toLocaleString() : ""; // 期末残高のフォーマット(マイナス値も表示) let displayClosing = ""; if (closing !== 0) { displayClosing = closing.toLocaleString(); } tr.innerHTML = `