(Feat-Fix): Fixed attendance system
This commit is contained in:
@@ -157,27 +157,43 @@ router.post(
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there's an active check-in (not yet checked out) for today
|
||||
const activeCheckIn = await db.query<Attendance[]>(
|
||||
"SELECT * FROM attendance WHERE employee_id = ? AND work_date = ? AND status = 'CheckedIn'",
|
||||
// Check if there's any existing attendance record for today
|
||||
const existingRecord = await db.query<Attendance[]>(
|
||||
"SELECT * FROM attendance WHERE employee_id = ? AND work_date = ?",
|
||||
[employeeId, workDate],
|
||||
);
|
||||
|
||||
if (activeCheckIn.length > 0) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "User has an active check-in. Please check out first before checking in again." };
|
||||
return;
|
||||
}
|
||||
|
||||
const checkInTime = new Date().toISOString().slice(0, 19).replace(
|
||||
"T",
|
||||
" ",
|
||||
);
|
||||
|
||||
let recordId: number;
|
||||
|
||||
if (existingRecord.length > 0) {
|
||||
const record = existingRecord[0];
|
||||
|
||||
// If already checked in, don't allow another check-in
|
||||
if (record.status === "CheckedIn") {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "User has an active check-in. Please check out first before checking in again." };
|
||||
return;
|
||||
}
|
||||
|
||||
// If checked out or other status, update the existing record to check in again
|
||||
await db.execute(
|
||||
"UPDATE attendance SET check_in_time = ?, check_out_time = NULL, status = ?, supervisor_id = ? WHERE id = ?",
|
||||
[checkInTime, "CheckedIn", currentUser.id, record.id],
|
||||
);
|
||||
recordId = record.id;
|
||||
} else {
|
||||
// No existing record, create new one
|
||||
const result = await db.execute(
|
||||
"INSERT INTO attendance (employee_id, supervisor_id, check_in_time, work_date, status) VALUES (?, ?, ?, ?, ?)",
|
||||
[employeeId, currentUser.id, checkInTime, workDate, "CheckedIn"],
|
||||
);
|
||||
recordId = result.insertId as number;
|
||||
}
|
||||
|
||||
const newRecord = await db.query<Attendance[]>(
|
||||
`SELECT a.*,
|
||||
@@ -191,10 +207,10 @@ router.post(
|
||||
LEFT JOIN departments d ON e.department_id = d.id
|
||||
LEFT JOIN users c ON e.contractor_id = c.id
|
||||
WHERE a.id = ?`,
|
||||
[result.insertId],
|
||||
[recordId],
|
||||
);
|
||||
|
||||
ctx.response.status = 201;
|
||||
ctx.response.status = existingRecord.length > 0 ? 200 : 201;
|
||||
ctx.response.body = newRecord[0];
|
||||
} catch (error) {
|
||||
console.error("Check in error:", error);
|
||||
|
||||
@@ -45,7 +45,7 @@ export const AllRatesPage: React.FC = () => {
|
||||
setLoading(true);
|
||||
setError("");
|
||||
try {
|
||||
const params: any = {};
|
||||
const params: { departmentId?: number; startDate?: string; endDate?: string } = {};
|
||||
if (filters.departmentId) {
|
||||
params.departmentId = parseInt(filters.departmentId);
|
||||
}
|
||||
@@ -55,8 +55,8 @@ export const AllRatesPage: React.FC = () => {
|
||||
const data = await api.getAllRates(params);
|
||||
setAllRates(data.allRates);
|
||||
setSummary(data.summary);
|
||||
} catch (err: any) {
|
||||
setError(err.message || "Failed to fetch rates");
|
||||
} catch (err: unknown) {
|
||||
setError(err instanceof Error ? err.message : "Failed to fetch rates");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user