From ebc87f96f9a9cc7ae77a3039a10108b90f7b0b61 Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 22 May 2026 23:05:38 +0900 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/css/mobile.css | 10 +- frontend/journal-entry.html | 291 +++--- frontend/nenkin-portal.html | 1369 ++++++++++++++++------------- frontend/payroll-calculation.html | 18 +- frontend/payroll.html | 13 +- frontend/withholding-slip.html | 1296 +++++++++++++++++---------- 6 files changed, 1783 insertions(+), 1214 deletions(-) diff --git a/frontend/css/mobile.css b/frontend/css/mobile.css index f799f58..3c2deb7 100644 --- a/frontend/css/mobile.css +++ b/frontend/css/mobile.css @@ -10,7 +10,6 @@ html { } @media screen and (max-width: 767px) { - /* ── body 余白を縮小 ── */ body { padding: 12px !important; @@ -18,8 +17,12 @@ html { } /* ── h1・h2 フォントサイズ ── */ - h1 { font-size: 1.35rem !important; } - h2 { font-size: 1.1rem !important; } + h1 { + font-size: 1.35rem !important; + } + h2 { + font-size: 1.1rem !important; + } /* ================================================================ テーブル: 横スクロール @@ -320,5 +323,4 @@ html { width: 100% !important; box-sizing: border-box !important; } - } diff --git a/frontend/journal-entry.html b/frontend/journal-entry.html index 70f4718..7b3921a 100644 --- a/frontend/journal-entry.html +++ b/frontend/journal-entry.html @@ -863,7 +863,19 @@
- +
@@ -2830,7 +2842,8 @@ // 複数行フォームへのコピー function copyJournalToDetailForm(data) { document.getElementById("detailEntryDate").value = data.entry_date; - document.getElementById("detailDescription").value = data.description || ""; + document.getElementById("detailDescription").value = + data.description || ""; // 既存行をクリア document.getElementById("detailLinesTbody").innerHTML = ""; @@ -2846,10 +2859,14 @@ accountInput.dataset.accountId = acc.account_id; } if (Number(line.debit) > 0) { - tr.querySelector(".detail-debit").value = Number(line.debit).toLocaleString(); + tr.querySelector(".detail-debit").value = Number( + line.debit, + ).toLocaleString(); } if (Number(line.credit) > 0) { - tr.querySelector(".detail-credit").value = Number(line.credit).toLocaleString(); + tr.querySelector(".detail-credit").value = Number( + line.credit, + ).toLocaleString(); } if (line.line_description) { tr.querySelector(".detail-line-memo").value = line.line_description; @@ -2879,58 +2896,121 @@ // 新UIでは簡易的にフォームに反映(最初の借方行の科目 + 最初の貸方行を取引手段に設定) if (data.lines && data.lines.length > 0) { - // 借方と貸方を分類 - const debitLines = data.lines.filter((l) => Number(l.debit) > 0); - const creditLines = data.lines.filter((l) => Number(l.credit) > 0); + // 借方と貸方を分類 + const debitLines = data.lines.filter((l) => Number(l.debit) > 0); + const creditLines = data.lines.filter((l) => Number(l.credit) > 0); - // 仮払/仮受消費税行を除外して主要な科目を特定 - const mainDebit = debitLines.find((l) => { - const acc = accounts.find((a) => a.account_id === l.account_id); - return ( - acc && - !acc.account_name.includes("仮払消費税") && - !acc.account_name.includes("仮受消費税") + // 仮払/仮受消費税行を除外して主要な科目を特定 + const mainDebit = debitLines.find((l) => { + const acc = accounts.find((a) => a.account_id === l.account_id); + return ( + acc && + !acc.account_name.includes("仮払消費税") && + !acc.account_name.includes("仮受消費税") + ); + }); + const mainCredit = creditLines.find((l) => { + const acc = accounts.find((a) => a.account_id === l.account_id); + return ( + acc && + !acc.account_name.includes("仮払消費税") && + !acc.account_name.includes("仮受消費税") + ); + }); + + // 税額行を検出 + const taxDebitLine = debitLines.find((l) => { + const acc = accounts.find((a) => a.account_id === l.account_id); + return acc && acc.account_name.includes("仮払消費税"); + }); + const taxCreditLine = creditLines.find((l) => { + const acc = accounts.find((a) => a.account_id === l.account_id); + return acc && acc.account_name.includes("仮受消費税"); + }); + + if (mainDebit && mainCredit) { + // 支出パターン: 借方=科目, 貸方=取引手段 + if (taxDebitLine) { + // 支出(仮払消費税あり) + document.querySelector( + 'input[name="entryType"][value="expense"]', + ).checked = true; + const kamokuAcc = accounts.find( + (a) => a.account_id === mainDebit.account_id, ); - }); - const mainCredit = creditLines.find((l) => { - const acc = accounts.find((a) => a.account_id === l.account_id); - return ( - acc && - !acc.account_name.includes("仮払消費税") && - !acc.account_name.includes("仮受消費税") + const methodAcc = accounts.find( + (a) => a.account_id === mainCredit.account_id, ); - }); - - // 税額行を検出 - const taxDebitLine = debitLines.find((l) => { - const acc = accounts.find((a) => a.account_id === l.account_id); - return acc && acc.account_name.includes("仮払消費税"); - }); - const taxCreditLine = creditLines.find((l) => { - const acc = accounts.find((a) => a.account_id === l.account_id); - return acc && acc.account_name.includes("仮受消費税"); - }); - - if (mainDebit && mainCredit) { - // 支出パターン: 借方=科目, 貸方=取引手段 - if (taxDebitLine) { - // 支出(仮払消費税あり) + if (kamokuAcc) { + document.getElementById("entryAccountInput").value = + `${kamokuAcc.account_code} ${kamokuAcc.account_name}`; + document.getElementById("entryAccountInput").dataset.accountId = + kamokuAcc.account_id; + } + if (methodAcc) { + document.getElementById("entryMethodInput").value = + `${methodAcc.account_code} ${methodAcc.account_name}`; + document.getElementById("entryMethodInput").dataset.accountId = + methodAcc.account_id; + } + const totalAmount = Number(mainCredit.credit); + document.getElementById("entryAmount").value = + totalAmount.toLocaleString(); + document.getElementById("entryTaxAmount").value = Number( + taxDebitLine.debit, + ).toLocaleString(); + } else if (taxCreditLine) { + // 収入(仮受消費税あり) + document.querySelector( + 'input[name="entryType"][value="income"]', + ).checked = true; + const kamokuAcc = accounts.find( + (a) => a.account_id === mainCredit.account_id, + ); + const methodAcc = accounts.find( + (a) => a.account_id === mainDebit.account_id, + ); + if (kamokuAcc) { + document.getElementById("entryAccountInput").value = + `${kamokuAcc.account_code} ${kamokuAcc.account_name}`; + document.getElementById("entryAccountInput").dataset.accountId = + kamokuAcc.account_id; + } + if (methodAcc) { + document.getElementById("entryMethodInput").value = + `${methodAcc.account_code} ${methodAcc.account_name}`; + document.getElementById("entryMethodInput").dataset.accountId = + methodAcc.account_id; + } + const totalAmount = Number(mainDebit.debit); + document.getElementById("entryAmount").value = + totalAmount.toLocaleString(); + document.getElementById("entryTaxAmount").value = Number( + taxCreditLine.credit, + ).toLocaleString(); + } else { + // 消費税なし - 借方科目が費用/資産 → 支出、それ以外は収入 + const kamokuAccD = accounts.find( + (a) => a.account_id === mainDebit.account_id, + ); + const isExpense = + kamokuAccD && + (kamokuAccD.account_code.startsWith("8") || + kamokuAccD.account_code.startsWith("1") || + kamokuAccD.account_code.startsWith("2") || + kamokuAccD.account_code.startsWith("3") || + kamokuAccD.account_code.startsWith("4")); + if (isExpense) { document.querySelector( 'input[name="entryType"][value="expense"]', ).checked = true; - const kamokuAcc = accounts.find( - (a) => a.account_id === mainDebit.account_id, - ); + document.getElementById("entryAccountInput").value = + `${kamokuAccD.account_code} ${kamokuAccD.account_name}`; + document.getElementById("entryAccountInput").dataset.accountId = + kamokuAccD.account_id; const methodAcc = accounts.find( (a) => a.account_id === mainCredit.account_id, ); - if (kamokuAcc) { - document.getElementById("entryAccountInput").value = - `${kamokuAcc.account_code} ${kamokuAcc.account_name}`; - document.getElementById( - "entryAccountInput", - ).dataset.accountId = kamokuAcc.account_id; - } if (methodAcc) { document.getElementById("entryMethodInput").value = `${methodAcc.account_code} ${methodAcc.account_name}`; @@ -2938,116 +3018,47 @@ "entryMethodInput", ).dataset.accountId = methodAcc.account_id; } - const totalAmount = Number(mainCredit.credit); - document.getElementById("entryAmount").value = - totalAmount.toLocaleString(); - document.getElementById("entryTaxAmount").value = Number( - taxDebitLine.debit, + document.getElementById("entryAmount").value = Number( + mainDebit.debit, ).toLocaleString(); - } else if (taxCreditLine) { - // 収入(仮受消費税あり) + } else { document.querySelector( 'input[name="entryType"][value="income"]', ).checked = true; - const kamokuAcc = accounts.find( + const kamokuAccC = accounts.find( (a) => a.account_id === mainCredit.account_id, ); - const methodAcc = accounts.find( - (a) => a.account_id === mainDebit.account_id, - ); - if (kamokuAcc) { + if (kamokuAccC) { document.getElementById("entryAccountInput").value = - `${kamokuAcc.account_code} ${kamokuAcc.account_name}`; + `${kamokuAccC.account_code} ${kamokuAccC.account_name}`; document.getElementById( "entryAccountInput", - ).dataset.accountId = kamokuAcc.account_id; + ).dataset.accountId = kamokuAccC.account_id; } - if (methodAcc) { - document.getElementById("entryMethodInput").value = - `${methodAcc.account_code} ${methodAcc.account_name}`; - document.getElementById( - "entryMethodInput", - ).dataset.accountId = methodAcc.account_id; - } - const totalAmount = Number(mainDebit.debit); - document.getElementById("entryAmount").value = - totalAmount.toLocaleString(); - document.getElementById("entryTaxAmount").value = Number( - taxCreditLine.credit, + document.getElementById("entryMethodInput").value = + `${kamokuAccD.account_code} ${kamokuAccD.account_name}`; + document.getElementById("entryMethodInput").dataset.accountId = + kamokuAccD.account_id; + document.getElementById("entryAmount").value = Number( + mainDebit.debit, ).toLocaleString(); - } else { - // 消費税なし - 借方科目が費用/資産 → 支出、それ以外は収入 - const kamokuAccD = accounts.find( - (a) => a.account_id === mainDebit.account_id, - ); - const isExpense = - kamokuAccD && - (kamokuAccD.account_code.startsWith("8") || - kamokuAccD.account_code.startsWith("1") || - kamokuAccD.account_code.startsWith("2") || - kamokuAccD.account_code.startsWith("3") || - kamokuAccD.account_code.startsWith("4")); - if (isExpense) { - document.querySelector( - 'input[name="entryType"][value="expense"]', - ).checked = true; - document.getElementById("entryAccountInput").value = - `${kamokuAccD.account_code} ${kamokuAccD.account_name}`; - document.getElementById( - "entryAccountInput", - ).dataset.accountId = kamokuAccD.account_id; - const methodAcc = accounts.find( - (a) => a.account_id === mainCredit.account_id, - ); - if (methodAcc) { - document.getElementById("entryMethodInput").value = - `${methodAcc.account_code} ${methodAcc.account_name}`; - document.getElementById( - "entryMethodInput", - ).dataset.accountId = methodAcc.account_id; - } - document.getElementById("entryAmount").value = Number( - mainDebit.debit, - ).toLocaleString(); - } else { - document.querySelector( - 'input[name="entryType"][value="income"]', - ).checked = true; - const kamokuAccC = accounts.find( - (a) => a.account_id === mainCredit.account_id, - ); - if (kamokuAccC) { - document.getElementById("entryAccountInput").value = - `${kamokuAccC.account_code} ${kamokuAccC.account_name}`; - document.getElementById( - "entryAccountInput", - ).dataset.accountId = kamokuAccC.account_id; - } - document.getElementById("entryMethodInput").value = - `${kamokuAccD.account_code} ${kamokuAccD.account_name}`; - document.getElementById( - "entryMethodInput", - ).dataset.accountId = kamokuAccD.account_id; - document.getElementById("entryAmount").value = Number( - mainDebit.debit, - ).toLocaleString(); - } - document.getElementById("entryTaxRate").value = "0"; - document.getElementById("entryTaxAmount").value = ""; } + document.getElementById("entryTaxRate").value = "0"; + document.getElementById("entryTaxAmount").value = ""; } } + } - // ページ上部の仕訳入力フォームにスクロール - window.scrollTo({ top: 0, behavior: "smooth" }); + // ページ上部の仕訳入力フォームにスクロール + window.scrollTo({ top: 0, behavior: "smooth" }); - const dateInput = document.getElementById("entryDate"); - dateInput.focus(); + const dateInput = document.getElementById("entryDate"); + dateInput.focus(); - showAlert( - `仕訳を複製しました。\n\n※ このコピーは新規仕訳として独立した記録になります。\n※ 日付と摘要を必要に応じて修正してから登録してください。`, - "success", - ); + showAlert( + `仕訳を複製しました。\n\n※ このコピーは新規仕訳として独立した記録になります。\n※ 日付と摘要を必要に応じて修正してから登録してください。`, + "success", + ); } // -------------------------------------------------- diff --git a/frontend/nenkin-portal.html b/frontend/nenkin-portal.html index 4d0b1bd..b16aa9e 100644 --- a/frontend/nenkin-portal.html +++ b/frontend/nenkin-portal.html @@ -1,521 +1,677 @@ - - - - 社会保険電子文書ポータル - - - - - - + /* 賞与明細テーブル */ + .shoyo-table-wrap { + overflow-x: auto; + } + .shoyo-table { + width: 100%; + border-collapse: collapse; + font-size: 13px; + } + .shoyo-table th { + background: #f8f9fa; + padding: 8px 10px; + text-align: center; + border: 1px solid #dee2e6; + white-space: nowrap; + font-size: 12px; + } + .shoyo-table td { + padding: 7px 10px; + border: 1px solid #f0f0f0; + text-align: right; + } + .shoyo-table td.name { + text-align: left; + font-weight: 600; + } + .shoyo-table tfoot td { + background: #e8f4ff; + font-weight: 700; + border-top: 2px solid #007bff; + } + .shoyo-table .empty-cell { + color: #ccc; + text-align: center; + } + + + + - + +
+

📥 社会保険 ZIP ファイルをここにドロップ

+

またはボタンから選択してください(複数ファイル対応)

+ +
+ +
+
- -
-

📥 社会保険 ZIP ファイルをここにドロップ

-

またはボタンから選択してください(複数ファイル対応)

- -
- -
-
+ +
+
+ + + + +
+ + +
- -
-
- - - - -
- - -
+ +
+ + + + + + + + + + + + + + + + + +
種別対象年月事業所名整理記号・番号年金事務所発行日登録日時
データを読み込んでいます...
+
- -
- - - - - - - - - - - - - - - -
種別対象年月事業所名整理記号・番号年金事務所発行日登録日時
データを読み込んでいます...
-
+ +
+
+

詳細

+ +
+
+
- -
-
-

詳細

- -
-
-
+ - + function showDetailError(msg) { + const panel = document.getElementById("detail-panel"); + document.getElementById("detail-body").innerHTML = + `

エラー: ${escHtml(msg)}

`; + panel.classList.add("visible"); + } + + diff --git a/frontend/payroll-calculation.html b/frontend/payroll-calculation.html index 36d6a85..6f029ad 100644 --- a/frontend/payroll-calculation.html +++ b/frontend/payroll-calculation.html @@ -1783,14 +1783,18 @@ // 源泉税控除対象人数を計算(給与と同じロジック) const bDependentCount = employee.dependents ? employee.dependents.filter((d) => { - if (d.valid_to && new Date(d.valid_to) < new Date()) return false; + if (d.valid_to && new Date(d.valid_to) < new Date()) + return false; if (!d.birth_date) return false; const birthDate = new Date(d.birth_date); const targetYear = bonus.bonus_year; const yearEnd = new Date(targetYear, 11, 31); let age = yearEnd.getFullYear() - birthDate.getFullYear(); const monthDiff = yearEnd.getMonth() - birthDate.getMonth(); - if (monthDiff < 0 || (monthDiff === 0 && yearEnd.getDate() < birthDate.getDate())) { + if ( + monthDiff < 0 || + (monthDiff === 0 && yearEnd.getDate() < birthDate.getDate()) + ) { age--; } return age >= 16; @@ -1969,10 +1973,10 @@
@@ -2451,7 +2455,7 @@ const bonusPaymentDate = bonus.payment_date ? (() => { const d = new Date(bonus.payment_date); - return `${d.getFullYear()}年${String(d.getMonth()+1).padStart(2,'0')}月${String(d.getDate()).padStart(2,'0')}日`; + return `${d.getFullYear()}年${String(d.getMonth() + 1).padStart(2, "0")}月${String(d.getDate()).padStart(2, "0")}日`; })() : `${bonus.bonus_year}年${String(bonus.bonus_month).padStart(2, "0")}月${getLastDayOfMonth(bonus.bonus_year, bonus.bonus_month)}日`; if (currentKey && currentKey !== currentKey_new) { diff --git a/frontend/payroll.html b/frontend/payroll.html index 386e227..e32f8ef 100644 --- a/frontend/payroll.html +++ b/frontend/payroll.html @@ -118,16 +118,17 @@ >
📄

源泉徴収票

-

給与所得の源泉徴収票を発行します(本人用・区役所用・税務署用 各1部)

+

+ 給与所得の源泉徴収票を発行します(本人用・区役所用・税務署用 各1部) +

- diff --git a/frontend/withholding-slip.html b/frontend/withholding-slip.html index 443f988..dd0c8e7 100644 --- a/frontend/withholding-slip.html +++ b/frontend/withholding-slip.html @@ -2,7 +2,10 @@ - + @@ -12,34 +15,122 @@
-

給与所得の源泉徴収票

-

① 発行条件の設定

+

① 発行条件の設定

- +
- +
-
- 読み込み中... +
+ 読み込み中...
-
-

② 支払者情報(源泉徴収票下部に印刷)

+
+

② 支払者情報(源泉徴収票下部に印刷)

- +
- +
- +
- +
-
- - +
+ +
@@ -143,16 +369,16 @@