199 lines
6.3 KiB
JavaScript
199 lines
6.3 KiB
JavaScript
import express from 'express';
|
|
import db from '../config/database.js';
|
|
import { authenticateToken, authorize } from '../middleware/auth.js';
|
|
|
|
const router = express.Router();
|
|
|
|
// Get contractor rates
|
|
router.get('/', authenticateToken, async (req, res) => {
|
|
try {
|
|
const { contractorId, subDepartmentId } = req.query;
|
|
|
|
let query = `
|
|
SELECT cr.*,
|
|
u.name as contractor_name, u.username as contractor_username,
|
|
sd.name as sub_department_name,
|
|
d.name as department_name
|
|
FROM contractor_rates cr
|
|
JOIN users u ON cr.contractor_id = u.id
|
|
LEFT JOIN sub_departments sd ON cr.sub_department_id = sd.id
|
|
LEFT JOIN departments d ON sd.department_id = d.id
|
|
WHERE 1=1
|
|
`;
|
|
const params = [];
|
|
|
|
if (contractorId) {
|
|
query += ' AND cr.contractor_id = ?';
|
|
params.push(contractorId);
|
|
}
|
|
|
|
if (subDepartmentId) {
|
|
query += ' AND cr.sub_department_id = ?';
|
|
params.push(subDepartmentId);
|
|
}
|
|
|
|
query += ' ORDER BY cr.effective_date DESC, cr.created_at DESC';
|
|
|
|
const [rates] = await db.query(query, params);
|
|
res.json(rates);
|
|
} catch (error) {
|
|
console.error('Get contractor rates error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Get current rate for a contractor + sub-department combination
|
|
router.get('/contractor/:contractorId/current', authenticateToken, async (req, res) => {
|
|
try {
|
|
const { subDepartmentId } = req.query;
|
|
|
|
let query = `
|
|
SELECT cr.*,
|
|
u.name as contractor_name, u.username as contractor_username,
|
|
sd.name as sub_department_name
|
|
FROM contractor_rates cr
|
|
JOIN users u ON cr.contractor_id = u.id
|
|
LEFT JOIN sub_departments sd ON cr.sub_department_id = sd.id
|
|
WHERE cr.contractor_id = ?
|
|
`;
|
|
const params = [req.params.contractorId];
|
|
|
|
if (subDepartmentId) {
|
|
query += ' AND cr.sub_department_id = ?';
|
|
params.push(subDepartmentId);
|
|
}
|
|
|
|
query += ' ORDER BY cr.effective_date DESC LIMIT 1';
|
|
|
|
const [rates] = await db.query(query, params);
|
|
|
|
if (rates.length === 0) {
|
|
return res.status(404).json({ error: 'No rate found for contractor' });
|
|
}
|
|
|
|
res.json(rates[0]);
|
|
} catch (error) {
|
|
console.error('Get current rate error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Set contractor rate (Supervisor or SuperAdmin)
|
|
router.post('/', authenticateToken, authorize('Supervisor', 'SuperAdmin'), async (req, res) => {
|
|
try {
|
|
const { contractorId, subDepartmentId, activity, rate, effectiveDate } = req.body;
|
|
|
|
if (!contractorId || !rate || !effectiveDate) {
|
|
return res.status(400).json({ error: 'Missing required fields (contractorId, rate, effectiveDate)' });
|
|
}
|
|
|
|
// Verify contractor exists
|
|
const [contractors] = await db.query(
|
|
'SELECT * FROM users WHERE id = ? AND role = ?',
|
|
[contractorId, 'Contractor']
|
|
);
|
|
|
|
if (contractors.length === 0) {
|
|
return res.status(404).json({ error: 'Contractor not found' });
|
|
}
|
|
|
|
// Supervisors can only set rates for contractors in their department
|
|
if (req.user.role === 'Supervisor' && contractors[0].department_id !== req.user.departmentId) {
|
|
return res.status(403).json({ error: 'Contractor not in your department' });
|
|
}
|
|
|
|
const [result] = await db.query(
|
|
'INSERT INTO contractor_rates (contractor_id, sub_department_id, activity, rate, effective_date) VALUES (?, ?, ?, ?, ?)',
|
|
[contractorId, subDepartmentId || null, activity || null, rate, effectiveDate]
|
|
);
|
|
|
|
const [newRate] = await db.query(
|
|
`SELECT cr.*,
|
|
u.name as contractor_name, u.username as contractor_username,
|
|
sd.name as sub_department_name
|
|
FROM contractor_rates cr
|
|
JOIN users u ON cr.contractor_id = u.id
|
|
LEFT JOIN sub_departments sd ON cr.sub_department_id = sd.id
|
|
WHERE cr.id = ?`,
|
|
[result.insertId]
|
|
);
|
|
|
|
res.status(201).json(newRate[0]);
|
|
} catch (error) {
|
|
console.error('Set contractor rate error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Update contractor rate
|
|
router.put('/:id', authenticateToken, authorize('Supervisor', 'SuperAdmin'), async (req, res) => {
|
|
try {
|
|
const { rate, activity, effectiveDate } = req.body;
|
|
|
|
const [existing] = await db.query('SELECT * FROM contractor_rates WHERE id = ?', [req.params.id]);
|
|
|
|
if (existing.length === 0) {
|
|
return res.status(404).json({ error: 'Rate not found' });
|
|
}
|
|
|
|
const updates = [];
|
|
const params = [];
|
|
|
|
if (rate !== undefined) {
|
|
updates.push('rate = ?');
|
|
params.push(rate);
|
|
}
|
|
if (activity !== undefined) {
|
|
updates.push('activity = ?');
|
|
params.push(activity);
|
|
}
|
|
if (effectiveDate !== undefined) {
|
|
updates.push('effective_date = ?');
|
|
params.push(effectiveDate);
|
|
}
|
|
|
|
if (updates.length === 0) {
|
|
return res.status(400).json({ error: 'No fields to update' });
|
|
}
|
|
|
|
params.push(req.params.id);
|
|
|
|
await db.query(`UPDATE contractor_rates SET ${updates.join(', ')} WHERE id = ?`, params);
|
|
|
|
const [updatedRate] = await db.query(
|
|
`SELECT cr.*,
|
|
u.name as contractor_name, u.username as contractor_username,
|
|
sd.name as sub_department_name
|
|
FROM contractor_rates cr
|
|
JOIN users u ON cr.contractor_id = u.id
|
|
LEFT JOIN sub_departments sd ON cr.sub_department_id = sd.id
|
|
WHERE cr.id = ?`,
|
|
[req.params.id]
|
|
);
|
|
|
|
res.json(updatedRate[0]);
|
|
} catch (error) {
|
|
console.error('Update contractor rate error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Delete contractor rate
|
|
router.delete('/:id', authenticateToken, authorize('Supervisor', 'SuperAdmin'), async (req, res) => {
|
|
try {
|
|
const [existing] = await db.query('SELECT * FROM contractor_rates WHERE id = ?', [req.params.id]);
|
|
|
|
if (existing.length === 0) {
|
|
return res.status(404).json({ error: 'Rate not found' });
|
|
}
|
|
|
|
await db.query('DELETE FROM contractor_rates WHERE id = ?', [req.params.id]);
|
|
res.json({ message: 'Rate deleted successfully' });
|
|
} catch (error) {
|
|
console.error('Delete contractor rate error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
export default router;
|