const { getDb } = require('../dbPool'); // 날짜 형식 변환 헬퍼 함수 (ISO 8601 -> MySQL DATE) const formatDate = (dateStr) => { if (!dateStr) return null; if (typeof dateStr === 'string' && dateStr.includes('T')) { return dateStr.split('T')[0]; // ISO 8601 -> YYYY-MM-DD } return dateStr; }; // 1. 작업자 생성 const create = async (worker) => { const db = await getDb(); const { worker_name, job_type = null, join_date = null, salary = null, annual_leave = null, status = 'active', employment_status = 'employed', department_id = null } = worker; const [result] = await db.query( `INSERT INTO workers (worker_name, job_type, join_date, salary, annual_leave, status, employment_status, department_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [worker_name, job_type, formatDate(join_date), salary, annual_leave, status, employment_status, department_id] ); return result.insertId; }; // 2. 전체 조회 const getAll = async () => { const db = await getDb(); const [rows] = await db.query(` SELECT w.*, w.user_id, CASE WHEN w.status = 'active' THEN 1 ELSE 0 END AS is_active, su.username, d.department_name FROM workers w LEFT JOIN sso_users su ON w.user_id = su.user_id LEFT JOIN departments d ON w.department_id = d.department_id ORDER BY w.worker_name ASC `); return rows; }; // 3. 단일 조회 (worker_id 기준 - 하위 호환성 유지) const getById = async (worker_id) => { const db = await getDb(); const [rows] = await db.query(` SELECT w.*, w.user_id, CASE WHEN w.status = 'active' THEN 1 ELSE 0 END AS is_active, su.username, d.department_name FROM workers w LEFT JOIN sso_users su ON w.user_id = su.user_id LEFT JOIN departments d ON w.department_id = d.department_id WHERE w.worker_id = ? `, [worker_id]); return rows[0]; }; // 3-1. 단일 조회 (user_id 기준) const getByUserId = async (userId) => { const db = await getDb(); const [rows] = await db.query(` SELECT w.*, w.user_id, CASE WHEN w.status = 'active' THEN 1 ELSE 0 END AS is_active, su.username, d.department_name FROM workers w LEFT JOIN sso_users su ON w.user_id = su.user_id LEFT JOIN departments d ON w.department_id = d.department_id WHERE w.user_id = ? `, [userId]); return rows[0]; }; // 4. 작업자 수정 (worker_id 또는 user_id 기준) const update = async (worker) => { const db = await getDb(); const { worker_id, user_id, worker_name, job_type, status, join_date, salary, annual_leave, employment_status, department_id } = worker; // 업데이트할 필드만 동적으로 구성 const updates = []; const values = []; if (worker_name !== undefined) { updates.push('worker_name = ?'); values.push(worker_name); } if (job_type !== undefined) { updates.push('job_type = ?'); values.push(job_type); } if (status !== undefined) { updates.push('status = ?'); values.push(status); } if (join_date !== undefined) { updates.push('join_date = ?'); values.push(formatDate(join_date)); } if (salary !== undefined) { updates.push('salary = ?'); values.push(salary); } if (annual_leave !== undefined) { updates.push('annual_leave = ?'); values.push(annual_leave); } if (employment_status !== undefined) { updates.push('employment_status = ?'); values.push(employment_status); } if (department_id !== undefined) { updates.push('department_id = ?'); values.push(department_id); } if (updates.length === 0) { throw new Error('업데이트할 필드가 없습니다'); } // WHERE 조건: user_id 우선, 없으면 worker_id 사용 let whereClause; if (user_id !== undefined) { whereClause = 'user_id = ?'; values.push(user_id); } else if (worker_id !== undefined) { whereClause = 'worker_id = ?'; values.push(worker_id); } else { throw new Error('worker_id 또는 user_id가 필요합니다'); } const query = `UPDATE workers SET ${updates.join(', ')} WHERE ${whereClause}`; console.log('실행할 SQL:', query); console.log('SQL 파라미터:', values); const [result] = await db.query(query, values); return result.affectedRows; }; // 5. 삭제 (user_id 기반 - 외래키 제약조건 처리) const remove = async (userId) => { const db = await getDb(); const conn = await db.getConnection(); try { await conn.beginTransaction(); console.log(`🗑️ 작업자 삭제 시작: user_id=${userId}`); // 안전한 삭제: 각 테이블을 개별적으로 처리하고 오류가 발생해도 계속 진행 const tables = [ { name: 'DailyIssueReports', query: 'DELETE FROM DailyIssueReports WHERE user_id = ?', action: '삭제' }, { name: 'WorkReports', query: 'DELETE FROM WorkReports WHERE user_id = ?', action: '삭제' }, { name: 'daily_work_reports', query: 'DELETE FROM daily_work_reports WHERE user_id = ?', action: '삭제' }, { name: 'daily_attendance_records', query: 'DELETE FROM daily_attendance_records WHERE user_id = ?', action: '삭제' }, { name: 'daily_worker_summary', query: 'DELETE FROM daily_worker_summary WHERE user_id = ?', action: '삭제' }, { name: 'tbm_team_assignments', query: 'DELETE FROM tbm_team_assignments WHERE user_id = ?', action: '삭제' }, { name: 'tbm_transfers', query: 'DELETE FROM tbm_transfers WHERE user_id = ?', action: '삭제' }, { name: 'vacation_requests', query: 'DELETE FROM vacation_requests WHERE user_id = ?', action: '삭제' }, { name: 'vacation_balance_details', query: 'DELETE FROM vacation_balance_details WHERE user_id = ?', action: '삭제' }, { name: 'worker_vacation_balance', query: 'DELETE FROM worker_vacation_balance WHERE user_id = ?', action: '삭제' }, { name: 'worker_groups', query: 'DELETE FROM worker_groups WHERE user_id = ?', action: '삭제' } ]; for (const table of tables) { try { const [result] = await conn.query(table.query, [userId]); if (result.affectedRows > 0) { console.log(`✅ ${table.name} 테이블 ${table.action}: ${result.affectedRows}건`); } } catch (tableError) { console.log(`⚠️ ${table.name} 테이블 ${table.action} 실패 (무시): ${tableError.message}`); } } // 마지막으로 작업자 삭제 const [result] = await conn.query( `DELETE FROM workers WHERE user_id = ?`, [userId] ); console.log(`✅ 작업자 삭제 완료: ${result.affectedRows}건`); await conn.commit(); return result.affectedRows; } catch (err) { await conn.rollback(); console.error(`❌ 작업자 삭제 오류 (user_id: ${userId}):`, err); throw new Error(`작업자 삭제 중 오류가 발생했습니다: ${err.message}`); } finally { conn.release(); } }; module.exports = { create, getAll, getById, getByUserId, update, remove };