修正
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -863,7 +863,19 @@
|
||||
<div class="search-buttons">
|
||||
<button onclick="searchJournals()">🔍 検索</button>
|
||||
<button onclick="printSearchResults()">🖨️ 印刷</button>
|
||||
<button onclick="clearSearchConditions()" style="background: #6c757d; color: white; border: none; padding: 6px 14px; border-radius: 4px; cursor: pointer;">🔄 条件クリア</button>
|
||||
<button
|
||||
onclick="clearSearchConditions()"
|
||||
style="
|
||||
background: #6c757d;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 6px 14px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
"
|
||||
>
|
||||
🔄 条件クリア
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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;
|
||||
@@ -2927,16 +2944,14 @@
|
||||
if (kamokuAcc) {
|
||||
document.getElementById("entryAccountInput").value =
|
||||
`${kamokuAcc.account_code} ${kamokuAcc.account_name}`;
|
||||
document.getElementById(
|
||||
"entryAccountInput",
|
||||
).dataset.accountId = kamokuAcc.account_id;
|
||||
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;
|
||||
document.getElementById("entryMethodInput").dataset.accountId =
|
||||
methodAcc.account_id;
|
||||
}
|
||||
const totalAmount = Number(mainCredit.credit);
|
||||
document.getElementById("entryAmount").value =
|
||||
@@ -2958,16 +2973,14 @@
|
||||
if (kamokuAcc) {
|
||||
document.getElementById("entryAccountInput").value =
|
||||
`${kamokuAcc.account_code} ${kamokuAcc.account_name}`;
|
||||
document.getElementById(
|
||||
"entryAccountInput",
|
||||
).dataset.accountId = kamokuAcc.account_id;
|
||||
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;
|
||||
document.getElementById("entryMethodInput").dataset.accountId =
|
||||
methodAcc.account_id;
|
||||
}
|
||||
const totalAmount = Number(mainDebit.debit);
|
||||
document.getElementById("entryAmount").value =
|
||||
@@ -2993,9 +3006,8 @@
|
||||
).checked = true;
|
||||
document.getElementById("entryAccountInput").value =
|
||||
`${kamokuAccD.account_code} ${kamokuAccD.account_name}`;
|
||||
document.getElementById(
|
||||
"entryAccountInput",
|
||||
).dataset.accountId = kamokuAccD.account_id;
|
||||
document.getElementById("entryAccountInput").dataset.accountId =
|
||||
kamokuAccD.account_id;
|
||||
const methodAcc = accounts.find(
|
||||
(a) => a.account_id === mainCredit.account_id,
|
||||
);
|
||||
@@ -3025,9 +3037,8 @@
|
||||
}
|
||||
document.getElementById("entryMethodInput").value =
|
||||
`${kamokuAccD.account_code} ${kamokuAccD.account_name}`;
|
||||
document.getElementById(
|
||||
"entryMethodInput",
|
||||
).dataset.accountId = kamokuAccD.account_id;
|
||||
document.getElementById("entryMethodInput").dataset.accountId =
|
||||
kamokuAccD.account_id;
|
||||
document.getElementById("entryAmount").value = Number(
|
||||
mainDebit.debit,
|
||||
).toLocaleString();
|
||||
|
||||
@@ -9,7 +9,13 @@
|
||||
<link rel="stylesheet" href="/css/mobile.css" />
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, "Yu Gothic UI", "Hiragino Kaku Gothic ProN", "メイリオ", sans-serif;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
"Yu Gothic UI",
|
||||
"Hiragino Kaku Gothic ProN",
|
||||
"メイリオ",
|
||||
sans-serif;
|
||||
padding: 24px;
|
||||
background: #f5f7fa;
|
||||
}
|
||||
@@ -20,7 +26,10 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.page-header h1 { margin: 0; font-size: 20px; }
|
||||
.page-header h1 {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
.back-link {
|
||||
padding: 8px 16px;
|
||||
background: #007bff;
|
||||
@@ -31,7 +40,9 @@
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.back-link:hover { background: #0056b3; }
|
||||
.back-link:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
|
||||
/* ── アップロードゾーン ── */
|
||||
.upload-zone {
|
||||
@@ -43,15 +54,27 @@
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s, background 0.2s;
|
||||
transition:
|
||||
border-color 0.2s,
|
||||
background 0.2s;
|
||||
}
|
||||
.upload-zone.dragover {
|
||||
border-color: #007bff;
|
||||
background: #e8f4ff;
|
||||
}
|
||||
.upload-zone h3 { margin: 0 0 8px; font-size: 16px; color: #495057; }
|
||||
.upload-zone p { margin: 0; color: #6c757d; font-size: 13px; }
|
||||
.upload-zone input[type=file] { display: none; }
|
||||
.upload-zone h3 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 16px;
|
||||
color: #495057;
|
||||
}
|
||||
.upload-zone p {
|
||||
margin: 0;
|
||||
color: #6c757d;
|
||||
font-size: 13px;
|
||||
}
|
||||
.upload-zone input[type="file"] {
|
||||
display: none;
|
||||
}
|
||||
.upload-btn {
|
||||
display: inline-block;
|
||||
margin-top: 12px;
|
||||
@@ -63,15 +86,23 @@
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
.upload-btn:hover { background: #0056b3; }
|
||||
.upload-btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
#upload-status {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto 12px;
|
||||
font-size: 14px;
|
||||
min-height: 24px;
|
||||
}
|
||||
.status-ok { color: #28a745; font-weight: bold; }
|
||||
.status-err { color: #dc3545; font-weight: bold; }
|
||||
.status-ok {
|
||||
color: #28a745;
|
||||
font-weight: bold;
|
||||
}
|
||||
.status-err {
|
||||
color: #dc3545;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* ── フィルターバー ── */
|
||||
.filter-bar {
|
||||
@@ -82,7 +113,11 @@
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.type-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
|
||||
.type-tabs {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.type-tab {
|
||||
padding: 5px 14px;
|
||||
border-radius: 20px;
|
||||
@@ -93,8 +128,15 @@
|
||||
color: #495057;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.type-tab:hover { border-color: #007bff; color: #007bff; }
|
||||
.type-tab.active { background: #007bff; color: #fff; border-color: #007bff; }
|
||||
.type-tab:hover {
|
||||
border-color: #007bff;
|
||||
color: #007bff;
|
||||
}
|
||||
.type-tab.active {
|
||||
background: #007bff;
|
||||
color: #fff;
|
||||
border-color: #007bff;
|
||||
}
|
||||
.filter-select {
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #ced4da;
|
||||
@@ -130,9 +172,15 @@
|
||||
cursor: pointer;
|
||||
transition: background 0.1s;
|
||||
}
|
||||
.doc-table tbody tr:hover { background: #f0f7ff; }
|
||||
.doc-table tbody tr.selected { background: #dbeafe; }
|
||||
.doc-table tbody td { padding: 10px 12px; }
|
||||
.doc-table tbody tr:hover {
|
||||
background: #f0f7ff;
|
||||
}
|
||||
.doc-table tbody tr.selected {
|
||||
background: #dbeafe;
|
||||
}
|
||||
.doc-table tbody td {
|
||||
padding: 10px 12px;
|
||||
}
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
@@ -140,11 +188,27 @@
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.badge-shakai { background: #d1ecf1; color: #0c5460; }
|
||||
.badge-nounyu { background: #d4edda; color: #155724; }
|
||||
.badge-shoyo { background: #fff3cd; color: #856404; }
|
||||
.badge-unknown { background: #e2e3e5; color: #383d41; }
|
||||
.no-data { text-align: center; color: #aaa; padding: 40px; }
|
||||
.badge-shakai {
|
||||
background: #d1ecf1;
|
||||
color: #0c5460;
|
||||
}
|
||||
.badge-nounyu {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
.badge-shoyo {
|
||||
background: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
.badge-unknown {
|
||||
background: #e2e3e5;
|
||||
color: #383d41;
|
||||
}
|
||||
.no-data {
|
||||
text-align: center;
|
||||
color: #aaa;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
/* ── 詳細パネル ── */
|
||||
#detail-panel {
|
||||
@@ -156,14 +220,19 @@
|
||||
padding: 24px;
|
||||
display: none;
|
||||
}
|
||||
#detail-panel.visible { display: block; }
|
||||
#detail-panel.visible {
|
||||
display: block;
|
||||
}
|
||||
.detail-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.detail-header h2 { margin: 0; font-size: 18px; }
|
||||
.detail-header h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
.detail-close {
|
||||
background: none;
|
||||
border: 1px solid #ced4da;
|
||||
@@ -173,7 +242,9 @@
|
||||
font-size: 13px;
|
||||
color: #6c757d;
|
||||
}
|
||||
.detail-close:hover { background: #f8f9fa; }
|
||||
.detail-close:hover {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
/* 事業所情報カード */
|
||||
.info-cards {
|
||||
@@ -189,12 +260,27 @@
|
||||
border-radius: 6px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
.info-card .label { font-size: 11px; color: #6c757d; margin-bottom: 4px; }
|
||||
.info-card .value { font-size: 14px; font-weight: 600; color: #212529; }
|
||||
.info-card .label {
|
||||
font-size: 11px;
|
||||
color: #6c757d;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.info-card .value {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
/* 金額テーブル */
|
||||
.amount-section { margin-bottom: 20px; }
|
||||
.amount-section h3 { font-size: 15px; margin: 0 0 12px; border-left: 3px solid #007bff; padding-left: 8px; }
|
||||
.amount-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.amount-section h3 {
|
||||
font-size: 15px;
|
||||
margin: 0 0 12px;
|
||||
border-left: 3px solid #007bff;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.amount-grid {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
@@ -213,7 +299,10 @@
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
}
|
||||
.amount-row .amt { font-family: monospace; font-size: 15px; }
|
||||
.amount-row .amt {
|
||||
font-family: monospace;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* 告知額 vs 領収済額 サイドバイサイド */
|
||||
.nounyu-compare {
|
||||
@@ -222,17 +311,32 @@
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
@media (max-width: 640px) { .nounyu-compare { grid-template-columns: 1fr; } }
|
||||
@media (max-width: 640px) {
|
||||
.nounyu-compare {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.nounyu-box {
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
}
|
||||
.nounyu-box.kokuchi { background: #fff3cd; border: 1px solid #ffc107; }
|
||||
.nounyu-box.ryoshu { background: #d4edda; border: 1px solid #28a745; }
|
||||
.nounyu-box h4 { margin: 0 0 12px; font-size: 14px; }
|
||||
.nounyu-box.kokuchi {
|
||||
background: #fff3cd;
|
||||
border: 1px solid #ffc107;
|
||||
}
|
||||
.nounyu-box.ryoshu {
|
||||
background: #d4edda;
|
||||
border: 1px solid #28a745;
|
||||
}
|
||||
.nounyu-box h4 {
|
||||
margin: 0 0 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 賞与明細テーブル */
|
||||
.shoyo-table-wrap { overflow-x: auto; }
|
||||
.shoyo-table-wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.shoyo-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
@@ -251,17 +355,22 @@
|
||||
border: 1px solid #f0f0f0;
|
||||
text-align: right;
|
||||
}
|
||||
.shoyo-table td.name { text-align: left; font-weight: 600; }
|
||||
.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; }
|
||||
.shoyo-table .empty-cell {
|
||||
color: #ccc;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>社会保険電子文書ポータル</h1>
|
||||
<a class="back-link" href="payroll.html">← 給与管理メニューに戻る</a>
|
||||
@@ -272,8 +381,11 @@
|
||||
<h3>📥 社会保険 ZIP ファイルをここにドロップ</h3>
|
||||
<p>またはボタンから選択してください(複数ファイル対応)</p>
|
||||
<input type="file" id="zip-input" accept=".zip" multiple />
|
||||
<br>
|
||||
<button class="upload-btn" onclick="document.getElementById('zip-input').click()">
|
||||
<br />
|
||||
<button
|
||||
class="upload-btn"
|
||||
onclick="document.getElementById('zip-input').click()"
|
||||
>
|
||||
ファイルを選択
|
||||
</button>
|
||||
</div>
|
||||
@@ -292,12 +404,18 @@
|
||||
</select>
|
||||
<select class="filter-select" id="month-select">
|
||||
<option value="">月(すべて)</option>
|
||||
<option value="1">1月</option><option value="2">2月</option>
|
||||
<option value="3">3月</option><option value="4">4月</option>
|
||||
<option value="5">5月</option><option value="6">6月</option>
|
||||
<option value="7">7月</option><option value="8">8月</option>
|
||||
<option value="9">9月</option><option value="10">10月</option>
|
||||
<option value="11">11月</option><option value="12">12月</option>
|
||||
<option value="1">1月</option>
|
||||
<option value="2">2月</option>
|
||||
<option value="3">3月</option>
|
||||
<option value="4">4月</option>
|
||||
<option value="5">5月</option>
|
||||
<option value="6">6月</option>
|
||||
<option value="7">7月</option>
|
||||
<option value="8">8月</option>
|
||||
<option value="9">9月</option>
|
||||
<option value="10">10月</option>
|
||||
<option value="11">11月</option>
|
||||
<option value="12">12月</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -316,7 +434,9 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="doc-list-body">
|
||||
<tr><td colspan="7" class="no-data">データを読み込んでいます...</td></tr>
|
||||
<tr>
|
||||
<td colspan="7" class="no-data">データを読み込んでいます...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -338,27 +458,33 @@ let selectedDocId = null;
|
||||
// ──────────────────────────────────
|
||||
// ページ初期化
|
||||
// ──────────────────────────────────
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
checkAuth();
|
||||
loadDocuments();
|
||||
loadFilterOptions();
|
||||
initUploadZone();
|
||||
|
||||
document.getElementById('type-tabs').addEventListener('click', e => {
|
||||
const tab = e.target.closest('.type-tab');
|
||||
document.getElementById("type-tabs").addEventListener("click", (e) => {
|
||||
const tab = e.target.closest(".type-tab");
|
||||
if (!tab) return;
|
||||
document.querySelectorAll('.type-tab').forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
document
|
||||
.querySelectorAll(".type-tab")
|
||||
.forEach((t) => t.classList.remove("active"));
|
||||
tab.classList.add("active");
|
||||
currentFilter.type = tab.dataset.type;
|
||||
loadDocuments();
|
||||
});
|
||||
|
||||
document.getElementById('year-select').addEventListener('change', e => {
|
||||
document
|
||||
.getElementById("year-select")
|
||||
.addEventListener("change", (e) => {
|
||||
currentFilter.year = e.target.value;
|
||||
loadDocuments();
|
||||
});
|
||||
|
||||
document.getElementById('month-select').addEventListener('change', e => {
|
||||
document
|
||||
.getElementById("month-select")
|
||||
.addEventListener("change", (e) => {
|
||||
currentFilter.month = e.target.value;
|
||||
loadDocuments();
|
||||
});
|
||||
@@ -369,49 +495,62 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
// ──────────────────────────────────
|
||||
async function loadDocuments() {
|
||||
const params = new URLSearchParams();
|
||||
if (currentFilter.type) params.set('doc_type', currentFilter.type);
|
||||
if (currentFilter.year) params.set('year', currentFilter.year);
|
||||
if (currentFilter.month) params.set('month', currentFilter.month);
|
||||
if (currentFilter.type) params.set("doc_type", currentFilter.type);
|
||||
if (currentFilter.year) params.set("year", currentFilter.year);
|
||||
if (currentFilter.month) params.set("month", currentFilter.month);
|
||||
|
||||
const url = `${API}/nenkin/documents${params.toString() ? '?' + params : ''}`;
|
||||
const url = `${API}/nenkin/documents${params.toString() ? "?" + params : ""}`;
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
const docs = await res.json();
|
||||
renderDocList(docs);
|
||||
} catch (e) {
|
||||
document.getElementById('doc-list-body').innerHTML =
|
||||
document.getElementById("doc-list-body").innerHTML =
|
||||
`<tr><td colspan="7" class="no-data" style="color:#dc3545">読み込みエラー: ${e.message}</td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
function renderDocList(docs) {
|
||||
const tbody = document.getElementById('doc-list-body');
|
||||
const tbody = document.getElementById("doc-list-body");
|
||||
if (!docs.length) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="no-data">文書が登録されていません</td></tr>';
|
||||
tbody.innerHTML =
|
||||
'<tr><td colspan="7" class="no-data">文書が登録されていません</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = docs.map(d => {
|
||||
const period = d.purpose_year && d.purpose_month
|
||||
tbody.innerHTML = docs
|
||||
.map((d) => {
|
||||
const period =
|
||||
d.purpose_year && d.purpose_month
|
||||
? `${d.purpose_year}年${d.purpose_month}月`
|
||||
: '−';
|
||||
const issueDate = d.issue_date ? d.issue_date.replace(/-/g, '/') : '−';
|
||||
const uploadedAt = d.uploaded_at ? d.uploaded_at.slice(0, 16).replace('T', ' ') : '−';
|
||||
const selected = d.id === selectedDocId ? 'selected' : '';
|
||||
: "−";
|
||||
const issueDate = d.issue_date
|
||||
? d.issue_date.replace(/-/g, "/")
|
||||
: "−";
|
||||
const uploadedAt = d.uploaded_at
|
||||
? d.uploaded_at.slice(0, 16).replace("T", " ")
|
||||
: "−";
|
||||
const selected = d.id === selectedDocId ? "selected" : "";
|
||||
return `<tr class="${selected}" onclick="loadDetail(${d.id})" data-id="${d.id}">
|
||||
<td>${badgeHtml(d.document_type, d.document_type_name)}</td>
|
||||
<td>${period}</td>
|
||||
<td>${escHtml(d.office_name || '−')}</td>
|
||||
<td><small>${escHtml(d.office_kigo || '')} ${escHtml(d.office_number || '')}</small></td>
|
||||
<td>${escHtml(d.nenkin_jimusho || '−')}</td>
|
||||
<td>${escHtml(d.office_name || "−")}</td>
|
||||
<td><small>${escHtml(d.office_kigo || "")} ${escHtml(d.office_number || "")}</small></td>
|
||||
<td>${escHtml(d.nenkin_jimusho || "−")}</td>
|
||||
<td>${issueDate}</td>
|
||||
<td><small>${uploadedAt}</small></td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
function badgeHtml(type, name) {
|
||||
const cls = {SHAKAI:'badge-shakai', NOUNYU:'badge-nounyu', SHOYO:'badge-shoyo'}[type] || 'badge-unknown';
|
||||
const cls =
|
||||
{
|
||||
SHAKAI: "badge-shakai",
|
||||
NOUNYU: "badge-nounyu",
|
||||
SHOYO: "badge-shoyo",
|
||||
}[type] || "badge-unknown";
|
||||
return `<span class="badge ${cls}">${escHtml(name || type)}</span>`;
|
||||
}
|
||||
|
||||
@@ -422,11 +561,14 @@ async function loadFilterOptions() {
|
||||
try {
|
||||
const res = await fetch(`${API}/nenkin/filter-options`);
|
||||
const data = await res.json();
|
||||
const sel = document.getElementById('year-select');
|
||||
const years = [...new Set(data.periods.map(p => p.purpose_year))].sort((a,b) => b-a);
|
||||
years.forEach(y => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = y; opt.textContent = `${y}年`;
|
||||
const sel = document.getElementById("year-select");
|
||||
const years = [
|
||||
...new Set(data.periods.map((p) => p.purpose_year)),
|
||||
].sort((a, b) => b - a);
|
||||
years.forEach((y) => {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = y;
|
||||
opt.textContent = `${y}年`;
|
||||
sel.appendChild(opt);
|
||||
});
|
||||
} catch (_) {}
|
||||
@@ -438,8 +580,8 @@ async function loadFilterOptions() {
|
||||
async function loadDetail(docId) {
|
||||
// 選択行のハイライト
|
||||
selectedDocId = docId;
|
||||
document.querySelectorAll('.doc-table tbody tr').forEach(tr => {
|
||||
tr.classList.toggle('selected', parseInt(tr.dataset.id) === docId);
|
||||
document.querySelectorAll(".doc-table tbody tr").forEach((tr) => {
|
||||
tr.classList.toggle("selected", parseInt(tr.dataset.id) === docId);
|
||||
});
|
||||
|
||||
try {
|
||||
@@ -453,18 +595,21 @@ async function loadDetail(docId) {
|
||||
|
||||
function closeDetail() {
|
||||
selectedDocId = null;
|
||||
document.getElementById('detail-panel').classList.remove('visible');
|
||||
document.querySelectorAll('.doc-table tbody tr').forEach(tr => tr.classList.remove('selected'));
|
||||
document.getElementById("detail-panel").classList.remove("visible");
|
||||
document
|
||||
.querySelectorAll(".doc-table tbody tr")
|
||||
.forEach((tr) => tr.classList.remove("selected"));
|
||||
}
|
||||
|
||||
function renderDetail({ document: doc, detail }) {
|
||||
const panel = document.getElementById('detail-panel');
|
||||
const title = document.getElementById('detail-title');
|
||||
const body = document.getElementById('detail-body');
|
||||
const panel = document.getElementById("detail-panel");
|
||||
const title = document.getElementById("detail-title");
|
||||
const body = document.getElementById("detail-body");
|
||||
|
||||
const period = doc.purpose_year && doc.purpose_month
|
||||
const period =
|
||||
doc.purpose_year && doc.purpose_month
|
||||
? `${doc.purpose_year}年${doc.purpose_month}月分`
|
||||
: '';
|
||||
: "";
|
||||
title.textContent = `${doc.document_type_name} ${period}`;
|
||||
|
||||
// 共通事業所カード
|
||||
@@ -472,50 +617,61 @@ function renderDetail({ document: doc, detail }) {
|
||||
<div class="info-cards">
|
||||
<div class="info-card">
|
||||
<div class="label">事業所名</div>
|
||||
<div class="value">${escHtml(doc.office_name || '−')}</div>
|
||||
<div class="value">${escHtml(doc.office_name || "−")}</div>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<div class="label">事業所番号 / 整理記号</div>
|
||||
<div class="value">${escHtml(doc.office_number || '')} / ${escHtml(doc.office_kigo || '')}</div>
|
||||
<div class="value">${escHtml(doc.office_number || "")} / ${escHtml(doc.office_kigo || "")}</div>
|
||||
</div>
|
||||
<div class="info-card">
|
||||
<div class="label">担当年金事務所</div>
|
||||
<div class="value">${escHtml(doc.nenkin_jimusho || '−')}</div>
|
||||
<div class="value">${escHtml(doc.nenkin_jimusho || "−")}</div>
|
||||
</div>
|
||||
${doc.issue_date ? `<div class="info-card">
|
||||
${
|
||||
doc.issue_date
|
||||
? `<div class="info-card">
|
||||
<div class="label">発行日</div>
|
||||
<div class="value">${doc.issue_date.replace(/-/g,'/')}</div>
|
||||
</div>` : ''}
|
||||
<div class="value">${doc.issue_date.replace(/-/g, "/")}</div>
|
||||
</div>`
|
||||
: ""
|
||||
}
|
||||
</div>`;
|
||||
|
||||
let typeHtml = '';
|
||||
if (doc.document_type === 'SHAKAI') {
|
||||
let typeHtml = "";
|
||||
if (doc.document_type === "SHAKAI") {
|
||||
typeHtml = renderShakai(detail);
|
||||
} else if (doc.document_type === 'NOUNYU') {
|
||||
} else if (doc.document_type === "NOUNYU") {
|
||||
typeHtml = renderNounyu(detail);
|
||||
} else if (doc.document_type === 'SHOYO') {
|
||||
} else if (doc.document_type === "SHOYO") {
|
||||
typeHtml = renderShoyo(detail);
|
||||
}
|
||||
|
||||
body.innerHTML = infoHtml + typeHtml;
|
||||
panel.classList.add('visible');
|
||||
panel.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
panel.classList.add("visible");
|
||||
panel.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
}
|
||||
|
||||
// ──────────────────────────────────
|
||||
// 社会保険料額情報 (SHAKAI)
|
||||
// ──────────────────────────────────
|
||||
function renderShakai(d) {
|
||||
const kigen = d.nofu_kigen_date ? d.nofu_kigen_date.replace(/-/g, '/') : '−';
|
||||
const addr = [d.office_postcode ? `〒${d.office_postcode}` : '', d.office_address].filter(Boolean).join(' ');
|
||||
const kigen = d.nofu_kigen_date
|
||||
? d.nofu_kigen_date.replace(/-/g, "/")
|
||||
: "−";
|
||||
const addr = [
|
||||
d.office_postcode ? `〒${d.office_postcode}` : "",
|
||||
d.office_address,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
return `
|
||||
<div class="amount-section">
|
||||
<h3>保険料額</h3>
|
||||
<div class="amount-grid">
|
||||
${amtRow('健康保険料', d.kenkou_hokenryo)}
|
||||
${amtRow('厚生年金保険料', d.kousei_nenkin_hokenryo)}
|
||||
${amtRow('子ども・子育て拠出金', d.kodomo_kyoshutsukin)}
|
||||
${amtRow('合 計', d.total, true)}
|
||||
${amtRow("健康保険料", d.kenkou_hokenryo)}
|
||||
${amtRow("厚生年金保険料", d.kousei_nenkin_hokenryo)}
|
||||
${amtRow("子ども・子育て拠出金", d.kodomo_kyoshutsukin)}
|
||||
${amtRow("合 計", d.total, true)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-cards">
|
||||
@@ -523,10 +679,14 @@ function renderShakai(d) {
|
||||
<div class="label">納付期限</div>
|
||||
<div class="value">${kigen}</div>
|
||||
</div>
|
||||
${addr ? `<div class="info-card" style="flex:2">
|
||||
${
|
||||
addr
|
||||
? `<div class="info-card" style="flex:2">
|
||||
<div class="label">事業所所在地</div>
|
||||
<div class="value">${escHtml(addr)}</div>
|
||||
</div>` : ''}
|
||||
</div>`
|
||||
: ""
|
||||
}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -534,36 +694,39 @@ function renderShakai(d) {
|
||||
// 保険料納入告知額・領収済額 (NOUNYU)
|
||||
// ──────────────────────────────────
|
||||
function renderNounyu(d) {
|
||||
const kigen = d.kokuchi_nofu_kigen ? d.kokuchi_nofu_kigen.replace(/-/g, '/') : '−';
|
||||
const ryoshuDt = d.ryoshu_date ? d.ryoshu_date.replace(/-/g, '/') : '−';
|
||||
const ryoshuPeriod = d.ryoshu_nofu_year && d.ryoshu_nofu_month
|
||||
const kigen = d.kokuchi_nofu_kigen
|
||||
? d.kokuchi_nofu_kigen.replace(/-/g, "/")
|
||||
: "−";
|
||||
const ryoshuDt = d.ryoshu_date ? d.ryoshu_date.replace(/-/g, "/") : "−";
|
||||
const ryoshuPeriod =
|
||||
d.ryoshu_nofu_year && d.ryoshu_nofu_month
|
||||
? `${d.ryoshu_nofu_year}年${d.ryoshu_nofu_month}月分`
|
||||
: '−';
|
||||
: "−";
|
||||
return `
|
||||
<div class="nounyu-compare">
|
||||
<div class="nounyu-box kokuchi">
|
||||
<h4>📋 今月の保険料告知額(納付期限: ${kigen})</h4>
|
||||
<div class="amount-grid">
|
||||
${amtRow('健康保険料', d.kokuchi_kenkou)}
|
||||
${amtRow('厚生年金保険料', d.kokuchi_kounen)}
|
||||
${amtRow('子ども・子育て拠出金', d.kokuchi_kodomo)}
|
||||
${amtRow('合 計', d.kokuchi_total, true)}
|
||||
${amtRow("健康保険料", d.kokuchi_kenkou)}
|
||||
${amtRow("厚生年金保険料", d.kokuchi_kounen)}
|
||||
${amtRow("子ども・子育て拠出金", d.kokuchi_kodomo)}
|
||||
${amtRow("合 計", d.kokuchi_total, true)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="nounyu-box ryoshu">
|
||||
<h4>✅ 前月分領収済額(${ryoshuPeriod}・領収日: ${ryoshuDt})</h4>
|
||||
<div class="amount-grid">
|
||||
${amtRow('健康保険料', d.ryoshu_kenkou)}
|
||||
${amtRow('厚生年金保険料', d.ryoshu_kounen)}
|
||||
${amtRow('子ども・子育て拠出金', d.ryoshu_kodomo)}
|
||||
${amtRow('合 計', d.ryoshu_total, true)}
|
||||
${amtRow("健康保険料", d.ryoshu_kenkou)}
|
||||
${amtRow("厚生年金保険料", d.ryoshu_kounen)}
|
||||
${amtRow("子ども・子育て拠出金", d.ryoshu_kodomo)}
|
||||
${amtRow("合 計", d.ryoshu_total, true)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-cards">
|
||||
<div class="info-card">
|
||||
<div class="label">事業所所在地</div>
|
||||
<div class="value">${escHtml([d.office_postcode ? '〒'+d.office_postcode : '', d.office_address].filter(Boolean).join(' '))}</div>
|
||||
<div class="value">${escHtml([d.office_postcode ? "〒" + d.office_postcode : "", d.office_address].filter(Boolean).join(" "))}</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
@@ -572,20 +735,21 @@ function renderNounyu(d) {
|
||||
// 賞与保険料算出内訳書 (SHOYO)
|
||||
// ──────────────────────────────────
|
||||
function renderShoyo(d) {
|
||||
if (!d || !d.items) return '<p>詳細データなし</p>';
|
||||
if (!d || !d.items) return "<p>詳細データなし</p>";
|
||||
|
||||
const totKenpo = sum(d.items, 'kenpo_hongetsu');
|
||||
const totKounen = sum(d.items, 'kounen_hongetsu');
|
||||
const totHKenpo = sum(d.items, 'hyojun_shoyo_kenpo');
|
||||
const totHKounen = sum(d.items, 'hyojun_shoyo_kounen');
|
||||
const totKenpo = sum(d.items, "kenpo_hongetsu");
|
||||
const totKounen = sum(d.items, "kounen_hongetsu");
|
||||
const totHKenpo = sum(d.items, "hyojun_shoyo_kenpo");
|
||||
const totHKounen = sum(d.items, "hyojun_shoyo_kounen");
|
||||
|
||||
const rows = d.items.map(it => {
|
||||
const rows = d.items
|
||||
.map((it) => {
|
||||
const hassei = it.hassei_date_iso
|
||||
? it.hassei_date_iso.replace(/-/g, '/')
|
||||
: (it.hassei_ymd || '−');
|
||||
? it.hassei_date_iso.replace(/-/g, "/")
|
||||
: it.hassei_ymd || "−";
|
||||
return `<tr>
|
||||
<td>${escHtml(it.seiri_num || '')}</td>
|
||||
<td class="name">${escHtml(it.shimei || '')}</td>
|
||||
<td>${escHtml(it.seiri_num || "")}</td>
|
||||
<td class="name">${escHtml(it.shimei || "")}</td>
|
||||
<td>${hassei}</td>
|
||||
<td>${fmtAmt(it.hyojun_shoyo_kenpo)}</td>
|
||||
<td>${fmtAmt(it.hyojun_shoyo_kounen)}</td>
|
||||
@@ -594,7 +758,8 @@ function renderShoyo(d) {
|
||||
<td>${fmtAmt(it.kounen_hongetsu)}</td>
|
||||
<td>${it.kounen_zengetsu ? fmtAmt(it.kounen_zengetsu) : '<span class="empty-cell">−</span>'}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
})
|
||||
.join("");
|
||||
|
||||
return `
|
||||
<div class="info-cards" style="margin-bottom:16px">
|
||||
@@ -602,10 +767,14 @@ function renderShoyo(d) {
|
||||
<div class="label">対象人員</div>
|
||||
<div class="value">${d.jin_in_num} 名</div>
|
||||
</div>
|
||||
${d.menjyo_hokenryo_ritsu ? `<div class="info-card">
|
||||
${
|
||||
d.menjyo_hokenryo_ritsu
|
||||
? `<div class="info-card">
|
||||
<div class="label">免除保険料率</div>
|
||||
<div class="value">${escHtml(d.menjyo_hokenryo_ritsu)}</div>
|
||||
</div>` : ''}
|
||||
</div>`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
<div class="shoyo-table-wrap">
|
||||
<table class="shoyo-table">
|
||||
@@ -647,36 +816,48 @@ function renderShoyo(d) {
|
||||
// アップロードゾーン
|
||||
// ──────────────────────────────────
|
||||
function initUploadZone() {
|
||||
const zone = document.getElementById('upload-zone');
|
||||
const input = document.getElementById('zip-input');
|
||||
const zone = document.getElementById("upload-zone");
|
||||
const input = document.getElementById("zip-input");
|
||||
|
||||
zone.addEventListener('dragover', e => { e.preventDefault(); zone.classList.add('dragover'); });
|
||||
zone.addEventListener('dragleave', () => zone.classList.remove('dragover'));
|
||||
zone.addEventListener('drop', e => {
|
||||
zone.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
zone.classList.remove('dragover');
|
||||
const files = [...e.dataTransfer.files].filter(f => f.name.endsWith('.zip'));
|
||||
zone.classList.add("dragover");
|
||||
});
|
||||
zone.addEventListener("dragleave", () =>
|
||||
zone.classList.remove("dragover"),
|
||||
);
|
||||
zone.addEventListener("drop", (e) => {
|
||||
e.preventDefault();
|
||||
zone.classList.remove("dragover");
|
||||
const files = [...e.dataTransfer.files].filter((f) =>
|
||||
f.name.endsWith(".zip"),
|
||||
);
|
||||
if (files.length) uploadFiles(files);
|
||||
});
|
||||
|
||||
input.addEventListener('change', () => {
|
||||
input.addEventListener("change", () => {
|
||||
const files = [...input.files];
|
||||
if (files.length) uploadFiles(files);
|
||||
input.value = '';
|
||||
input.value = "";
|
||||
});
|
||||
}
|
||||
|
||||
async function uploadFiles(files) {
|
||||
const status = document.getElementById('upload-status');
|
||||
const status = document.getElementById("upload-status");
|
||||
status.innerHTML = `<span style="color:#6c757d">アップロード中... (${files.length}件)</span>`;
|
||||
|
||||
let ok = 0, skipped = 0, errors = [];
|
||||
let ok = 0,
|
||||
skipped = 0,
|
||||
errors = [];
|
||||
|
||||
for (const file of files) {
|
||||
const fd = new FormData();
|
||||
fd.append('file', file);
|
||||
fd.append("file", file);
|
||||
try {
|
||||
const res = await fetch(`${API}/nenkin/upload`, { method: 'POST', body: fd });
|
||||
const res = await fetch(`${API}/nenkin/upload`, {
|
||||
method: "POST",
|
||||
body: fd,
|
||||
});
|
||||
const json = await res.json();
|
||||
if (res.status === 409) {
|
||||
skipped++;
|
||||
@@ -690,10 +871,12 @@ async function uploadFiles(files) {
|
||||
}
|
||||
}
|
||||
|
||||
let msg = '';
|
||||
let msg = "";
|
||||
if (ok > 0) msg += `<span class="status-ok">✓ ${ok}件登録完了</span> `;
|
||||
if (skipped > 0) msg += `<span style="color:#856404">⚠ ${skipped}件は既登録のためスキップ</span> `;
|
||||
if (errors.length) msg += `<span class="status-err">✗ エラー: ${errors.join(' / ')}</span>`;
|
||||
if (skipped > 0)
|
||||
msg += `<span style="color:#856404">⚠ ${skipped}件は既登録のためスキップ</span> `;
|
||||
if (errors.length)
|
||||
msg += `<span class="status-err">✗ エラー: ${errors.join(" / ")}</span>`;
|
||||
status.innerHTML = msg;
|
||||
|
||||
if (ok > 0) {
|
||||
@@ -706,16 +889,26 @@ async function uploadFiles(files) {
|
||||
// ユーティリティ
|
||||
// ──────────────────────────────────
|
||||
function escHtml(s) {
|
||||
return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
||||
return String(s)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """);
|
||||
}
|
||||
|
||||
function fmtAmt(v) {
|
||||
if (v == null || v === '') return '<span class="empty-cell">−</span>';
|
||||
return '¥' + Number(v).toLocaleString('ja-JP', { minimumFractionDigits: 0, maximumFractionDigits: 0 });
|
||||
if (v == null || v === "") return '<span class="empty-cell">−</span>';
|
||||
return (
|
||||
"¥" +
|
||||
Number(v).toLocaleString("ja-JP", {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 0,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function amtRow(label, value, isTotal = false) {
|
||||
return `<div class="amount-row${isTotal ? ' total' : ''}">
|
||||
return `<div class="amount-row${isTotal ? " total" : ""}">
|
||||
<span>${label}</span>
|
||||
<span class="amt">${fmtAmt(value)}</span>
|
||||
</div>`;
|
||||
@@ -726,10 +919,10 @@ function sum(items, key) {
|
||||
}
|
||||
|
||||
function showDetailError(msg) {
|
||||
const panel = document.getElementById('detail-panel');
|
||||
document.getElementById('detail-body').innerHTML =
|
||||
const panel = document.getElementById("detail-panel");
|
||||
document.getElementById("detail-body").innerHTML =
|
||||
`<p style="color:#dc3545">エラー: ${escHtml(msg)}</p>`;
|
||||
panel.classList.add('visible');
|
||||
panel.classList.add("visible");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -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 @@
|
||||
<div class="form-group">
|
||||
<label>賞与種別</label>
|
||||
<select name="bonus_type">
|
||||
<option value="夏季賞与" ${bonus.bonus_type === '夏季賞与' ? 'selected' : ''}>夏季賞与</option>
|
||||
<option value="冬季賞与" ${bonus.bonus_type === '冬季賞与' ? 'selected' : ''}>冬季賞与</option>
|
||||
<option value="決算賞与" ${bonus.bonus_type === '決算賞与' ? 'selected' : ''}>決算賞与</option>
|
||||
<option value="その他" ${bonus.bonus_type === 'その他' ? 'selected' : ''}>その他</option>
|
||||
<option value="夏季賞与" ${bonus.bonus_type === "夏季賞与" ? "selected" : ""}>夏季賞与</option>
|
||||
<option value="冬季賞与" ${bonus.bonus_type === "冬季賞与" ? "selected" : ""}>冬季賞与</option>
|
||||
<option value="決算賞与" ${bonus.bonus_type === "決算賞与" ? "selected" : ""}>決算賞与</option>
|
||||
<option value="その他" ${bonus.bonus_type === "その他" ? "selected" : ""}>その他</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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) {
|
||||
|
||||
@@ -118,16 +118,17 @@
|
||||
>
|
||||
<div class="icon">📄</div>
|
||||
<h2>源泉徴収票</h2>
|
||||
<p>給与所得の源泉徴収票を発行します(本人用・区役所用・税務署用 各1部)</p>
|
||||
<p>
|
||||
給与所得の源泉徴収票を発行します(本人用・区役所用・税務署用 各1部)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="menu-card"
|
||||
onclick="location.href = 'nenkin-portal.html'"
|
||||
>
|
||||
<div class="menu-card" onclick="location.href = 'nenkin-portal.html'">
|
||||
<div class="icon">📋</div>
|
||||
<h2>社会保険電子文書</h2>
|
||||
<p>日本年金機構からの電子文書(保険料通知・賞与内訳等)を管理します</p>
|
||||
<p>
|
||||
日本年金機構からの電子文書(保険料通知・賞与内訳等)を管理します
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user