修正
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
.account-search-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.account-search-input {
|
||||
@@ -52,6 +53,7 @@
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.account-search-input:focus {
|
||||
@@ -84,6 +86,9 @@
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.account-option:hover,
|
||||
@@ -94,11 +99,14 @@
|
||||
.account-option-strong {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
display: inline;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.account-option-light {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -241,43 +249,81 @@
|
||||
const container = inputElement.closest(".account-search-container");
|
||||
const dropdown = container.querySelector(".account-dropdown");
|
||||
|
||||
inputElement.addEventListener("input", (e) => {
|
||||
const searchText = e.target.value.toLowerCase().trim();
|
||||
// 科目選択履歴を保存(journal-entry.htmlと共通のlocalStorageキー)
|
||||
function saveAccountToRecentEdit(accountId) {
|
||||
if (!accountId) return;
|
||||
let recent = JSON.parse(localStorage.getItem("recentAccounts") || "[]");
|
||||
recent = recent.filter((id) => id !== accountId);
|
||||
recent.unshift(accountId);
|
||||
if (recent.length > 20) recent = recent.slice(0, 20);
|
||||
localStorage.setItem("recentAccounts", JSON.stringify(recent));
|
||||
}
|
||||
|
||||
if (!searchText) {
|
||||
dropdown.classList.remove("active");
|
||||
return;
|
||||
}
|
||||
function makeLbl(text) {
|
||||
const lbl = document.createElement("div");
|
||||
lbl.style.cssText = "padding:3px 12px;font-size:11px;color:#888;background:#f5f5f5;font-weight:bold;border-bottom:1px solid #e0e0e0;";
|
||||
lbl.textContent = text;
|
||||
return lbl;
|
||||
}
|
||||
|
||||
// 过滤账户
|
||||
const filtered = accounts.filter((acc) => {
|
||||
const code = acc.account_code.toLowerCase();
|
||||
const name = acc.account_name.toLowerCase();
|
||||
return code.includes(searchText) || name.includes(searchText);
|
||||
});
|
||||
|
||||
// 生成下拉建议
|
||||
dropdown.innerHTML = "";
|
||||
if (filtered.length === 0) {
|
||||
dropdown.innerHTML = `<div style="padding: 8px 12px; color: #999;">該当する科目がありません</div>`;
|
||||
} else {
|
||||
filtered.slice(0, 20).forEach((acc) => {
|
||||
const option = document.createElement("div");
|
||||
option.className = "account-option";
|
||||
option.innerHTML = `
|
||||
<span class="account-option-strong">${acc.account_code}</span>
|
||||
<span class="account-option-light">${acc.account_name}</span>
|
||||
`;
|
||||
option.addEventListener("click", () => {
|
||||
inputElement.value = `${acc.account_code} ${acc.account_name}`;
|
||||
inputElement.dataset.accountId = acc.account_id;
|
||||
dropdown.classList.remove("active");
|
||||
});
|
||||
dropdown.appendChild(option);
|
||||
// 显示科目下拉列表的函数
|
||||
function showAccountList(searchText = "") {
|
||||
const isFiltered = searchText.length > 0;
|
||||
let filtered = accounts;
|
||||
if (isFiltered) {
|
||||
filtered = accounts.filter((acc) => {
|
||||
const code = acc.account_code.toLowerCase();
|
||||
const name = acc.account_name.toLowerCase();
|
||||
return code.includes(searchText) || name.includes(searchText);
|
||||
});
|
||||
}
|
||||
|
||||
dropdown.innerHTML = "";
|
||||
|
||||
function appendOpt(acc) {
|
||||
const option = document.createElement("div");
|
||||
option.className = "account-option";
|
||||
option.innerHTML = `<span class="account-option-strong">${acc.account_code}</span><span class="account-option-light">${acc.account_name}</span>`;
|
||||
option.addEventListener("click", () => {
|
||||
inputElement.value = `${acc.account_code} ${acc.account_name}`;
|
||||
inputElement.dataset.accountId = acc.account_id;
|
||||
dropdown.classList.remove("active");
|
||||
saveAccountToRecentEdit(acc.account_id);
|
||||
});
|
||||
dropdown.appendChild(option);
|
||||
}
|
||||
|
||||
if (filtered.length === 0) {
|
||||
dropdown.innerHTML = `<div style="padding: 8px 12px; color: #999;">該当する科目がありません</div>`;
|
||||
} else if (isFiltered) {
|
||||
const sorted = filtered.slice().sort((a, b) => a.account_code.localeCompare(b.account_code));
|
||||
sorted.slice(0, 50).forEach(appendOpt);
|
||||
} else {
|
||||
const recentIds = JSON.parse(localStorage.getItem("recentAccounts") || "[]");
|
||||
const recentItems = recentIds.map((id) => filtered.find((a) => a.account_id === id)).filter(Boolean);
|
||||
const recentSet = new Set(recentIds);
|
||||
const otherItems = filtered
|
||||
.filter((a) => !recentSet.has(a.account_id))
|
||||
.sort((a, b) => a.account_code.localeCompare(b.account_code));
|
||||
|
||||
if (recentItems.length > 0) {
|
||||
dropdown.appendChild(makeLbl("⭐ 最近使った科目"));
|
||||
recentItems.forEach(appendOpt);
|
||||
const sep = document.createElement("div");
|
||||
sep.style.cssText = "border-top:1px solid #e8e8e8;margin:2px 0;";
|
||||
dropdown.appendChild(sep);
|
||||
}
|
||||
dropdown.appendChild(makeLbl("📋 すべての科目"));
|
||||
otherItems.slice(0, 50).forEach(appendOpt);
|
||||
}
|
||||
|
||||
dropdown.classList.add("active");
|
||||
}
|
||||
|
||||
// 入力時:フィルター
|
||||
inputElement.addEventListener("input", (e) => {
|
||||
const searchText = e.target.value.toLowerCase().trim();
|
||||
showAccountList(searchText);
|
||||
});
|
||||
|
||||
// クリック以外の場所のドロップダウンを非表示
|
||||
@@ -287,11 +333,9 @@
|
||||
}
|
||||
});
|
||||
|
||||
// フォーカス時にドロップダウンを表示(既存値がある場合)
|
||||
// フォーカス時:すべての科目を表示
|
||||
inputElement.addEventListener("focus", () => {
|
||||
if (inputElement.value) {
|
||||
dropdown.classList.add("active");
|
||||
}
|
||||
showAccountList(inputElement.value.toLowerCase().trim());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -386,13 +430,20 @@
|
||||
|
||||
if (line) {
|
||||
// Find the account and populate the input
|
||||
const account = accounts.find(a => a.account_id === line.account_id);
|
||||
const account = accounts.find(
|
||||
(a) => a.account_id === line.account_id,
|
||||
);
|
||||
if (account) {
|
||||
accountInput.value = `${account.account_code} ${account.account_name}`;
|
||||
accountInput.dataset.accountId = account.account_id;
|
||||
}
|
||||
tr.querySelectorAll("input")[1].value = line.debit || "";
|
||||
tr.querySelectorAll("input")[2].value = line.credit || "";
|
||||
// type="number" のみを取得
|
||||
const numberInputs = tr.querySelectorAll("input[type='number']");
|
||||
// Decimal 値を数値に変換してから代入
|
||||
const debitVal = Number(line.debit) || 0;
|
||||
const creditVal = Number(line.credit) || 0;
|
||||
numberInputs[0].value = debitVal > 0 ? String(debitVal) : "";
|
||||
numberInputs[1].value = creditVal > 0 ? String(creditVal) : "";
|
||||
}
|
||||
|
||||
// 入力時に合計を自動更新
|
||||
@@ -414,8 +465,26 @@
|
||||
let d = 0,
|
||||
c = 0;
|
||||
document.querySelectorAll("#linesTable tbody tr").forEach((tr) => {
|
||||
d += Number(tr.querySelectorAll("input")[0].value || 0);
|
||||
c += Number(tr.querySelectorAll("input")[1].value || 0);
|
||||
// type="number" のみを取得(科目検索入力框を除外)
|
||||
const numberInputs = tr.querySelectorAll("input[type='number']");
|
||||
if (numberInputs.length >= 2) {
|
||||
const debitStr = numberInputs[0]?.value;
|
||||
const creditStr = numberInputs[1]?.value;
|
||||
|
||||
// 空または 0 を含む場合は 0、そうでなければ数値に変換
|
||||
const debitVal =
|
||||
debitStr && debitStr.trim()
|
||||
? Number(debitStr.toString().replace(/,/g, ""))
|
||||
: 0;
|
||||
const creditVal =
|
||||
creditStr && creditStr.trim()
|
||||
? Number(creditStr.toString().replace(/,/g, ""))
|
||||
: 0;
|
||||
|
||||
// NaN チェック
|
||||
if (!isNaN(debitVal)) d += debitVal;
|
||||
if (!isNaN(creditVal)) c += creditVal;
|
||||
}
|
||||
});
|
||||
document.getElementById("debitTotal").textContent = d.toLocaleString();
|
||||
document.getElementById("creditTotal").textContent = c.toLocaleString();
|
||||
@@ -429,13 +498,28 @@
|
||||
result.textContent = "";
|
||||
result.className = "";
|
||||
|
||||
const entryDate = document.getElementById("entryDate").value;
|
||||
const entryDateInput = document.getElementById("entryDate");
|
||||
const entryDate = entryDateInput.value;
|
||||
const desc = document.getElementById("description").value;
|
||||
|
||||
if (!entryDate || !desc) {
|
||||
if (entryDateInput.validity.badInput) {
|
||||
showError(
|
||||
"日付が正しくありません。存在しない日付が入力されています(例:11月31日は無効です)",
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!entryDate && !desc) {
|
||||
showError("日付と摘要は必須です");
|
||||
return;
|
||||
}
|
||||
if (!entryDate) {
|
||||
showError("日付を入力してください");
|
||||
return;
|
||||
}
|
||||
if (!desc) {
|
||||
showError("摘要を入力してください");
|
||||
return;
|
||||
}
|
||||
|
||||
const lines = [];
|
||||
let d = 0,
|
||||
@@ -444,8 +528,9 @@
|
||||
document.querySelectorAll("#linesTable tbody tr").forEach((tr) => {
|
||||
const accountInput = tr.querySelector(".account-search-input");
|
||||
const accountId = Number(accountInput.dataset.accountId || 0);
|
||||
const debit = Number(tr.querySelectorAll("input")[1].value || 0);
|
||||
const credit = Number(tr.querySelectorAll("input")[2].value || 0);
|
||||
const numberInputs = tr.querySelectorAll("input[type='number']");
|
||||
const debit = Number(numberInputs[0]?.value || 0);
|
||||
const credit = Number(numberInputs[1]?.value || 0);
|
||||
if (debit === 0 && credit === 0) return;
|
||||
lines.push({ account_id: accountId, debit, credit });
|
||||
d += debit;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,18 @@
|
||||
// ===============================================
|
||||
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`;
|
||||
@@ -69,12 +79,90 @@ function initTrialBalance() {
|
||||
|
||||
tbody.innerHTML = "";
|
||||
|
||||
let totalOpening = 0;
|
||||
let totalDebit = 0;
|
||||
let totalCredit = 0;
|
||||
let totalClosing = 0;
|
||||
// =========================================
|
||||
// 科目タイプ判定関数(日本企業損益計算書対応)
|
||||
// =========================================
|
||||
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);
|
||||
@@ -85,14 +173,6 @@ function initTrialBalance() {
|
||||
// =========================
|
||||
const isTotalRow = !row.account_code; // null / "" / undefined 全覆盖
|
||||
|
||||
// 明细行だけ合計に含める
|
||||
if (!isTotalRow) {
|
||||
totalOpening += opening;
|
||||
totalDebit += debit;
|
||||
totalCredit += credit;
|
||||
totalClosing += closing;
|
||||
}
|
||||
|
||||
const tr = document.createElement("tr");
|
||||
|
||||
if (isTotalRow) {
|
||||
@@ -106,32 +186,32 @@ function initTrialBalance() {
|
||||
|
||||
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 = `
|
||||
<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">${displayDebit}</td>
|
||||
<td class="right">${displayCredit}</td>
|
||||
<td class="right">${displayClosing}</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");
|
||||
@@ -166,9 +246,15 @@ function initTrialBalance() {
|
||||
toDate.getMonth() + 1
|
||||
}月 ${toDate.getDate()}日`;
|
||||
document.getElementById("periodInfo").textContent = periodText;
|
||||
|
||||
// thead内の期間情報も更新(印刷用)
|
||||
const theadPeriodInfo = document.getElementById("theadPeriodInfo");
|
||||
if (theadPeriodInfo) {
|
||||
theadPeriodInfo.textContent = periodText;
|
||||
}
|
||||
}
|
||||
|
||||
// 検索ボタンのイベント
|
||||
// 檢索按鈕的事件
|
||||
document.getElementById("btnSearch").addEventListener("click", () => {
|
||||
const dateFrom = document.getElementById("dateFrom").value;
|
||||
const dateTo = document.getElementById("dateTo").value;
|
||||
@@ -198,6 +284,31 @@ function initTrialBalance() {
|
||||
loadTrialBalance(dateFrom, dateTo);
|
||||
});
|
||||
|
||||
// 印刷ボタンのイベント(最新データを読み込んでから印刷)
|
||||
document.getElementById("btnPrint").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);
|
||||
|
||||
// データ読込完了を待って印刷開始(少し遅延させる)
|
||||
setTimeout(() => {
|
||||
setupPrintDate(); // 打印前更新日期
|
||||
window.print();
|
||||
}, 800);
|
||||
});
|
||||
|
||||
// 初期読み込み(5/31決算に対応)
|
||||
try {
|
||||
const defaultPeriod = getDefaultPeriod();
|
||||
@@ -219,3 +330,38 @@ if (document.readyState === "loading") {
|
||||
// ページがすでに読み込まれている場合、すぐに実行
|
||||
setTimeout(initTrialBalance, 100);
|
||||
}
|
||||
|
||||
// 打印日期和页码设置
|
||||
// ===============================================
|
||||
function setupPrintDate() {
|
||||
const printDateEl = document.getElementById("printDate");
|
||||
if (!printDateEl) return;
|
||||
|
||||
// 设置打印日期
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, "0");
|
||||
const date = String(today.getDate()).padStart(2, "0");
|
||||
const dateStr = `${year}年${month.replace(/^0/, "")}月${date.replace(
|
||||
/^0/,
|
||||
"",
|
||||
)}日`;
|
||||
|
||||
printDateEl.textContent = `印刷日:${dateStr}`;
|
||||
|
||||
// thead内の印刷日も更新
|
||||
const theadPrintDate = document.getElementById("theadPrintDate");
|
||||
if (theadPrintDate) {
|
||||
theadPrintDate.textContent = `印刷日:${dateStr}`;
|
||||
console.log("✓ 印刷日を更新しました:", theadPrintDate.textContent);
|
||||
} else {
|
||||
console.warn("⚠️ theadPrintDate要素が見つかりません");
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载时设置一次(仅一次)
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", setupPrintDate, { once: true });
|
||||
} else {
|
||||
setupPrintDate();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,10 @@
|
||||
td.right {
|
||||
text-align: right;
|
||||
}
|
||||
td.center,
|
||||
th.center {
|
||||
text-align: center;
|
||||
}
|
||||
tr.total-row td {
|
||||
background-color: #d8d8d8 !important;
|
||||
font-weight: bold;
|
||||
@@ -91,10 +95,171 @@
|
||||
tr.indent-row td:nth-child(2) {
|
||||
padding-left: 40px !important;
|
||||
}
|
||||
tfoot td {
|
||||
font-weight: bold;
|
||||
background: #e0e0e0;
|
||||
border-top: 2px solid #333;
|
||||
.print-button {
|
||||
background: #ff9800;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
margin-left: 10px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
.print-button:hover {
|
||||
background: #e68900;
|
||||
}
|
||||
/* 画面表示時:thead内の印刷用ヘッダー行を非表示 */
|
||||
tr.print-header-title,
|
||||
tr.print-header-period,
|
||||
tr.print-header-meta {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.print-header-cell {
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
background-color: white !important;
|
||||
padding: 2px 5px !important;
|
||||
}
|
||||
|
||||
@media print {
|
||||
* {
|
||||
-webkit-print-color-adjust: exact !important;
|
||||
print-color-adjust: exact !important;
|
||||
color-adjust: exact !important;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* 画面用の要素を印刷時に隠す */
|
||||
#printDate,
|
||||
h2,
|
||||
.period-info,
|
||||
.back-button,
|
||||
.search-form,
|
||||
.print-button,
|
||||
#loadingStatus {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* thead内の印刷用ヘッダー行を表示 */
|
||||
tr.print-header-title,
|
||||
tr.print-header-period,
|
||||
tr.print-header-meta {
|
||||
display: table-row !important;
|
||||
}
|
||||
|
||||
.print-header-cell {
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
background-color: white !important;
|
||||
padding: 3px 5px !important;
|
||||
}
|
||||
|
||||
/* 印刷時の単位・印刷日のスタイリング */
|
||||
tr.print-header-meta th {
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
padding: 2px 5px !important;
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
tr.print-header-meta th:last-child {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
tr.print-header-meta div {
|
||||
text-align: right !important;
|
||||
font-size: 10px !important;
|
||||
font-weight: normal !important;
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
#theadPrintDate {
|
||||
text-align: right !important;
|
||||
align-items: center !important;
|
||||
flex-wrap: wrap !important;
|
||||
gap: 20px !important;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
thead {
|
||||
display: table-header-group;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
tfoot {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #e8e8e8 !important;
|
||||
font-weight: bold;
|
||||
padding: 5px 6px;
|
||||
border: 1px solid #666;
|
||||
page-break-inside: avoid;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid #666;
|
||||
padding: 4px 5px;
|
||||
font-size: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
tr.total-row td {
|
||||
background-color: #d8d8d8 !important;
|
||||
font-weight: bold;
|
||||
border-top: 2px solid #333;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
tr.indent-row td:nth-child(2) {
|
||||
padding-left: 20px !important;
|
||||
}
|
||||
|
||||
td.left {
|
||||
text-align: left;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
td.right {
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td.center,
|
||||
th.center {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@page {
|
||||
size: A4 portrait;
|
||||
margin-top: 10mm;
|
||||
margin-bottom: 20mm;
|
||||
margin-left: 10mm;
|
||||
margin-right: 10mm;
|
||||
|
||||
@bottom-center {
|
||||
content: "第 " counter(page) " 页";
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -115,6 +280,7 @@
|
||||
>
|
||||
← 首ページに戻る
|
||||
</button>
|
||||
|
||||
<h2>残高試算表(貸借・損益)</h2>
|
||||
|
||||
<div
|
||||
@@ -133,18 +299,68 @@
|
||||
|
||||
<button id="btnSearch">検索</button>
|
||||
<button id="btnFullYear" class="secondary">全年度表示</button>
|
||||
<button id="btnPrint" class="print-button">印刷</button>
|
||||
</div>
|
||||
|
||||
<div class="period-info">
|
||||
<span id="periodInfo">令和7年 1月 1日 ~ 令和7年 12月31日</span>
|
||||
<span style="margin-left: 20px">単位: 円</span>
|
||||
<span style="margin-left: 20px; float: right">単位: 円</span>
|
||||
</div>
|
||||
|
||||
<table id="trialBalanceTable">
|
||||
<thead>
|
||||
<tr class="print-header-title">
|
||||
<th
|
||||
colspan="7"
|
||||
class="print-header-cell"
|
||||
style="text-align: center; font-size: 14px; font-weight: bold"
|
||||
>
|
||||
残高試算表(貸借・損益)
|
||||
</th>
|
||||
</tr>
|
||||
<tr class="print-header-period">
|
||||
<th
|
||||
colspan="7"
|
||||
class="print-header-cell"
|
||||
style="text-align: center; font-size: 11px; font-weight: normal"
|
||||
id="theadPeriodInfo"
|
||||
></th>
|
||||
</tr>
|
||||
<tr class="print-header-meta">
|
||||
<th colspan="5" class="print-header-cell"></th>
|
||||
<th
|
||||
colspan="2"
|
||||
class="print-header-cell"
|
||||
style="text-align: right !important; padding: 2px 5px"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
text-align: right !important;
|
||||
font-size: 10px;
|
||||
line-height: 1.2;
|
||||
display: block;
|
||||
width: 100%;
|
||||
"
|
||||
id="theadPrintDate"
|
||||
>
|
||||
印刷日:2026年2月25日
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
text-align: right !important;
|
||||
font-size: 10px;
|
||||
line-height: 1.2;
|
||||
display: block;
|
||||
width: 100%;
|
||||
"
|
||||
>
|
||||
単位:円
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="left">科目コード</th>
|
||||
<th class="left">科目名称</th>
|
||||
<th class="center">科目名称</th>
|
||||
<th>期首残高</th>
|
||||
<th>借方発生額</th>
|
||||
<th>貸方発生額</th>
|
||||
@@ -155,16 +371,6 @@
|
||||
<tbody>
|
||||
<!-- JS 动态插入 -->
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="2" class="left">合計</td>
|
||||
<td id="totalOpening">0</td>
|
||||
<td id="totalDebit">0</td>
|
||||
<td id="totalCredit">0</td>
|
||||
<td id="totalClosing">0</td>
|
||||
<td id="totalRatio">100.00</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<script src="js/trial-balance.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user