Files
njts-accounting-core/frontend/js/trial-balance.js
2026-02-07 20:04:42 +09:00

217 lines
7.5 KiB
JavaScript
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.
// ===============================================
// trial-balance.js - 試算表データ読み込みスクリプト
// ===============================================
console.log("🔧 trial-balance.js ファイルが読み込まれました");
// 初期读入関数
function initTrialBalance() {
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 = "";
let totalOpening = 0;
let totalDebit = 0;
let totalCredit = 0;
let totalClosing = 0;
data.accounts.forEach((row) => {
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 全覆盖
// 明细行だけ合計に含める
if (!isTotalRow) {
totalOpening += opening;
totalDebit += debit;
totalCredit += credit;
totalClosing += closing;
}
const tr = document.createElement("tr");
if (isTotalRow) {
tr.classList.add("total-row");
}
const ratio = row.ratio ?? "0.00";
tr.innerHTML = `
<td class="left">${row.account_code ?? ""}</td>
<td class="left">${row.account_name ?? ""}</td>
<td class="right">${opening ? opening.toLocaleString() : ""}</td>
<td class="right">${debit ? debit.toLocaleString() : ""}</td>
<td class="right">${credit ? credit.toLocaleString() : ""}</td>
<td class="right">${closing ? closing.toLocaleString() : ""}</td>
<td class="right">${ratio}</td>
`;
tbody.appendChild(tr);
});
// =========================
// フッター合計
// =========================
document.getElementById("totalOpening").textContent =
totalOpening.toLocaleString();
document.getElementById("totalDebit").textContent =
totalDebit.toLocaleString();
document.getElementById("totalCredit").textContent =
totalCredit.toLocaleString();
document.getElementById("totalClosing").textContent =
totalClosing.toLocaleString();
document.getElementById("totalRatio").textContent =
data.totals?.ratio ?? "100.00";
// 加載中ステータスを非表示
const loadingEl = document.getElementById("loadingStatus");
if (loadingEl) loadingEl.style.display = "none";
})
.catch((err) => {
console.error("試算表読取失敗:", err);
const tbody = document.querySelector("#trialBalanceTable tbody");
if (tbody) {
tbody.innerHTML = `<tr><td colspan="7" style="text-align:center; color:red;">エラー: ${err.message}</td></tr>`;
}
// 加載中ステータスを非表示
const loadingEl = document.getElementById("loadingStatus");
if (loadingEl) loadingEl.style.display = "none";
alert(
`試算表読取失敗: ${err.message}\n\nコンソールログ(F12)を確認してください`,
);
});
}
// 期間情報を更新する関数
function updatePeriodInfo(dateFrom, dateTo) {
const fromDate = new Date(dateFrom);
const toDate = new Date(dateTo);
const fromYear = fromDate.getFullYear() - 2018; // 令和変換2019年=令和1年
const toYear = toDate.getFullYear() - 2018;
const periodText = `令和${fromYear}${
fromDate.getMonth() + 1
}${fromDate.getDate()} 令和${toYear}${
toDate.getMonth() + 1
}${toDate.getDate()}`;
document.getElementById("periodInfo").textContent = periodText;
}
// 検索ボタンのイベント
document.getElementById("btnSearch").addEventListener("click", () => {
const dateFrom = document.getElementById("dateFrom").value;
const dateTo = document.getElementById("dateTo").value;
if (!dateFrom || !dateTo) {
alert("開始年月日と終了年月日を入力してください");
return;
}
if (dateFrom > dateTo) {
alert("開始年月日は終了年月日より前の日付を指定してください");
return;
}
loadTrialBalance(dateFrom, dateTo);
});
// 全年度表示ボタンのイベント
document.getElementById("btnFullYear").addEventListener("click", () => {
const currentYear = new Date().getFullYear();
const dateFrom = `${currentYear}-01-01`;
const dateTo = `${currentYear}-12-31`;
document.getElementById("dateFrom").value = dateFrom;
document.getElementById("dateTo").value = dateTo;
loadTrialBalance(dateFrom, dateTo);
});
// 初期読み込み5/31決算に対応
try {
const defaultPeriod = getDefaultPeriod();
document.getElementById("dateFrom").value = defaultPeriod.dateFrom;
document.getElementById("dateTo").value = defaultPeriod.dateTo;
loadTrialBalance(defaultPeriod.dateFrom, defaultPeriod.dateTo);
console.log("✓ 初期読み込み完了");
} catch (err) {
console.error("初期読み込みエラー:", err);
}
}
// 複数の方式で初期化を実行iOS互換性を向上
document.addEventListener("DOMContentLoaded", initTrialBalance);
window.addEventListener("load", initTrialBalance);
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initTrialBalance);
} else {
// ページがすでに読み込まれている場合、すぐに実行
setTimeout(initTrialBalance, 100);
}