139 lines
5.1 KiB
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}");
|
|
}
|
|
}
|