修正
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
<h2>修正仕訳入力</h2>
|
||||
|
||||
<label>仕訳日</label>
|
||||
<input type="date" id="entryDate" />
|
||||
<input type="date" id="entryDate" min="1900-01-01" max="9999-12-31" />
|
||||
|
||||
<label>摘要</label>
|
||||
<input type="text" id="description" style="width: 60%" />
|
||||
@@ -143,6 +143,12 @@
|
||||
tr.querySelectorAll("input")[0].value = line.debit || "";
|
||||
tr.querySelectorAll("input")[1].value = line.credit || "";
|
||||
}
|
||||
|
||||
// 入力時に合計を自動更新
|
||||
tr.querySelectorAll("input").forEach((input) => {
|
||||
input.addEventListener("input", recalc);
|
||||
input.addEventListener("change", recalc);
|
||||
});
|
||||
}
|
||||
|
||||
function removeRow(btn) {
|
||||
@@ -197,6 +203,12 @@
|
||||
if (lines.length < 2) return showError("仕訳行は2行以上必要です");
|
||||
if (d !== c) return showError("借方合計と貸方合計が一致していません");
|
||||
|
||||
// 逆仕訳IDを親IDとして取得(逆仕訳が存在する場合)
|
||||
const src = localStorage.getItem("editSource");
|
||||
const srcData = src ? JSON.parse(src) : null;
|
||||
// 【修正後】仕訳のparent_entry_idは、直前に作成された逆仕訳のID
|
||||
const parentEntryId = srcData?.reversed_journal_entry_id || null;
|
||||
|
||||
const payload = {
|
||||
entry_date: entryDate,
|
||||
description: desc,
|
||||
@@ -204,6 +216,7 @@
|
||||
tax_paid_account_id: null,
|
||||
tax_received_account_id: null,
|
||||
rounding_mode: "floor",
|
||||
parent_entry_id: parentEntryId,
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -103,6 +103,33 @@
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
|
||||
<div
|
||||
style="
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
background: #f9f9f9;
|
||||
border: 1px solid #ddd;
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
font-weight: bold;
|
||||
"
|
||||
>
|
||||
<div>
|
||||
<label>借方合計:</label>
|
||||
<span id="totalDebit" style="color: #0066cc; font-size: 16px">0</span>
|
||||
円
|
||||
</div>
|
||||
<div>
|
||||
<label>貸方合計:</label>
|
||||
<span id="totalCredit" style="color: #cc0000; font-size: 16px">0</span>
|
||||
円
|
||||
</div>
|
||||
<div
|
||||
id="balanceStatus"
|
||||
style="margin-left: auto; padding: 4px 12px; border-radius: 4px"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 10px; display: flex; gap: 8px">
|
||||
<button onclick="addRow()">+ 行追加</button>
|
||||
<button onclick="submitJournal()">登録</button>
|
||||
@@ -199,6 +226,7 @@
|
||||
<th>摘要</th>
|
||||
<th>借方合計</th>
|
||||
<th>貸方合計</th>
|
||||
<th>税率</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -301,6 +329,29 @@
|
||||
|
||||
// 摘要履歴を読み込み
|
||||
loadDescriptionHistory();
|
||||
|
||||
// 各フィールドの変更時に合計を更新
|
||||
document
|
||||
.getElementById("entryDate")
|
||||
.addEventListener("change", updateTotals);
|
||||
document
|
||||
.getElementById("description")
|
||||
.addEventListener("input", updateTotals);
|
||||
document
|
||||
.getElementById("taxPaidSelect")
|
||||
.addEventListener("change", updateTotals);
|
||||
document
|
||||
.getElementById("taxReceivedSelect")
|
||||
.addEventListener("change", updateTotals);
|
||||
document
|
||||
.getElementById("roundingMode")
|
||||
.addEventListener("change", () => {
|
||||
// 端数処理変更時は全ての税行を再計算
|
||||
const rows = document.querySelectorAll(
|
||||
"#linesTable tbody tr:not(.tax-row)"
|
||||
);
|
||||
rows.forEach((row) => handleTax(row));
|
||||
});
|
||||
}
|
||||
|
||||
init();
|
||||
@@ -451,8 +502,16 @@
|
||||
// 普通行:绑定事件
|
||||
if (!isTaxRow) {
|
||||
const recalc = () => handleTax(tr);
|
||||
tr.querySelector(".debit").addEventListener("input", recalc);
|
||||
tr.querySelector(".credit").addEventListener("input", recalc);
|
||||
const debitInput = tr.querySelector(".debit");
|
||||
const creditInput = tr.querySelector(".credit");
|
||||
|
||||
debitInput.addEventListener("input", recalc);
|
||||
creditInput.addEventListener("input", recalc);
|
||||
|
||||
// blur(フォーカス離脱)時に合計を更新
|
||||
debitInput.addEventListener("blur", updateTotals);
|
||||
creditInput.addEventListener("blur", updateTotals);
|
||||
|
||||
tr.querySelector(".taxType").addEventListener("change", recalc);
|
||||
tr.querySelector(".taxDirection").addEventListener("change", recalc);
|
||||
}
|
||||
@@ -473,6 +532,49 @@
|
||||
const row = btn.closest("tr");
|
||||
removeTaxRowsOf(row);
|
||||
row.remove();
|
||||
updateTotals(); // 削除後に合計を更新
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// 借方・貸方合計を計算して表示
|
||||
// -----------------------------
|
||||
function updateTotals() {
|
||||
let totalDebit = 0;
|
||||
let totalCredit = 0;
|
||||
|
||||
const rows = document.querySelectorAll("#linesTable tbody tr");
|
||||
rows.forEach((row) => {
|
||||
const debitValue =
|
||||
row.querySelector(".debit")?.value.replace(/,/g, "") || "0";
|
||||
const creditValue =
|
||||
row.querySelector(".credit")?.value.replace(/,/g, "") || "0";
|
||||
|
||||
totalDebit += Number(debitValue) || 0;
|
||||
totalCredit += Number(creditValue) || 0;
|
||||
});
|
||||
|
||||
// 表示を更新
|
||||
document.getElementById("totalDebit").textContent =
|
||||
totalDebit.toLocaleString();
|
||||
document.getElementById("totalCredit").textContent =
|
||||
totalCredit.toLocaleString();
|
||||
|
||||
// 貸借一致チェック
|
||||
const balanceStatus = document.getElementById("balanceStatus");
|
||||
if (totalDebit === totalCredit && totalDebit > 0) {
|
||||
balanceStatus.textContent = "✓ 貸借一致";
|
||||
balanceStatus.style.background = "#d4edda";
|
||||
balanceStatus.style.color = "#155724";
|
||||
} else if (totalDebit === 0 && totalCredit === 0) {
|
||||
balanceStatus.textContent = "";
|
||||
balanceStatus.style.background = "";
|
||||
} else {
|
||||
balanceStatus.textContent = `✗ 差額: ${Math.abs(
|
||||
totalDebit - totalCredit
|
||||
).toLocaleString()}`;
|
||||
balanceStatus.style.background = "#f8d7da";
|
||||
balanceStatus.style.color = "#721c24";
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
@@ -491,10 +593,16 @@
|
||||
row.querySelector(".credit").value.replace(/,/g, "") || 0
|
||||
);
|
||||
|
||||
if (taxType === "none" || taxDir === "none") return;
|
||||
if (taxType === "none" || taxDir === "none") {
|
||||
updateTotals(); // 税なしでも合計更新
|
||||
return;
|
||||
}
|
||||
|
||||
const totalAmount = debit || credit;
|
||||
if (!totalAmount) return;
|
||||
if (!totalAmount) {
|
||||
updateTotals();
|
||||
return;
|
||||
}
|
||||
|
||||
const rate = taxType === "8" ? 0.08 : 0.1;
|
||||
const roundingMode = document.getElementById("roundingMode").value;
|
||||
@@ -517,7 +625,10 @@
|
||||
|
||||
if (taxDir === "paid") {
|
||||
const taxAcc = document.getElementById("taxPaidSelect").value;
|
||||
if (!taxAcc) return alert("仮払消費税等 勘定を選択してください");
|
||||
if (!taxAcc) {
|
||||
updateTotals();
|
||||
return alert("仮払消費税等 勘定を選択してください");
|
||||
}
|
||||
addRow(
|
||||
true,
|
||||
{ accountId: taxAcc, amount: taxAmount, side: "debit" },
|
||||
@@ -526,13 +637,18 @@
|
||||
}
|
||||
if (taxDir === "received") {
|
||||
const taxAcc = document.getElementById("taxReceivedSelect").value;
|
||||
if (!taxAcc) return alert("仮受消費税等 勘定を選択してください");
|
||||
if (!taxAcc) {
|
||||
updateTotals();
|
||||
return alert("仮受消費税等 勘定を選択してください");
|
||||
}
|
||||
addRow(
|
||||
true,
|
||||
{ accountId: taxAcc, amount: taxAmount, side: "credit" },
|
||||
parentId
|
||||
);
|
||||
}
|
||||
|
||||
updateTotals(); // 税行追加後に合計更新
|
||||
}
|
||||
|
||||
// 税行は常に「直後の1行」を使う
|
||||
@@ -686,6 +802,12 @@
|
||||
rowSeq = 0;
|
||||
addRow();
|
||||
|
||||
// 借方合計・貸方合計を0にリセット
|
||||
document.getElementById("totalDebit").textContent = "0";
|
||||
document.getElementById("totalCredit").textContent = "0";
|
||||
document.getElementById("balanceStatus").textContent = "";
|
||||
document.getElementById("balanceStatus").style.background = "";
|
||||
|
||||
// 仕訳検索を自動実行して最新の登録状況を表示
|
||||
searchJournals();
|
||||
} catch (error) {
|
||||
@@ -911,9 +1033,12 @@
|
||||
includeHistory && e.version > 1 ? ` (v${e.version})` : "";
|
||||
tr.innerHTML = `
|
||||
<td>${e.entry_date}</td>
|
||||
<td>${e.description}${versionInfo}</td>
|
||||
<td style="text-align:left">${e.description}${versionInfo}</td>
|
||||
<td style="text-align:right">${e.debit_total.toLocaleString()}</td>
|
||||
<td style="text-align:right">${e.credit_total.toLocaleString()}</td>
|
||||
<td style="text-align:center">${
|
||||
e.tax_rates ? e.tax_rates + "%" : ""
|
||||
}</td>
|
||||
<td>
|
||||
<button onclick="viewJournal(${
|
||||
e.journal_entry_id
|
||||
@@ -1050,6 +1175,8 @@
|
||||
}
|
||||
|
||||
const srcData = await srcRes.json();
|
||||
// 逆仕訳IDを追加して保存(【修正後】仕訳のparent_entry_idとして使用)
|
||||
srcData.reversed_journal_entry_id = data.reversed_journal_entry_id;
|
||||
localStorage.setItem("editSource", JSON.stringify(srcData));
|
||||
|
||||
// 修正画面を開く
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
}
|
||||
|
||||
const srcData = await srcRes.json();
|
||||
// 逆仕訳IDを追加して保存(【修正後】仕訳のparent_entry_idとして使用)
|
||||
srcData.reversed_journal_entry_id = data.reversed_journal_entry_id;
|
||||
localStorage.setItem("editSource", JSON.stringify(srcData));
|
||||
|
||||
// 修正画面を開く
|
||||
|
||||
@@ -99,10 +99,10 @@
|
||||
|
||||
<div class="search-form">
|
||||
<label for="dateFrom">開始年月日:</label>
|
||||
<input type="date" id="dateFrom" />
|
||||
<input type="date" id="dateFrom" min="1900-01-01" max="9999-12-31" />
|
||||
|
||||
<label for="dateTo">終了年月日:</label>
|
||||
<input type="date" id="dateTo" />
|
||||
<input type="date" id="dateTo" min="1900-01-01" max="9999-12-31" />
|
||||
|
||||
<button id="btnSearch">検索</button>
|
||||
<button id="btnFullYear" class="secondary">全年度表示</button>
|
||||
|
||||
Reference in New Issue
Block a user