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