const { getPool } = require('../middleware/auth'); const vacationRequestModel = { async create(data) { const db = getPool(); const [result] = await db.query('INSERT INTO sp_vacation_requests SET ?', data); return result; }, async getAll(filters = {}) { const db = getPool(); let query = ` SELECT vr.*, su.name as user_name, su.username, vt.type_name as vacation_type_name, vt.type_code, reviewer.name as reviewer_name FROM sp_vacation_requests vr INNER JOIN sso_users su ON vr.user_id = su.user_id INNER JOIN vacation_types vt ON vr.vacation_type_id = vt.id LEFT JOIN sso_users reviewer ON vr.reviewed_by = reviewer.user_id WHERE 1=1 `; const params = []; if (filters.user_id) { query += ' AND vr.user_id = ?'; params.push(filters.user_id); } if (filters.status) { query += ' AND vr.status = ?'; params.push(filters.status); } if (filters.start_date) { query += ' AND vr.start_date >= ?'; params.push(filters.start_date); } if (filters.end_date) { query += ' AND vr.end_date <= ?'; params.push(filters.end_date); } if (filters.vacation_type_id) { query += ' AND vr.vacation_type_id = ?'; params.push(filters.vacation_type_id); } query += ' ORDER BY vr.created_at DESC'; const [rows] = await db.query(query, params); return rows; }, async getById(requestId) { const db = getPool(); const [rows] = await db.query(` SELECT vr.*, su.name as user_name, su.username, vt.type_name as vacation_type_name, vt.type_code, reviewer.name as reviewer_name FROM sp_vacation_requests vr INNER JOIN sso_users su ON vr.user_id = su.user_id INNER JOIN vacation_types vt ON vr.vacation_type_id = vt.id LEFT JOIN sso_users reviewer ON vr.reviewed_by = reviewer.user_id WHERE vr.request_id = ? `, [requestId]); return rows; }, async update(requestId, data) { const db = getPool(); const [result] = await db.query('UPDATE sp_vacation_requests SET ? WHERE request_id = ?', [data, requestId]); return result; }, async updateStatus(requestId, statusData) { const db = getPool(); const [result] = await db.query(` UPDATE sp_vacation_requests SET status = ?, reviewed_by = ?, reviewed_at = NOW(), review_note = ? WHERE request_id = ? `, [statusData.status, statusData.reviewed_by, statusData.review_note || null, requestId]); return result; }, async checkOverlap(userId, startDate, endDate, excludeRequestId = null) { const db = getPool(); let query = ` SELECT COUNT(*) as count FROM sp_vacation_requests WHERE user_id = ? AND status IN ('pending', 'approved') AND start_date <= ? AND end_date >= ? `; const params = [userId, endDate, startDate]; if (excludeRequestId) { query += ' AND request_id != ?'; params.push(excludeRequestId); } const [rows] = await db.query(query, params); return rows; }, async getAllPending() { const db = getPool(); const [rows] = await db.query(` SELECT vr.*, su.name as user_name, su.username, vt.type_name as vacation_type_name, vt.type_code FROM sp_vacation_requests vr INNER JOIN sso_users su ON vr.user_id = su.user_id INNER JOIN vacation_types vt ON vr.vacation_type_id = vt.id WHERE vr.status = 'pending' ORDER BY vr.created_at ASC `); return rows; }, async runMigration() { const db = getPool(); const fs = require('fs'); const path = require('path'); const sqlFile = path.join(__dirname, '..', 'db', 'migrations', '001_create_sp_tables.sql'); const sql = fs.readFileSync(sqlFile, 'utf8'); const statements = sql.split(';').map(s => s.trim()).filter(s => s.length > 0); for (const stmt of statements) { try { await db.query(stmt); } catch (err) { if (err.code === 'ER_DUP_FIELDNAME' || err.code === 'ER_TABLE_EXISTS_ERROR') { // Already migrated } else { throw err; } } } console.log('[tksupport] Migration completed'); } }; module.exports = vacationRequestModel;