/* ===== tkuser 설비(Equipment) CRUD ===== */ let equipmentsLoaded = false; let equipmentsList = []; let selectedEquipmentIdTkuser = null; const EQUIPMENT_STATUS_MAP = { active: { label: '활성', cls: 'bg-green-100 text-green-700' }, maintenance: { label: '정비중', cls: 'bg-yellow-100 text-yellow-700' }, inactive: { label: '비활성', cls: 'bg-gray-100 text-gray-400' } }; async function loadEquipmentsTab() { if (equipmentsLoaded) return; equipmentsLoaded = true; if (currentUser && ['admin', 'system'].includes(currentUser.role)) { document.getElementById('btnAddEquipment')?.classList.remove('hidden'); } await Promise.all([loadEquipmentFilters(), loadEquipmentsList()]); } async function loadEquipmentFilters() { try { // 작업장 필터 const wRes = await api('/workplaces'); const workplaces = wRes.data || []; const wSel = document.getElementById('equipmentFilterWorkplace'); if (wSel) { const current = wSel.value; wSel.innerHTML = '' + workplaces.map(w => ``).join(''); wSel.value = current; } // 유형 필터 const tRes = await api('/equipments/types'); const types = tRes.data || []; const tSel = document.getElementById('equipmentFilterType'); if (tSel) { const current = tSel.value; tSel.innerHTML = '' + types.map(t => ``).join(''); tSel.value = current; } // 모달 select 채우기 (작업장) ['newEquipmentWorkplaceTkuser', 'editEquipmentWorkplaceTkuser'].forEach(id => { const el = document.getElementById(id); if (el) el.innerHTML = '' + workplaces.map(w => ``).join(''); }); } catch (e) { /* 필터 로드 실패는 무시 */ } } async function loadEquipmentsList() { try { const workplaceId = document.getElementById('equipmentFilterWorkplace')?.value || ''; const eqType = document.getElementById('equipmentFilterType')?.value || ''; const status = document.getElementById('equipmentFilterStatus')?.value || ''; const search = document.getElementById('equipmentSearchTkuser')?.value?.trim() || ''; const params = new URLSearchParams(); if (workplaceId) params.set('workplace_id', workplaceId); if (eqType) params.set('equipment_type', eqType); if (status) params.set('status', status); if (search) params.set('search', search); const r = await api('/equipments?' + params.toString()); equipmentsList = r.data || []; renderEquipmentsListTkuser(); } catch (e) { document.getElementById('equipmentsListTkuser').innerHTML = `

${e.message}

`; } } function renderEquipmentsListTkuser() { const c = document.getElementById('equipmentsListTkuser'); if (!equipmentsList.length) { c.innerHTML = '

등록된 설비가 없습니다.

'; return; } const isAdmin = currentUser && ['admin', 'system'].includes(currentUser.role); c.innerHTML = equipmentsList.map(eq => { const st = EQUIPMENT_STATUS_MAP[eq.status] || EQUIPMENT_STATUS_MAP.active; return `
${escHtml(eq.equipment_name)} ${st.label}
${escHtml(eq.equipment_code)} ${eq.workplace_name ? `· ${escHtml(eq.workplace_name)}` : ''} ${eq.equipment_type ? `· ${escHtml(eq.equipment_type)}` : ''}
${isAdmin ? `
` : ''}
`; }).join(''); } async function selectEquipmentTkuser(id) { selectedEquipmentIdTkuser = id; renderEquipmentsListTkuser(); try { const r = await api(`/equipments/${id}`); const eq = r.data; renderEquipmentDetailTkuser(eq); document.getElementById('equipmentDetailTkuser').classList.remove('hidden'); document.getElementById('equipmentEmptyTkuser').classList.add('hidden'); } catch (e) { showToast('상세 조회 실패: ' + e.message, 'error'); } } function renderEquipmentDetailTkuser(eq) { const st = EQUIPMENT_STATUS_MAP[eq.status] || EQUIPMENT_STATUS_MAP.active; const installDate = eq.installation_date ? eq.installation_date.substring(0, 10) : '-'; document.getElementById('equipmentDetailTkuser').innerHTML = `

${escHtml(eq.equipment_name)}

${st.label}
관리번호: ${escHtml(eq.equipment_code)}
설비유형: ${escHtml(eq.equipment_type) || '-'}
작업장: ${escHtml(eq.workplace_name) || '-'}
제조사: ${escHtml(eq.manufacturer) || '-'}
모델명: ${escHtml(eq.model_name) || '-'}
시리얼번호: ${escHtml(eq.serial_number) || '-'}
설치일: ${installDate}
공급업체: ${escHtml(eq.supplier) || '-'}
${eq.purchase_price ? `
구매가격: ${Number(eq.purchase_price).toLocaleString()}원
` : ''} ${eq.specifications ? `
사양: ${escHtml(eq.specifications)}
` : ''} ${eq.notes ? `
비고: ${escHtml(eq.notes)}
` : ''}
`; } /* ===== 설비 등록 ===== */ function openAddEquipmentTkuser() { // 다음 코드 자동 생성 api('/equipments/next-code').then(r => { document.getElementById('newEquipmentCodeTkuser').value = r.data || ''; }).catch(() => {}); document.getElementById('addEquipmentModalTkuser').classList.remove('hidden'); } function closeAddEquipmentTkuser() { document.getElementById('addEquipmentModalTkuser').classList.add('hidden'); document.getElementById('addEquipmentFormTkuser').reset(); } async function submitAddEquipmentTkuser(e) { e.preventDefault(); const data = { equipment_code: document.getElementById('newEquipmentCodeTkuser').value.trim(), equipment_name: document.getElementById('newEquipmentNameTkuser').value.trim(), equipment_type: document.getElementById('newEquipmentTypeTkuser').value.trim() || null, workplace_id: document.getElementById('newEquipmentWorkplaceTkuser').value || null, manufacturer: document.getElementById('newEquipmentManufacturerTkuser').value.trim() || null, model_name: document.getElementById('newEquipmentModelTkuser').value.trim() || null, serial_number: document.getElementById('newEquipmentSerialTkuser').value.trim() || null, installation_date: document.getElementById('newEquipmentInstallDateTkuser').value || null, supplier: document.getElementById('newEquipmentSupplierTkuser').value.trim() || null, purchase_price: document.getElementById('newEquipmentPriceTkuser').value || null, status: document.getElementById('newEquipmentStatusTkuser').value || 'active', specifications: document.getElementById('newEquipmentSpecsTkuser').value.trim() || null, notes: document.getElementById('newEquipmentNotesTkuser').value.trim() || null, }; if (!data.equipment_code) { showToast('관리번호는 필수입니다', 'error'); return; } if (!data.equipment_name) { showToast('설비명은 필수입니다', 'error'); return; } try { await api('/equipments', { method: 'POST', body: JSON.stringify(data) }); showToast('설비가 등록되었습니다'); closeAddEquipmentTkuser(); await loadEquipmentFilters(); await loadEquipmentsList(); } catch (e) { showToast(e.message, 'error'); } } /* ===== 설비 수정 ===== */ function openEditEquipmentTkuser(id) { const eq = equipmentsList.find(x => x.equipment_id === id); if (!eq) return; document.getElementById('editEquipmentIdTkuser').value = eq.equipment_id; document.getElementById('editEquipmentCodeTkuser').value = eq.equipment_code; document.getElementById('editEquipmentNameTkuser').value = eq.equipment_name; document.getElementById('editEquipmentTypeTkuser').value = eq.equipment_type || ''; document.getElementById('editEquipmentWorkplaceTkuser').value = eq.workplace_id || ''; document.getElementById('editEquipmentManufacturerTkuser').value = eq.manufacturer || ''; document.getElementById('editEquipmentModelTkuser').value = eq.model_name || ''; document.getElementById('editEquipmentSerialTkuser').value = eq.serial_number || ''; document.getElementById('editEquipmentInstallDateTkuser').value = eq.installation_date ? eq.installation_date.substring(0, 10) : ''; document.getElementById('editEquipmentSupplierTkuser').value = eq.supplier || ''; document.getElementById('editEquipmentPriceTkuser').value = eq.purchase_price || ''; document.getElementById('editEquipmentStatusTkuser').value = eq.status || 'active'; document.getElementById('editEquipmentSpecsTkuser').value = eq.specifications || ''; document.getElementById('editEquipmentNotesTkuser').value = eq.notes || ''; document.getElementById('editEquipmentModalTkuser').classList.remove('hidden'); } function closeEditEquipmentTkuser() { document.getElementById('editEquipmentModalTkuser').classList.add('hidden'); } async function submitEditEquipmentTkuser(e) { e.preventDefault(); const id = document.getElementById('editEquipmentIdTkuser').value; const data = { equipment_code: document.getElementById('editEquipmentCodeTkuser').value.trim(), equipment_name: document.getElementById('editEquipmentNameTkuser').value.trim(), equipment_type: document.getElementById('editEquipmentTypeTkuser').value.trim() || null, workplace_id: document.getElementById('editEquipmentWorkplaceTkuser').value || null, manufacturer: document.getElementById('editEquipmentManufacturerTkuser').value.trim() || null, model_name: document.getElementById('editEquipmentModelTkuser').value.trim() || null, serial_number: document.getElementById('editEquipmentSerialTkuser').value.trim() || null, installation_date: document.getElementById('editEquipmentInstallDateTkuser').value || null, supplier: document.getElementById('editEquipmentSupplierTkuser').value.trim() || null, purchase_price: document.getElementById('editEquipmentPriceTkuser').value || null, status: document.getElementById('editEquipmentStatusTkuser').value || 'active', specifications: document.getElementById('editEquipmentSpecsTkuser').value.trim() || null, notes: document.getElementById('editEquipmentNotesTkuser').value.trim() || null, }; try { await api(`/equipments/${id}`, { method: 'PUT', body: JSON.stringify(data) }); showToast('수정되었습니다'); closeEditEquipmentTkuser(); await loadEquipmentFilters(); await loadEquipmentsList(); if (selectedEquipmentIdTkuser == id) selectEquipmentTkuser(id); } catch (e) { showToast(e.message, 'error'); } } /* ===== 설비 삭제 ===== */ async function deleteEquipmentTkuser(id, name) { if (!confirm(`"${name}" 설비를 삭제하시겠습니까?`)) return; try { await api(`/equipments/${id}`, { method: 'DELETE' }); showToast('삭제 완료'); await loadEquipmentsList(); if (selectedEquipmentIdTkuser === id) { document.getElementById('equipmentDetailTkuser').classList.add('hidden'); document.getElementById('equipmentEmptyTkuser').classList.remove('hidden'); selectedEquipmentIdTkuser = null; } } catch (e) { showToast(e.message, 'error'); } } /* ===== 필터 ===== */ let equipmentSearchTimeout; function filterEquipmentsTkuser() { clearTimeout(equipmentSearchTimeout); equipmentSearchTimeout = setTimeout(loadEquipmentsList, 300); } // 검색/필터 이벤트 + 모달 폼 이벤트 document.addEventListener('DOMContentLoaded', () => { document.getElementById('addEquipmentFormTkuser')?.addEventListener('submit', submitAddEquipmentTkuser); document.getElementById('editEquipmentFormTkuser')?.addEventListener('submit', submitEditEquipmentTkuser); });