From 2d3412f79a3e9be113ae277f4bad81a25c31a34c Mon Sep 17 00:00:00 2001 From: bereck-work Date: Sun, 21 Dec 2025 10:06:05 +0000 Subject: [PATCH] (Feat-Fix): Fixed attendance system --- backend-deno/routes/attendance.ts | 46 +++++++++++++++++++++---------- src/pages/AllRatesPage.tsx | 6 ++-- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/backend-deno/routes/attendance.ts b/backend-deno/routes/attendance.ts index bd89a34..8f7dcf8 100644 --- a/backend-deno/routes/attendance.ts +++ b/backend-deno/routes/attendance.ts @@ -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( - "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( + "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", " ", ); - 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"], - ); + 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( `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); diff --git a/src/pages/AllRatesPage.tsx b/src/pages/AllRatesPage.tsx index 649243f..1e7cd62 100644 --- a/src/pages/AllRatesPage.tsx +++ b/src/pages/AllRatesPage.tsx @@ -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); }