3.5 KiB
3.5 KiB
PLAN: Shift-Aware Biometric Routing and Double-Punch Protection
This plan documents the integration of shift-aware punch classification (In/Out routing for single punches) and the prevention of duplicate check-ins (double-punch filtering).
🏗️ Target Files
- Backend Controller:
app/Http/Controllers/BiometricAttendanceController.php - Frontend UI Page:
resources/js/pages/hr/biometric-attendance/index.tsx
🛠️ Proposed Implementation Steps
Phase 1: Main Dashboard UI Updates (Frontend)
Modify index.tsx:
- Remove the
Total Entriescolumn from thecolumnsarray. - Ensure the table renders clean and responsive rows without the total entries column.
Phase 2: Double-Punch Filtering Logic (Backend)
Modify BiometricAttendanceController.php:
- Add a helper method to filter out raw punches occurring within 60 seconds of the previous valid punch:
private static function filterDoublePunches($dayEntries) { $sorted = $dayEntries->sortBy('punch_time'); $filtered = collect(); foreach ($sorted as $entry) { if ($filtered->isEmpty()) { $filtered->push($entry); } else { $lastValid = $filtered->last(); $diffInSeconds = $entry->punch_time->diffInSeconds($lastValid->punch_time); if ($diffInSeconds > 60) { $filtered->push($entry); } } } return $filtered; }
Phase 3: Shift-Aware Single Punch Routing (Backend)
Modify BiometricAttendanceController.php:
- Refactor the grouping map in
indexand the processing loop insyncAllto:- Filter out double-punches first using
filterDoublePunches. - If the remaining entries count is exactly 1:
- Check if the employee has a shift.
- If so, calculate the expected shift
start_timeandend_time(accounting for night shifts) on that work date. - Calculate the distance from the punch to the shift start and shift end.
- If the punch is closer to the shift end time, set
clock_outas the punch time, andclock_inasnull(or-). - Otherwise, set
clock_inas the punch time, andclock_outasnull. - If no shift is found, default to treating the single punch as
clock_in.
- If the remaining entries count is 2 or more:
- Treat the earliest punch as
clock_inand the latest asclock_out.
- Treat the earliest punch as
- Filter out double-punches first using
🏁 Verification Checklist
- Verify Column Removal: Open the main biometric attendance page and check that the "Total Entries" column is removed.
- Verify Double-Punch Filtering: Push mock data containing two punches for the same employee 30 seconds apart (e.g.
08:30:00and08:30:30). Verify that the dashboard groups this as a single punch at08:30:00and treats it as a Clock In. - Verify Shift-Aware Routing (Clock In): Push a single punch at
08:45:00for an employee with a09:00 - 18:00shift. Verify that the system assigns it as Clock In. - Verify Shift-Aware Routing (Clock Out): Push a single punch at
17:45:00for the same employee. Verify that the system assigns it as Clock Out and leaves Clock In blank. - Vite compilation: Run
npm run buildto verify React compilation. - PHP syntax check: Run
php -lon the controller.