124 lines
4.6 KiB
JavaScript
124 lines
4.6 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const express_1 = require("express");
|
|
const prisma_1 = __importDefault(require("../lib/prisma"));
|
|
const auth_1 = require("../middleware/auth");
|
|
const router = (0, express_1.Router)();
|
|
// GET /attendance/today
|
|
router.get('/today', auth_1.requireAuth, async (req, res) => {
|
|
try {
|
|
const employeeId = req.user.employeeId;
|
|
if (!employeeId)
|
|
return res.json(null);
|
|
const today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
const record = await prisma_1.default.attendanceRecord.findUnique({
|
|
where: { employeeId_date: { employeeId, date: today } },
|
|
});
|
|
return res.json(record);
|
|
}
|
|
catch (err) {
|
|
return res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
// POST /attendance/clock-in
|
|
router.post('/clock-in', auth_1.requireAuth, async (req, res) => {
|
|
try {
|
|
const employeeId = req.user.employeeId;
|
|
if (!employeeId)
|
|
return res.status(400).json({ error: 'Employee not found' });
|
|
const today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
const existing = await prisma_1.default.attendanceRecord.findUnique({
|
|
where: { employeeId_date: { employeeId, date: today } },
|
|
});
|
|
if (existing) {
|
|
return res.status(409).json({ error: 'Already clocked in today' });
|
|
}
|
|
const now = new Date();
|
|
const isLate = now.getHours() > 9 || (now.getHours() === 9 && now.getMinutes() > 30);
|
|
const record = await prisma_1.default.attendanceRecord.create({
|
|
data: {
|
|
employeeId,
|
|
date: today,
|
|
clockIn: now,
|
|
status: 'PRESENT',
|
|
isLate,
|
|
},
|
|
});
|
|
return res.status(201).json(record);
|
|
}
|
|
catch (err) {
|
|
return res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
// POST /attendance/clock-out
|
|
router.post('/clock-out', auth_1.requireAuth, async (req, res) => {
|
|
try {
|
|
const employeeId = req.user.employeeId;
|
|
if (!employeeId)
|
|
return res.status(400).json({ error: 'Employee not found' });
|
|
const today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
const existing = await prisma_1.default.attendanceRecord.findUnique({
|
|
where: { employeeId_date: { employeeId, date: today } },
|
|
});
|
|
if (!existing) {
|
|
return res.status(400).json({ error: 'Not clocked in today' });
|
|
}
|
|
if (existing.clockOut) {
|
|
return res.status(409).json({ error: 'Already clocked out' });
|
|
}
|
|
const now = new Date();
|
|
const hoursWorked = existing.clockIn
|
|
? (now.getTime() - existing.clockIn.getTime()) / (1000 * 60 * 60)
|
|
: 0;
|
|
const record = await prisma_1.default.attendanceRecord.update({
|
|
where: { id: existing.id },
|
|
data: { clockOut: now, hoursWorked: parseFloat(hoursWorked.toFixed(2)) },
|
|
});
|
|
return res.json(record);
|
|
}
|
|
catch (err) {
|
|
return res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
// GET /attendance
|
|
router.get('/', auth_1.requireAuth, async (req, res) => {
|
|
try {
|
|
const { employeeId, startDate, endDate, page = '1', limit = '30' } = req.query;
|
|
const skip = (parseInt(page) - 1) * parseInt(limit);
|
|
const where = {};
|
|
if (req.user.role === 'EMPLOYEE') {
|
|
where.employeeId = req.user.employeeId;
|
|
}
|
|
else if (employeeId) {
|
|
where.employeeId = employeeId;
|
|
}
|
|
if (startDate)
|
|
where.date = { ...where.date, gte: new Date(startDate) };
|
|
if (endDate)
|
|
where.date = { ...where.date, lte: new Date(endDate) };
|
|
const [records, total] = await Promise.all([
|
|
prisma_1.default.attendanceRecord.findMany({
|
|
where,
|
|
skip,
|
|
take: parseInt(limit),
|
|
include: {
|
|
employee: { select: { firstName: true, lastName: true, employeeCode: true } },
|
|
},
|
|
orderBy: { date: 'desc' },
|
|
}),
|
|
prisma_1.default.attendanceRecord.count({ where }),
|
|
]);
|
|
return res.json({ data: records, total });
|
|
}
|
|
catch (err) {
|
|
return res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
exports.default = router;
|
|
//# sourceMappingURL=attendance.js.map
|