v3: Кнопка «Выдать» в таблице норм — выбор работника и выдача СИЗ в один клик
This commit is contained in:
parent
6a6512db49
commit
1a7f7e2ba9
90
index.html
90
index.html
@ -403,6 +403,28 @@ tr:hover td { background: var(--cyan-50); }
|
||||
}
|
||||
.norm-hint-item .btn-xs:hover { opacity: .8; }
|
||||
|
||||
/* Norm issue modal — employee pick list */
|
||||
.norm-issue-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
max-height: 40vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.norm-issue-emp {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
padding: 10px 14px;
|
||||
background: var(--gray-100);
|
||||
border-radius: var(--radius);
|
||||
font-size: 13px;
|
||||
}
|
||||
.norm-issue-emp-info { min-width: 0; }
|
||||
.norm-issue-emp-name { font-weight: 600; }
|
||||
.norm-issue-emp-meta { font-size: 12px; color: var(--gray-500); }
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.header { padding: 12px 16px; }
|
||||
@ -833,6 +855,18 @@ tr:hover td { background: var(--cyan-50); }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- NORM ISSUE MODAL (выдать сотруднику по норме) -->
|
||||
<div class="modal-overlay" id="normIssueModal">
|
||||
<div class="modal">
|
||||
<h2 id="normIssueTitle">Выдать СИЗ</h2>
|
||||
<div id="normIssueInfo" style="font-size:13px;color:var(--gray-500);margin-bottom:16px;"></div>
|
||||
<div id="normIssueList" class="norm-issue-list"></div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn btn-outline" onclick="closeModal('normIssueModal')">Отмена</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ISSUANCE MODAL -->
|
||||
<div class="modal-overlay" id="issuanceModal">
|
||||
<div class="modal">
|
||||
@ -1299,6 +1333,7 @@ function renderNorms() {
|
||||
<td>${n.quantity} ${(DB.siz.find(s=>s.id===n.sizId)||{}).unit||'шт.'}</td>
|
||||
<td>${n.note || '—'}</td>
|
||||
<td>
|
||||
<button class="btn btn-success" style="padding:4px 10px;font-size:12px;margin-right:4px;" onclick="normPickEmployee('${n.id}')" title="Выдать">📤 Выдать</button>
|
||||
<button class="action-btn" title="Редактировать" onclick="openNormModal(DB.norms.find(x=>x.id==='${n.id}'))">✏️</button>
|
||||
<button class="action-btn" title="Удалить" onclick="deleteNorm('${n.id}')">🗑️</button>
|
||||
</td>
|
||||
@ -1306,6 +1341,61 @@ function renderNorms() {
|
||||
document.getElementById('normEmpty').style.display = list.length ? 'none' : 'block';
|
||||
}
|
||||
|
||||
function normPickEmployee(normId) {
|
||||
const norm = DB.norms.find(n => n.id === normId);
|
||||
if (!norm) return;
|
||||
const siz = DB.siz.find(s => s.id === norm.sizId);
|
||||
const sizName = siz ? siz.name : '—';
|
||||
const unit = siz ? siz.unit : 'шт.';
|
||||
const zone = norm.climateZone || '0';
|
||||
|
||||
document.getElementById('normIssueTitle').textContent = 'Выдать СИЗ';
|
||||
document.getElementById('normIssueInfo').innerHTML = `<strong>${sizName}</strong> × ${norm.quantity} ${unit} — ${monthsToText(norm.wearMonths)}<br>Должность: ${norm.position}, ${climateZoneLabel(zone)}`;
|
||||
|
||||
let employees = DB.employees;
|
||||
if (zone !== '0') {
|
||||
employees = employees.filter(e => e.position === norm.position && (e.climateZone || '0') === zone);
|
||||
if (employees.length === 0) employees = DB.employees.filter(e => e.position === norm.position && (e.climateZone || '0') === '0');
|
||||
if (employees.length === 0) employees = DB.employees.filter(e => e.position === norm.position);
|
||||
} else {
|
||||
employees = DB.employees.filter(e => e.position === norm.position);
|
||||
}
|
||||
|
||||
document.getElementById('normIssueList').innerHTML = employees.length
|
||||
? employees.map(e => `<div class="norm-issue-emp">
|
||||
<div class="norm-issue-emp-info">
|
||||
<div class="norm-issue-emp-name">${e.fullName}</div>
|
||||
<div class="norm-issue-emp-meta">Таб. № ${e.tabNum} • ${e.department} • ${climateZoneLabel(e.climateZone||'0')}</div>
|
||||
</div>
|
||||
<button class="btn btn-xs" style="background:var(--cyan);color:var(--ink);padding:6px 14px;border:none;border-radius:6px;cursor:pointer;font-weight:600;" onclick="normDoIssue('${norm.id}','${e.id}')">Выдать</button>
|
||||
</div>`).join('')
|
||||
: `<div class="empty"><p>Нет работников с должностью «${norm.position}»${zone!=='0'?' в поясе '+climateZoneLabel(zone):''}.</p></div>`;
|
||||
|
||||
openModal('normIssueModal');
|
||||
}
|
||||
|
||||
function normDoIssue(normId, empId) {
|
||||
const norm = DB.norms.find(n => n.id === normId);
|
||||
if (!norm) return;
|
||||
const dateIssued = todayStr();
|
||||
const expireDate = new Date(dateIssued);
|
||||
expireDate.setMonth(expireDate.getMonth() + norm.wearMonths);
|
||||
const dateExpire = expireDate.toISOString().slice(0, 10);
|
||||
let status = dateExpire < todayStr() ? 'expired' : 'active';
|
||||
DB.issuances = [...DB.issuances, {
|
||||
id: uid(),
|
||||
employeeId: empId,
|
||||
sizId: norm.sizId,
|
||||
quantity: norm.quantity,
|
||||
dateIssued,
|
||||
dateExpire,
|
||||
status,
|
||||
notes: norm.note || '',
|
||||
}];
|
||||
closeModal('normIssueModal');
|
||||
renderIssuances();
|
||||
}
|
||||
|
||||
// ===================== ISSUANCE — SHOW NORMS =====================
|
||||
function showNormsForEmployee() {
|
||||
const empId = document.getElementById('issEmployeeId').value;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user