Files
2026-06-11 11:46:12 -04:00

119 lines
3.6 KiB
PHP

<?php
namespace App\Services\BadgeScan;
use App\Controllers\View\RFIDController;
use App\Models\Configuration;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
/**
* legacy {@see RFIDController} parity (badge scan + log listing).
*/
class BadgeScanService
{
private const LOG_LIMIT = 500;
/**
* @return array{recognized: bool, message: string, user_id?: int, display_name?: string}
*/
public function processScan(string $badgeScan, ?string $schoolYear = null, ?string $semester = null): array
{
$tag = trim($badgeScan);
if ($tag === '') {
return [
'recognized' => false,
'message' => 'Badge scan value is required.',
];
}
if (! Schema::hasTable('scan_log')) {
return [
'recognized' => false,
'message' => 'Scan logging is not available.',
];
}
$user = User::query()->where('rfid_tag', $tag)->first();
if (! $user) {
return [
'recognized' => false,
'message' => 'Badge scan not recognized.',
];
}
$displayName = trim(($user->firstname ?? '').' '.($user->lastname ?? ''));
if ($displayName === '') {
$displayName = $user->email ?? ('User #'.$user->id);
}
DB::table('scan_log')->insert([
'user_id' => $user->id,
'card_id' => $tag,
'scan_time' => now(),
'school_year' => $schoolYear ?: Configuration::getConfigValueByKey('school_year'),
'semester' => $semester ?: Configuration::getConfigValueByKey('semester'),
]);
return [
'recognized' => true,
'message' => 'Badge recognized: '.$displayName,
'user_id' => (int) $user->id,
'display_name' => $displayName,
];
}
/**
* Scan log listing (legacy RFIDController::log() query shape).
*
* @return list<array<string, mixed>>
*/
public function scanLogRows(?string $schoolYear = null, ?string $semester = null): array
{
if (! Schema::hasTable('scan_log')) {
return [];
}
$query = DB::table('scan_log')
->select([
'scan_log.id',
'scan_log.user_id',
'scan_log.card_id',
'scan_log.scan_time',
'scan_log.school_year',
'scan_log.semester',
'users.firstname as user_firstname',
'users.lastname as user_lastname',
'students.firstname as student_firstname',
'students.lastname as student_lastname',
])
->leftJoin('users', 'users.id', '=', 'scan_log.user_id')
->leftJoin('students', 'students.rfid_tag', '=', 'scan_log.card_id');
if ($schoolYear !== null && trim($schoolYear) !== '') {
$query->where('scan_log.school_year', trim($schoolYear));
}
if ($semester !== null && trim($semester) !== '') {
$query->where('scan_log.semester', trim($semester));
}
return $query
->orderByDesc('scan_log.scan_time')
->limit(self::LOG_LIMIT)
->get()
->map(function ($row) {
$r = (array) $row;
foreach (['scan_time'] as $k) {
if (isset($r[$k]) && $r[$k] !== null && ! is_string($r[$k])) {
$r[$k] = (string) $r[$k];
}
}
return $r;
})
->all();
}
}