Files
HRM-System/app/Console/Commands/SyncLegacyDailyShifts.php

139 lines
5.1 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\User;
use App\Models\AttendanceRecord;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
class SyncLegacyDailyShifts extends Command
{
protected $signature = 'import:legacy-shifts {start_date?} {end_date?}';
protected $description = 'Sweeps legacy employee_daily_shifts to synchronize proper working/rest day tracking into the core attendance engine natively.';
public function handle()
{
$startDate = $this->argument('start_date') ?: '2026-01-11';
$endDate = $this->argument('end_date') ?: '2026-01-25';
$this->info("Initializing Legacy Shift Matrix Sync: $startDate to $endDate");
$employees = User::where('type', 'employee')->whereHas('employee')->get();
$bar = $this->output->createProgressBar(count($employees));
$legacyUsers = DB::connection('legacy')->table('users')->get(['id', 'name']);
$newUserIdMap = [];
foreach ($legacyUsers as $lu) {
$matchingLocal = User::where('name', $lu->name)->first();
if ($matchingLocal) {
$newUserIdMap[$matchingLocal->id] = $lu->id;
}
}
$synced = 0;
$patterned = 0;
foreach ($employees as $user) {
if (!isset($newUserIdMap[$user->id])) {
$bar->advance();
continue;
}
$legacyUserId = $newUserIdMap[$user->id];
// Check if legacy has data for the requested date range
$hasDirectData = DB::connection('legacy')
->table('employee_daily_shifts')
->where('user_id', $legacyUserId)
->whereBetween('date', [$startDate, $endDate])
->exists();
// Build a 7-day pattern from their last known week if no direct data
$weeklyPattern = null;
if (!$hasDirectData) {
$lastRecords = DB::connection('legacy')
->table('employee_daily_shifts')
->where('user_id', $legacyUserId)
->orderByDesc('date')
->limit(7)
->get();
if ($lastRecords->isNotEmpty()) {
// Build pattern keyed by day-of-week (0=Sunday, 6=Saturday)
$weeklyPattern = [];
foreach ($lastRecords as $rec) {
$dow = Carbon::parse($rec->date)->dayOfWeek;
$weeklyPattern[$dow] = $rec->shift_id;
}
$this->line("{$user->name}: No legacy data for range. Repeating last known weekly pattern.");
}
}
$currentDate = Carbon::parse($startDate);
$periodEndObj = Carbon::parse($endDate);
while ($currentDate->lte($periodEndObj)) {
$dateString = $currentDate->toDateString();
$shiftId = null;
$isRestDay = true;
if ($hasDirectData) {
// Direct lookup from legacy DB
$shiftRecord = DB::connection('legacy')
->table('employee_daily_shifts')
->where('user_id', $legacyUserId)
->where('date', $dateString)
->first();
$isRestDay = (!$shiftRecord || empty($shiftRecord->shift_id));
$shiftId = $shiftRecord->shift_id ?? null;
} elseif ($weeklyPattern !== null) {
// Use the repeating weekly pattern
$dow = $currentDate->dayOfWeek;
$shiftId = $weeklyPattern[$dow] ?? null;
$isRestDay = empty($shiftId);
}
if ($isRestDay) {
AttendanceRecord::updateOrCreate(
[
'employee_id' => $user->id,
'date' => $dateString
],
[
'is_rest_day' => true,
'is_absent' => false,
'status' => 'present',
'created_by' => 1,
'shift_id' => null
]
);
} else {
AttendanceRecord::updateOrCreate(
[
'employee_id' => $user->id,
'date' => $dateString
],
[
'is_rest_day' => false,
'shift_id' => $shiftId,
'created_by' => 1
]
);
}
$hasDirectData ? $synced++ : $patterned++;
$currentDate->addDay();
}
$bar->advance();
}
$bar->finish();
$this->info("\nMatrix Sync Complete. Direct synced: {$synced} | Pattern-filled: {$patterned}");
}
}