Files
HRM-System/rollback_and_resync.php

111 lines
4.7 KiB
PHP

<?php
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();
use Illuminate\Support\Facades\DB;
use App\Models\Employee;
use App\Models\BiometricAttendance;
use App\Models\AttendanceRecord;
use App\Models\Shift;
use App\Models\AttendancePolicy;
use App\Http\Controllers\BiometricAttendanceController;
DB::transaction(function() {
echo "=== 1. Rolling back raw punch times by -8 hours ===\n";
DB::statement("UPDATE biometric_attendances SET punch_time = DATE_SUB(punch_time, INTERVAL 8 HOUR)");
// Remove the migration record since we rolled it back
DB::table('migrations')->where('migration', '2026_05_30_030000_fix_biometric_timezone_offset')->delete();
echo "Punches successfully restored to their original local times.\n\n";
echo "=== 2. Re-processing and Syncing Attendance Records with Correct Times ===\n";
// Fetch all biometric attendances
$allBioRecords = BiometricAttendance::all();
$empIds = $allBioRecords->pluck('biometric_emp_id')->unique();
$employees = Employee::with(['user', 'shift'])
->whereIn('biometric_emp_id', $empIds)
->get()
->keyBy('biometric_emp_id');
$grouped = $allBioRecords->groupBy(function ($item) use ($employees) {
$employee = $employees->get($item->biometric_emp_id);
$workDate = BiometricAttendanceController::getWorkDateForPunch($item->punch_time, $employee);
return $item->biometric_emp_id . '_' . $workDate;
});
$updatedCount = 0;
$createdCount = 0;
foreach ($grouped as $key => $dayEntries) {
$sorted = $dayEntries->sortBy('punch_time');
$firstEntry = $sorted->first();
$lastEntry = $sorted->last();
$employee = $employees->get($firstEntry->biometric_emp_id);
if (!$employee) continue;
$workDate = BiometricAttendanceController::getWorkDateForPunch($firstEntry->punch_time, $employee);
$clockInTime = $firstEntry->punch_time->format('H:i:s');
$clockOutTime = $sorted->count() > 1 ? $lastEntry->punch_time->format('H:i:s') : null;
$attendance = AttendanceRecord::where('employee_id', $employee->user_id)
->where('date', $workDate)
->first();
if ($attendance) {
if (empty($attendance->shift_id)) {
$shift = Shift::where('id', $employee->shift_id)->where('status', 'active')->first();
$attendance->shift_id = $shift?->id;
}
if (empty($attendance->attendance_policy_id)) {
$policy = AttendancePolicy::where('id', $employee->attendance_policy_id)->where('status', 'active')->first();
$attendance->attendance_policy_id = $policy?->id;
}
$attendance->biometric_id = $firstEntry->id;
$attendance->branch_id = $firstEntry->branch_id;
$attendance->clock_in = $clockInTime;
$attendance->clock_out = $clockOutTime;
$attendance->save();
$attendance->fresh();
$attendance->processAttendance();
echo "Updated record for Employee User ID {$employee->user_id} ({$employee->user->name}) on Date {$workDate}: In {$clockInTime} | Out " . ($clockOutTime ?? 'NULL') . "\n";
$updatedCount++;
} else {
$shift = Shift::where('id', $employee->shift_id)->where('status', 'active')->first();
$policy = AttendancePolicy::where('id', $employee->attendance_policy_id)->where('status', 'active')->first();
$attendance = new AttendanceRecord();
$attendance->employee_id = $employee->user_id;
$attendance->branch_id = $firstEntry->branch_id;
$attendance->biometric_id = $firstEntry->id;
$attendance->shift_id = $shift?->id;
$attendance->attendance_policy_id = $policy?->id;
$attendance->date = $workDate;
$attendance->clock_in = $clockInTime;
$attendance->clock_out = $clockOutTime;
$attendance->created_by = $employee->user_id;
$attendance->save();
$attendance->fresh();
$attendance->processAttendance();
echo "Created record for Employee User ID {$employee->user_id} ({$employee->user->name}) on Date {$workDate}: In {$clockInTime} | Out " . ($clockOutTime ?? 'NULL') . "\n";
$createdCount++;
}
foreach ($dayEntries as $entry) {
$entry->update(['sync_status' => 'synced']);
}
}
echo "\nRollback & Sync Complete! Created: {$createdCount} | Updated: {$updatedCount}\n";
});