388 lines
17 KiB
HTML
388 lines
17 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Исполнительные листы — учёт удержаний</title>
|
||
<style>
|
||
:root{--ink:#0F1218;--cyan:#00E5FF;--cyan-50:#E8FCFF;--white:#fff;--gray-500:#5B6573;--gray-100:#F2F4F7;--red:#DC3545;--green:#28A745;--orange:#FD7E14}
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{font:16px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;color:var(--ink);background:var(--white)}
|
||
.container{max-width:1400px;margin:0 auto;padding:40px 24px}
|
||
.header{background:var(--ink);color:var(--white);padding:32px 24px}
|
||
.header h1{font-size:36px;font-weight:700;margin-bottom:8px}
|
||
.header p{color:#9aa3b2;font-size:16px}
|
||
.nav{display:flex;gap:12px;margin-top:20px;flex-wrap:wrap}
|
||
.nav button{background:rgba(255,255,255,0.1);color:var(--white);border:1px solid rgba(255,255,255,0.2);padding:10px 20px;border-radius:8px;cursor:pointer;font-size:14px}
|
||
.nav button.active{background:var(--cyan);color:var(--ink);border-color:var(--cyan)}
|
||
.section{display:none;padding:40px 24px}
|
||
.section.active{display:block}
|
||
.section h2{font-size:28px;font-weight:700;margin-bottom:24px}
|
||
.card{background:var(--gray-100);border-radius:12px;padding:24px;margin-bottom:16px}
|
||
.card h3{font-size:18px;font-weight:600;margin-bottom:16px}
|
||
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:16px}
|
||
.btn{display:inline-block;background:var(--cyan);color:var(--ink);padding:12px 24px;border-radius:8px;font-weight:600;text-decoration:none;border:none;cursor:pointer;font-size:14px}
|
||
.btn:hover{opacity:0.9}
|
||
.btn-secondary{background:var(--gray-500);color:var(--white)}
|
||
.btn-danger{background:var(--red);color:var(--white)}
|
||
.btn-success{background:var(--green);color:var(--white)}
|
||
input,select,textarea{width:100%;padding:10px 12px;border:1px solid #ddd;border-radius:6px;font-size:14px;margin-bottom:12px}
|
||
input:focus,select:focus,textarea:focus{outline:2px solid var(--cyan);border-color:transparent}
|
||
label{display:block;font-weight:600;margin-bottom:6px;font-size:13px;color:var(--gray-500)}
|
||
.table-wrap{overflow-x:auto}
|
||
table{width:100%;border-collapse:collapse;font-size:14px}
|
||
th,td{padding:12px;text-align:left;border-bottom:1px solid #eee}
|
||
th{background:var(--gray-100);font-weight:600;font-size:13px}
|
||
tr:hover{background:#f9f9f9}
|
||
.badge{display:inline-block;padding:4px 10px;border-radius:20px;font-size:12px;font-weight:600}
|
||
.badge-ali{background:#FFE5F0;color:#C2185B}
|
||
.badge-other{background:#E3F2FD;color:#1976D2}
|
||
.badge-closed{background:#E8F5E9;color:#388E3C}
|
||
.badge-active{background:#FFF3E0;color:#F57C00}
|
||
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin-bottom:24px}
|
||
.stat{background:var(--gray-100);padding:20px;border-radius:12px}
|
||
.stat-value{font-size:32px;font-weight:700;color:var(--ink)}
|
||
.stat-label{font-size:13px;color:var(--gray-500);margin-top:4px}
|
||
.progress{height:8px;background:#eee;border-radius:4px;overflow:hidden;margin-top:8px}
|
||
.progress-bar{height:100%;background:var(--cyan);transition:width 0.3s}
|
||
.upload-zone{border:2px dashed #ddd;border-radius:12px;padding:40px;text-align:center;cursor:pointer;transition:all 0.3s}
|
||
.upload-zone:hover{border-color:var(--cyan);background:var(--cyan-50)}
|
||
.upload-zone.dragover{border-color:var(--cyan);background:var(--cyan-50)}
|
||
.filters{display:flex;gap:12px;margin-bottom:20px;flex-wrap:wrap;align-items:center}
|
||
.filters input{width:auto;min-width:250px;margin-bottom:0}
|
||
.chip{padding:6px 14px;border:1px solid #ddd;border-radius:20px;background:var(--white);cursor:pointer;font-size:13px}
|
||
.chip.active{background:var(--ink);color:var(--white);border-color:var(--ink)}
|
||
.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:1000;align-items:center;justify-content:center}
|
||
.modal.open{display:flex}
|
||
.modal-content{background:var(--white);border-radius:12px;max-width:600px;width:90%;max-height:90vh;overflow-y:auto;padding:32px}
|
||
.modal-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}
|
||
.modal-header h3{font-size:20px}
|
||
.modal-close{background:none;border:none;font-size:24px;cursor:pointer}
|
||
.toast{position:fixed;bottom:20px;right:20px;background:var(--ink);color:var(--white);padding:14px 24px;border-radius:8px;opacity:0;transform:translateY(20px);transition:all 0.3s;z-index:2000}
|
||
.toast.show{opacity:1;transform:translateY(0)}
|
||
.toast.success{background:var(--green)}
|
||
.toast.error{background:var(--red)}
|
||
@media (max-width:768px){.header h1{font-size:24px}.stats{grid-template-columns:1fr}.nav{flex-direction:column}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<section class="header">
|
||
<div class="container">
|
||
<h1>☐ Исполнительные листы</h1>
|
||
<p>Система учёта удержаний по постановлениям ЧСИ</p>
|
||
<div class="nav">
|
||
<button class="active" data-section="dashboard">📊 Дашборд</button>
|
||
<button data-section="sap">📁 Загрузка SAP</button>
|
||
<button data-section="employees">👥 Сотрудники</button>
|
||
<button data-section="decrees">📋 Постановления</button>
|
||
<button data-section="analytics">📈 Аналитика</button>
|
||
<button data-section="bank">🏦 Банк</button>
|
||
<button data-section="reports">📑 Отчёты</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="container">
|
||
|
||
<!-- DASHBOARD -->
|
||
<section id="dashboard" class="section active">
|
||
<h2>Общая сводка</h2>
|
||
<div class="stats">
|
||
<div class="stat">
|
||
<div class="stat-value" id="stat-employees">0</div>
|
||
<div class="stat-label">Сотрудников</div>
|
||
</div>
|
||
<div class="stat">
|
||
<div class="stat-value" id="stat-decrees">0</div>
|
||
<div class="stat-label">Постановлений активно</div>
|
||
</div>
|
||
<div class="stat">
|
||
<div class="stat-value" id="stat-total-debt">0 ₸</div>
|
||
<div class="stat-label">Общий долг</div>
|
||
</div>
|
||
<div class="stat">
|
||
<div class="stat-value" id="stat-paid">0 ₸</div>
|
||
<div class="stat-label">Выплачено в этом месяце</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid">
|
||
<div class="card">
|
||
<h3>🔥 Требуют внимания</h3>
|
||
<div id="attention-list">
|
||
<p style="color:var(--gray-500)">Нет проблемных записей</p>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<h3>📅 Последние операции</h3>
|
||
<div id="recent-ops">
|
||
<p style="color:var(--gray-500)">Операций пока нет</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- SAP UPLOAD -->
|
||
<section id="sap" class="section">
|
||
<h2>Загрузка данных из SAP</h2>
|
||
<div class="card">
|
||
<h3>📤 Загрузка файла сотрудников</h3>
|
||
<p style="margin-bottom:16px;color:var(--gray-500)">Загрузите выгрузку из SAP с данными сотрудников (Таб.номер, ФИО, ИИН, Чистый доход)</p>
|
||
<div class="upload-zone" id="sap-upload">
|
||
<p>📎 Перетащите файл Excel сюда или кликните для выбора</p>
|
||
<p style="font-size:13px;color:var(--gray-500);margin-top:8px">Формат: .xlsx, колонки: Табельный номер, ФИО, ИИН, ЧистыйДоход</p>
|
||
<input type="file" id="sap-file" accept=".xlsx,.xls,.csv" style="display:none">
|
||
</div>
|
||
<div id="sap-preview" style="margin-top:20px"></div>
|
||
</div>
|
||
|
||
<div class="card" style="margin-top:20px">
|
||
<h3>📊 Текущий период</h3>
|
||
<label>Месяц расчёта</label>
|
||
<input type="month" id="current-period" value="2026-08">
|
||
<p style="font-size:13px;color:var(--gray-500);margin-top:8px">Все удержания будут привязаны к выбранному периоду</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- EMPLOYEES -->
|
||
<section id="employees" class="section">
|
||
<h2>Сотрудники</h2>
|
||
<div class="filters">
|
||
<input type="text" id="emp-search" placeholder="🔍 Поиск по ФИО, ИИН, таб.номеру">
|
||
<span class="chip active" data-filter="all">Все</span>
|
||
<span class="chip" data-filter="active">С удержаниями</span>
|
||
<span class="chip" data-filter="no-decree">Без постановлений</span>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table id="employees-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Таб.№</th>
|
||
<th>ФИО</th>
|
||
<th>ИИН</th>
|
||
<th>Чистый доход (₸)</th>
|
||
<th>Постановлений</th>
|
||
<th>Удержано в этом месяце</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- DECREES -->
|
||
<section id="decrees" class="section">
|
||
<h2>Постановления</h2>
|
||
<button class="btn" onclick="openModal('decree-modal')" style="margin-bottom:20px">+ Добавить постановление</button>
|
||
|
||
<div class="filters">
|
||
<input type="text" id="decree-search" placeholder="🔍 Поиск по номеру или сотруднику">
|
||
<span class="chip active" data-type="all">Все</span>
|
||
<span class="chip" data-type="alimony">Алименты</span>
|
||
<span class="chip" data-type="other">Штрафы</span>
|
||
<span class="chip" data-type="closed">Закрытые</span>
|
||
</div>
|
||
|
||
<div class="table-wrap">
|
||
<table id="decrees-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Номер</th>
|
||
<th>Дата</th>
|
||
<th>Сотрудник</th>
|
||
<th>Тип</th>
|
||
<th>Сумма долга (₸)</th>
|
||
<th>Удержано (₸)</th>
|
||
<th>% удержания</th>
|
||
<th>Статус</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ANALYTICS -->
|
||
<section id="analytics" class="section">
|
||
<h2>Аналитика по постановлениям</h2>
|
||
<div class="card" style="margin-bottom:20px">
|
||
<h3>📊 Распределение удержаний</h3>
|
||
<p style="color:var(--gray-500);margin-bottom:16px">Система автоматически распределит удержания пропорционально между всеми постановлениями сотрудника (не более 50% от чистого дохода)</p>
|
||
<button class="btn" onclick="calculateDeductions()">Рассчитать удержания</button>
|
||
<button class="btn btn-secondary" onclick="exportBankExcel()" style="margin-left:12px">📥 Выгрузить для банка</button>
|
||
</div>
|
||
|
||
<div class="table-wrap">
|
||
<table id="analytics-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Сотрудник</th>
|
||
<th>Чистый доход</th>
|
||
<th>Макс. удержание (50%)</th>
|
||
<th>Постановлений</th>
|
||
<th>Алименты</th>
|
||
<th>Штрафы</th>
|
||
<th>Итого удержано</th>
|
||
<th>Остаток</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- BANK -->
|
||
<section id="bank" class="section">
|
||
<h2>Онлайн-банкинг</h2>
|
||
<div class="card">
|
||
<h3>📤 Загрузка платёжных поручений</h3>
|
||
<p style="margin-bottom:16px;color:var(--gray-500)">Загрузите файл с платёжками из онлайн-банка для автоматического закрытия удержаний</p>
|
||
<div class="upload-zone" id="payment-upload">
|
||
<p>📎 Перетащите файл Excel сюда или кликните для выбора</p>
|
||
<p style="font-size:13px;color:var(--gray-500);margin-top:8px">Формат: .xlsx, колонки: Номер постановления, Сумма, Дата выплаты</p>
|
||
<input type="file" id="payment-file" accept=".xlsx,.xls,.csv" style="display:none">
|
||
</div>
|
||
<div id="payment-preview" style="margin-top:20px"></div>
|
||
</div>
|
||
|
||
<div class="card" style="margin-top:20px">
|
||
<h3>💳 Реестр выплат</h3>
|
||
<div class="table-wrap">
|
||
<table id="payments-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Дата</th>
|
||
<th>Номер постановления</th>
|
||
<th>Сотрудник</th>
|
||
<th>Тип</th>
|
||
<th>Сумма (₸)</th>
|
||
<th>Статус</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- REPORTS -->
|
||
<section id="reports" class="section">
|
||
<h2>Отчёты</h2>
|
||
<div class="grid">
|
||
<div class="card">
|
||
<h3>📑 Отчёт по кварталам</h3>
|
||
<label>Квартал</label>
|
||
<select id="report-quarter">
|
||
<option value="Q3-2026">3 квартал 2026</option>
|
||
<option value="Q2-2026">2 квартал 2026</option>
|
||
<option value="Q1-2026">1 квартал 2026</option>
|
||
<option value="Q4-2025">4 квартал 2025</option>
|
||
</select>
|
||
<button class="btn" onclick="generateReport()" style="margin-top:12px">Сформировать отчёт</button>
|
||
<button class="btn btn-secondary" onclick="exportReportExcel()" style="margin-top:12px;margin-left:8px">📥 Выгрузить Excel</button>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>📊 Статистика удержаний</h3>
|
||
<div id="report-stats">
|
||
<p style="color:var(--gray-500)">Данных пока нет</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card" style="margin-top:20px">
|
||
<h3>📋 Детализация по постановлениям</h3>
|
||
<div class="table-wrap">
|
||
<table id="report-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Месяц</th>
|
||
<th>Постановление</th>
|
||
<th>Сотрудник</th>
|
||
<th>Тип</th>
|
||
<th>Начислено</th>
|
||
<th>Выплачено</th>
|
||
<th>Остаток</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</div>
|
||
|
||
<!-- MODAL: ADD DECREE -->
|
||
<div id="decree-modal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>Добавить постановление</h3>
|
||
<button class="modal-close" onclick="closeModal('decree-modal')">×</button>
|
||
</div>
|
||
<form id="decree-form">
|
||
<label>Номер постановления ЧСИ</label>
|
||
<input type="text" id="decree-number" required placeholder="Например: №2-345-678">
|
||
|
||
<label>Дата вынесения</label>
|
||
<input type="date" id="decree-date" required>
|
||
|
||
<label>Сотрудник</label>
|
||
<select id="decree-employee" required>
|
||
<option value="">Выберите сотрудника</option>
|
||
</select>
|
||
|
||
<label>Тип удержания</label>
|
||
<select id="decree-type" required>
|
||
<option value="alimony">Алименты</option>
|
||
<option value="other">Штрафы (банк, физ.лицо, коллекторы)</option>
|
||
</select>
|
||
|
||
<label>Сумма задолженности (₸)</label>
|
||
<input type="number" id="decree-amount" required min="0" step="0.01" placeholder="0.00">
|
||
|
||
<label>Комментарий (необязательно)</label>
|
||
<textarea id="decree-comment" rows="3" placeholder="Дополнительная информация"></textarea>
|
||
|
||
<button type="submit" class="btn" style="width:100%;margin-top:16px">Сохранить</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODAL: EDIT EMPLOYEE -->
|
||
<div id="employee-modal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>Редактировать сотрудника</h3>
|
||
<button class="modal-close" onclick="closeModal('employee-modal')">×</button>
|
||
</div>
|
||
<form id="employee-form">
|
||
<input type="hidden" id="edit-emp-id">
|
||
<label>Табельный номер</label>
|
||
<input type="text" id="edit-emp-tabnum" required>
|
||
|
||
<label>ФИО</label>
|
||
<input type="text" id="edit-emp-name" required>
|
||
|
||
<label>ИИН</label>
|
||
<input type="text" id="edit-emp-iin" required maxlength="12">
|
||
|
||
<label>Чистый доход (₸)</label>
|
||
<input type="number" id="edit-emp-salary" required min="0" step="0.01">
|
||
|
||
<button type="submit" class="btn" style="width:100%;margin-top:16px">Сохранить</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="toast" class="toast"></div>
|
||
|
||
<script src="data.js"></script>
|
||
<script src="app.js"></script>
|
||
|
||
</body>
|
||
</html>
|