import { state } from '../../core/state'; import { SoftwareAsset } from '../../core/excelHandler'; import { openModal, closeModals } from './BaseModal'; import { openSwUserModal } from './SWUserModal'; import { createIcons, History, Plus, X, Save, Edit2, RotateCcw, Calendar } from 'lucide'; import { CORP_LIST } from './SharedData'; import { generateOptionsHTML, setFieldValue, getFieldValue, setEditLock, applyDateMask } from './ModalUtils'; let currentSwAsset: SoftwareAsset | null = null; let isEditMode = false; const SW_MODAL_HTML = ` `; function applySwTypeUI(type: string) { const cloudFields = document.querySelectorAll('.cloud-only'); const swFields = document.querySelectorAll('.sw-standard-field'); const userSection = document.getElementById('sw-user-section'); const keyGroup = document.getElementById('sw-license-key-group'); const typeGroup = document.getElementById('sw-license-type-group'); const expiryGroup = document.getElementById('sw-expiry-group'); if (type === '클라우드') { cloudFields.forEach(el => (el as HTMLElement).style.display = 'flex'); swFields.forEach(el => (el as HTMLElement).style.display = 'none'); if (userSection) userSection.style.display = 'none'; } else { cloudFields.forEach(el => (el as HTMLElement).style.display = 'none'); swFields.forEach(el => (el as HTMLElement).style.display = 'flex'); if (userSection) userSection.style.display = 'block'; if (type === '구독SW') { if (keyGroup) keyGroup.style.display = 'none'; if (typeGroup) typeGroup.style.display = 'flex'; if (expiryGroup) expiryGroup.style.display = 'flex'; } else { if (keyGroup) keyGroup.style.display = 'flex'; if (typeGroup) typeGroup.style.display = 'none'; if (expiryGroup) expiryGroup.style.display = 'flex'; } } } function fillSwFormData(asset: SoftwareAsset) { setFieldValue('sw-asset-id', asset.id); setFieldValue('sw-asset-type', asset.type); setFieldValue('sw-분야', asset.분야 || '업무공통'); setFieldValue('sw-법인', asset.법인); setFieldValue('sw-자산번호', asset.자산번호 || ''); setFieldValue('sw-부서', asset.부서 || ''); setFieldValue('sw-제품명', asset.제품명); setFieldValue('sw-수량', asset.수량); setFieldValue('sw-금액', asset.금액); setFieldValue('sw-구매일', asset.구매일 || ''); setFieldValue('sw-시작일', asset.시작일 || ''); setFieldValue('sw-납품업체', asset.납품업체 || ''); setFieldValue('sw-비고', asset.비고 || ''); if (asset.type === '클라우드') { setFieldValue('sw-플랫폼명', (asset as any).플랫폼명 || ''); setFieldValue('sw-계정명', (asset as any).계정명 || ''); setFieldValue('sw-결제수단', (asset as any).결제수단 || ''); setFieldValue('sw-연결카드번호', (asset as any).연결카드번호 || ''); setFieldValue('sw-결제일', (asset as any).결제일 || ''); setFieldValue('sw-당월청구액', (asset as any).당월청구액 || ''); } else if (asset.type === '구독SW') { setFieldValue('sw-라이선스유형', (asset as any).라이선스유형 || ''); setFieldValue('sw-만료일', (asset as any).만료일 || ''); } else { setFieldValue('sw-라이선스키', (asset as any).라이선스키 || ''); } renderUserSummary(asset.id); renderSwHistory(asset.id); } function renderUserSummary(swId: string) { const container = document.getElementById('sw-assigned-users-summary'); if (!container) return; const userMapping = state.masterData.swUsers.find(u => u.sw_id === swId); if (!userMapping || !userMapping.userData || userMapping.userData.length === 0) { container.innerHTML = '
할당된 사용자가 없습니다.
'; return; } container.innerHTML = userMapping.userData.map(u => `
${u[3] || '이름없음'} ${u[1] || '부서없음'}
`).join(''); } function renderSwHistory(swId: string) { const container = document.getElementById('sw-history-list'); if (!container) return; const logs = (state.masterData.logs || []).filter(l => l.assetId === swId); if (logs.length === 0) { container.innerHTML = '
수정 이력이 없습니다.
'; return; } container.innerHTML = logs.map(l => `
${l.date}
${l.user}
${l.details}
`).join(''); } export function openSwModal(asset: SoftwareAsset, mode: 'view' | 'add' | 'edit' = 'view') { currentSwAsset = asset; const modal = document.getElementById('sw-asset-modal')!; // 수정 잠금 상태 제어 setEditLock('sw-asset-form', mode, { saveBtnId: 'btn-save-sw-asset', revertBtnId: 'btn-revert-sw-edit' }); isEditMode = (mode === 'add' || mode === 'edit'); fillSwFormData(asset); applySwTypeUI(asset.type); modal.classList.remove('hidden'); createIcons({ icons: { X, History, Plus } }); } export function initSwModal(onSave: () => void, closeModals: () => void) { if (!document.getElementById('sw-asset-modal')) { document.body.insertAdjacentHTML('beforeend', SW_MODAL_HTML); } const form = document.getElementById('sw-asset-form') as HTMLFormElement; const saveBtn = document.getElementById('btn-save-sw-asset')!; const revertBtn = document.getElementById('btn-revert-sw-edit')!; const deleteBtn = document.getElementById('btn-delete-sw-asset')!; const userAssignBtn = document.getElementById('btn-open-sw-user')!; const btnOpenUpdate = document.getElementById('btn-open-sw-update')!; // 날짜 스마트 마스킹 적용 ['sw-구매일', 'sw-시작일', 'sw-만료일', 'sw-update-start', 'sw-update-end'].forEach(id => { applyDateMask(document.getElementById(id) as HTMLInputElement); }); createIcons({ icons: { Calendar } }); const closeModalAction = () => { closeModals(); isEditMode = false; }; document.getElementById('btn-close-sw-modal')?.addEventListener('click', closeModalAction); document.getElementById('btn-cancel-sw-modal')?.addEventListener('click', closeModalAction); revertBtn.addEventListener('click', () => { setEditLock('sw-asset-form', 'view', { saveBtnId: 'btn-save-sw-asset', revertBtnId: 'btn-revert-sw-edit' }); isEditMode = false; if (currentSwAsset) fillSwFormData(currentSwAsset); }); saveBtn.addEventListener('click', () => { if (!currentSwAsset) return; if (!isEditMode) { setEditLock('sw-asset-form', 'edit', { saveBtnId: 'btn-save-sw-asset', revertBtnId: 'btn-revert-sw-edit' }); isEditMode = true; return; } const type = getFieldValue('sw-asset-type'); const updated: any = { ...currentSwAsset, 분야: getFieldValue('sw-분야'), 법인: getFieldValue('sw-법인'), 부서: getFieldValue('sw-부서'), 자산번호: getFieldValue('sw-자산번호'), 제품명: getFieldValue('sw-제품명'), 수량: parseInt(getFieldValue('sw-수량') || '0'), 금액: getFieldValue('sw-금액'), 구매일: getFieldValue('sw-구매일'), 시작일: getFieldValue('sw-시작일'), 납품업체: getFieldValue('sw-납품업체'), 비고: getFieldValue('sw-비고'), type: type }; if (type === '클라우드') { updated.플랫폼명 = getFieldValue('sw-플랫폼명'); updated.계정명 = getFieldValue('sw-계정명'); updated.결제수단 = getFieldValue('sw-결제수단'); updated.연결카드번호 = getFieldValue('sw-연결카드번호'); updated.결제일 = getFieldValue('sw-결제일'); updated.당월청구액 = getFieldValue('sw-당월청구액'); } else if (type === '구독SW') { updated.라이선스유형 = getFieldValue('sw-라이선스유형'); updated.만료일 = getFieldValue('sw-만료일'); } else { updated.라이선스키 = getFieldValue('sw-라이선스키'); } // 데이터 저장 로직 (state 업데이트) let targetList: SoftwareAsset[] = []; if (type === '구독SW') targetList = state.masterData.subSw; else if (type === '영구SW') targetList = state.masterData.permSw; else if (type === '클라우드') targetList = state.masterData.cloud; const idx = targetList.findIndex(a => a.id === updated.id); if (idx > -1) targetList[idx] = updated; else targetList.push(updated); onSave(); setEditLock('sw-asset-form', 'view', { saveBtnId: 'btn-save-sw-asset', revertBtnId: 'btn-revert-sw-edit' }); isEditMode = false; }); deleteBtn.addEventListener('click', () => { if (!currentSwAsset) return; if (confirm('삭제하시겠습니까?')) { const type = currentSwAsset.type; if (type === '구독SW') state.masterData.subSw = state.masterData.subSw.filter(a => a.id !== currentSwAsset!.id); else if (type === '영구SW') state.masterData.permSw = state.masterData.permSw.filter(a => a.id !== currentSwAsset!.id); else if (type === '클라우드') state.masterData.cloud = state.masterData.cloud.filter(a => a.id !== currentSwAsset!.id); onSave(); closeModalAction(); } }); userAssignBtn.addEventListener('click', () => { if (currentSwAsset) openSwUserModal(currentSwAsset); }); // 자산 업데이트(계약 갱신) 모달 로직 const subModal = document.getElementById('sw-update-modal')!; const btnCloseUpdate = document.getElementById('btn-close-sw-update')!; const btnCancelUpdate = document.getElementById('btn-cancel-sw-update')!; const btnSaveUpdate = document.getElementById('btn-save-sw-update')!; const closeUpdateModal = () => subModal.classList.add('hidden'); btnCloseUpdate?.addEventListener('click', closeUpdateModal); btnCancelUpdate?.addEventListener('click', closeUpdateModal); btnOpenUpdate?.addEventListener('click', (e) => { e.preventDefault(); if (!isEditMode) { alert('자산을 수정 모드로 변경한 후 업데이트를 진행해주세요.'); return; } const isSub = getFieldValue('sw-asset-type') === '구독SW'; subModal.classList.remove('hidden'); (document.getElementById('sw-update-date') as HTMLInputElement).value = new Date().toISOString().substring(0, 10); (document.getElementById('sw-update-start') as HTMLInputElement).value = ''; (document.getElementById('sw-update-end') as HTMLInputElement).value = ''; (document.getElementById('sw-update-cost') as HTMLInputElement).value = ''; (document.getElementById('sw-update-note') as HTMLInputElement).value = ''; if (isSub) { document.querySelector('.sub-sw-update')!.setAttribute('style', 'display:flex; flex-direction:column;'); document.querySelector('.perm-sw-update')!.setAttribute('style', 'display:none'); } else { document.querySelector('.sub-sw-update')!.setAttribute('style', 'display:none'); document.querySelector('.perm-sw-update')!.setAttribute('style', 'display:flex; flex-direction:column;'); (document.getElementById('sw-update-maintenance') as HTMLInputElement).checked = (document.getElementById('sw-유지보수여부') as HTMLInputElement).checked; } }); btnSaveUpdate?.addEventListener('click', (e) => { e.preventDefault(); const isSub = getFieldValue('sw-asset-type') === '구독SW'; const date = (document.getElementById('sw-update-date') as HTMLInputElement).value; const start = (document.getElementById('sw-update-start') as HTMLInputElement).value; const end = (document.getElementById('sw-update-end') as HTMLInputElement).value; const maintenance = (document.getElementById('sw-update-maintenance') as HTMLInputElement).checked; const cost = (document.getElementById('sw-update-cost') as HTMLInputElement).value; const note = (document.getElementById('sw-update-note') as HTMLInputElement).value; const periodStr = (start || end) ? `${start || ''} ~ ${end || ''}` : ''; let details = `[업데이트] ${note || (isSub ? '구독 갱신' : '유지보수 갱신')}\n`; if (cost) details += `비용 추가: ${cost}원\n`; if (isSub) { if (periodStr) details += `계약 변경: -> ${periodStr}\n`; // 메인 폼에 시작일 만료일 자동 세팅 if (start) setFieldValue('sw-시작일', start); if (end) setFieldValue('sw-만료일', end); } else { details += `유지보수 상태: -> ${maintenance ? '유효' : '만료'}\n`; (document.getElementById('sw-유지보수여부') as HTMLInputElement).checked = maintenance; } // 금액 갱신 (선택사항) if (cost) setFieldValue('sw-금액', cost); // 이력 탭 갱신 (메모리상) if (!state.masterData.logs) state.masterData.logs = []; state.masterData.logs.push({ id: Math.random().toString(36).substring(2, 9), assetId: currentSwAsset ? currentSwAsset.id : 'NEW', date, details, user: '관리자' }); closeUpdateModal(); renderSwHistory(currentSwAsset ? currentSwAsset.id : ''); }); }