fix tests
This commit is contained in:
@@ -23,12 +23,13 @@ use Illuminate\Support\Facades\Schema;
|
||||
class ScannerController extends BaseApiController
|
||||
{
|
||||
private const LATE_CUTOFF_CONFIG_KEY = 'attendance_late_cutoff_time';
|
||||
|
||||
private const DEFAULT_LATE_CUTOFF = '10:00 AM';
|
||||
|
||||
public function process(Request $request): JsonResponse
|
||||
{
|
||||
$data = $request->json()->all();
|
||||
if (!is_array($data) || $data === []) {
|
||||
if (! is_array($data) || $data === []) {
|
||||
$data = $request->all();
|
||||
}
|
||||
|
||||
@@ -41,10 +42,11 @@ class ScannerController extends BaseApiController
|
||||
|
||||
if ($badgeCode === '') {
|
||||
$this->logScan($badgeCode, null, null, $action, 'rejected', $operatorId, $stationId, 'Badge code is required.', $scannedAt);
|
||||
|
||||
return response()->json($this->failure('Badge code is required.'), 400);
|
||||
}
|
||||
|
||||
if (!in_array($scanStatus, ['present', 'late'], true)) {
|
||||
if (! in_array($scanStatus, ['present', 'late'], true)) {
|
||||
$scanStatus = 'present';
|
||||
}
|
||||
|
||||
@@ -59,6 +61,7 @@ class ScannerController extends BaseApiController
|
||||
}
|
||||
|
||||
$this->logScan($badgeCode, null, null, $action, 'not_found', $operatorId, $stationId, 'Badge not found.', $scannedAt);
|
||||
|
||||
return response()->json($this->failure('Badge not found.'), 404);
|
||||
}
|
||||
|
||||
@@ -74,8 +77,9 @@ class ScannerController extends BaseApiController
|
||||
}
|
||||
|
||||
$assignment = $this->studentAssignment((int) $student->id, $term['semester'], $term['school_year']);
|
||||
if (!$assignment) {
|
||||
if (! $assignment) {
|
||||
$this->logScan($badgeCode, 'student', (int) $student->id, $action, 'rejected', $operatorId, $stationId, 'Student has no class assignment for current term.', $scannedAt);
|
||||
|
||||
return response()->json($this->failure('Student has no class assignment for current term.'), 409);
|
||||
}
|
||||
|
||||
@@ -150,7 +154,7 @@ class ScannerController extends BaseApiController
|
||||
$operatorId,
|
||||
$existing ? (string) ($oldStatus ?? '') : null
|
||||
);
|
||||
$warnings[] = 'Student arrived after ' . $lateCutoff->format('h:i A') . '. Late slip receipt generated.';
|
||||
$warnings[] = 'Student arrived after '.$lateCutoff->format('h:i A').'. Late slip receipt generated.';
|
||||
}
|
||||
|
||||
return response()->json($this->successPayload([
|
||||
@@ -194,7 +198,7 @@ class ScannerController extends BaseApiController
|
||||
|
||||
$person = [
|
||||
'id' => (int) $user->id,
|
||||
'name' => trim((string) ($user->firstname ?? '') . ' ' . (string) ($user->lastname ?? '')),
|
||||
'name' => trim((string) ($user->firstname ?? '').' '.(string) ($user->lastname ?? '')),
|
||||
'email' => $user->email,
|
||||
'role' => $roleName,
|
||||
'badgeCode' => $badgeCode,
|
||||
@@ -238,7 +242,7 @@ class ScannerController extends BaseApiController
|
||||
})
|
||||
->first();
|
||||
|
||||
if (!$user || !$this->isStaffUser((int) $user->id)) {
|
||||
if (! $user || ! $this->isStaffUser((int) $user->id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -255,7 +259,7 @@ class ScannerController extends BaseApiController
|
||||
|
||||
foreach ($roles as $role) {
|
||||
$name = trim((string) ($role->role_name ?? ''));
|
||||
if ($name !== '' && !in_array($name, ['parent', 'guest', 'student'], true)) {
|
||||
if ($name !== '' && ! in_array($name, ['parent', 'guest', 'student'], true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -287,7 +291,7 @@ class ScannerController extends BaseApiController
|
||||
}
|
||||
|
||||
$row = $builder->orderByDesc('sc.id')->first();
|
||||
if (!$row && Schema::hasColumn('student_class', 'school_year')) {
|
||||
if (! $row && Schema::hasColumn('student_class', 'school_year')) {
|
||||
$row = DB::table('student_class as sc')
|
||||
->select('sc.class_section_id', 'cs.class_id', 'cs.class_section_name')
|
||||
->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id')
|
||||
@@ -329,8 +333,9 @@ class ScannerController extends BaseApiController
|
||||
->where('school_year', $schoolYear)
|
||||
->first();
|
||||
|
||||
if (!$record) {
|
||||
if (! $record) {
|
||||
$this->addAttendanceRecord($classSectionId, $studentId, $schoolId, $newStatus, $semester, $schoolYear, $operatorId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -383,6 +388,7 @@ class ScannerController extends BaseApiController
|
||||
'updated_at' => utc_now(),
|
||||
]);
|
||||
$record->save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -424,13 +430,13 @@ class ScannerController extends BaseApiController
|
||||
return [
|
||||
'id' => (int) ($student['id'] ?? 0),
|
||||
'schoolId' => $student['school_id'] ?? null,
|
||||
'name' => trim((string) ($student['firstname'] ?? '') . ' ' . (string) ($student['lastname'] ?? '')),
|
||||
'name' => trim((string) ($student['firstname'] ?? '').' '.(string) ($student['lastname'] ?? '')),
|
||||
'firstName' => $student['firstname'] ?? null,
|
||||
'lastName' => $student['lastname'] ?? null,
|
||||
'grade' => $student['registration_grade'] ?? null,
|
||||
'classSectionId' => isset($assignment['class_section_id']) ? (int) $assignment['class_section_id'] : null,
|
||||
'classSectionName' => $assignment['class_section_name'] ?? null,
|
||||
'badgeCode' => !empty($student['rfid_tag']) ? $student['rfid_tag'] : ($student['school_id'] ?? null),
|
||||
'badgeCode' => ! empty($student['rfid_tag']) ? $student['rfid_tag'] : ($student['school_id'] ?? null),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -527,7 +533,7 @@ class ScannerController extends BaseApiController
|
||||
$outstandingBalance = 0.0;
|
||||
$paymentStatus = 'Unknown';
|
||||
|
||||
if (!empty($payments)) {
|
||||
if (! empty($payments)) {
|
||||
$latest = $payments[0];
|
||||
$paymentStatus = (string) ($latest['status'] ?? 'Unknown');
|
||||
$outstandingBalance = (float) ($latest['balance'] ?? 0);
|
||||
@@ -550,7 +556,7 @@ class ScannerController extends BaseApiController
|
||||
{
|
||||
$issues = [];
|
||||
$payments = $summary['payments'] ?? [];
|
||||
if (!empty($payments)) {
|
||||
if (! empty($payments)) {
|
||||
$latest = $payments[0];
|
||||
$balance = (float) ($latest['balance'] ?? 0);
|
||||
$status = strtolower(trim((string) ($latest['status'] ?? '')));
|
||||
@@ -559,9 +565,9 @@ class ScannerController extends BaseApiController
|
||||
'category' => 'payment',
|
||||
'severity' => 'critical',
|
||||
'title' => 'Payment balance due',
|
||||
'detail' => '$' . number_format($balance, 2) . ' outstanding',
|
||||
'detail' => '$'.number_format($balance, 2).' outstanding',
|
||||
];
|
||||
} elseif ($status !== '' && !in_array($status, ['paid', 'full', 'full payment', 'complete', 'completed'], true)) {
|
||||
} elseif ($status !== '' && ! in_array($status, ['paid', 'full', 'full payment', 'complete', 'completed'], true)) {
|
||||
$issues[] = [
|
||||
'category' => 'payment',
|
||||
'severity' => 'warning',
|
||||
@@ -578,7 +584,7 @@ class ScannerController extends BaseApiController
|
||||
'category' => 'grades',
|
||||
'severity' => (float) $semesterScore < 60 ? 'critical' : 'warning',
|
||||
'title' => 'Grade concern',
|
||||
'detail' => 'Semester score ' . number_format((float) $semesterScore, 1),
|
||||
'detail' => 'Semester score '.number_format((float) $semesterScore, 1),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -587,7 +593,7 @@ class ScannerController extends BaseApiController
|
||||
$issues[] = [
|
||||
'category' => 'grades',
|
||||
'severity' => 'warning',
|
||||
'title' => $label . ' average below target',
|
||||
'title' => $label.' average below target',
|
||||
'detail' => number_format((float) $grading[$key], 1),
|
||||
];
|
||||
}
|
||||
@@ -599,7 +605,7 @@ class ScannerController extends BaseApiController
|
||||
'category' => 'attendance',
|
||||
'severity' => 'warning',
|
||||
'title' => 'Repeated lateness',
|
||||
'detail' => (int) $attendance['late'] . ' late attendance records',
|
||||
'detail' => (int) $attendance['late'].' late attendance records',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -647,7 +653,7 @@ class ScannerController extends BaseApiController
|
||||
{
|
||||
$label = trim(str_replace('_', ' ', $flagType));
|
||||
if ($label !== '') {
|
||||
return ucwords($label) . ' flag';
|
||||
return ucwords($label).' flag';
|
||||
}
|
||||
|
||||
return match ($category) {
|
||||
@@ -679,10 +685,10 @@ class ScannerController extends BaseApiController
|
||||
|
||||
private function createLateSlipPayload(array $student, array $assignment, array $term, \DateTimeImmutable $schoolNow, \DateTimeImmutable $lateCutoff, int $operatorId, ?string $previousStatus): array
|
||||
{
|
||||
$studentName = trim((string) ($student['firstname'] ?? '') . ' ' . (string) ($student['lastname'] ?? ''));
|
||||
$studentName = trim((string) ($student['firstname'] ?? '').' '.(string) ($student['lastname'] ?? ''));
|
||||
$grade = (string) ($student['registration_grade'] ?? $assignment['class_section_name'] ?? '');
|
||||
$cutoffLabel = $lateCutoff->format('h:i A');
|
||||
$reason = 'Arrived after ' . $cutoffLabel;
|
||||
$reason = 'Arrived after '.$cutoffLabel;
|
||||
$adminName = $this->operatorName($operatorId);
|
||||
$slip = [
|
||||
'school_year' => $term['school_year'],
|
||||
@@ -714,7 +720,7 @@ class ScannerController extends BaseApiController
|
||||
$logId = (int) ($created->id ?? 0);
|
||||
$logged = $logId > 0;
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Badge scan late slip log failed: ' . $e->getMessage());
|
||||
Log::error('Badge scan late slip log failed: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,15 +741,15 @@ class ScannerController extends BaseApiController
|
||||
'reason' => $reason,
|
||||
'adminName' => $adminName,
|
||||
'cutoffTime' => $cutoffLabel,
|
||||
'message' => 'Late slip receipt generated for arrival after ' . $cutoffLabel . '.',
|
||||
'message' => 'Late slip receipt generated for arrival after '.$cutoffLabel.'.',
|
||||
'text' => implode("\n", [
|
||||
'Al Rahma School at ISGL',
|
||||
'School Year: ' . $slip['school_year'],
|
||||
'Student Name: ' . $studentName,
|
||||
'Date: ' . $displayDate . ' Time In: ' . $displayTime,
|
||||
'Grade: ' . $grade,
|
||||
'Reason: ' . $reason,
|
||||
'Admin: ' . $adminName,
|
||||
'School Year: '.$slip['school_year'],
|
||||
'Student Name: '.$studentName,
|
||||
'Date: '.$displayDate.' Time In: '.$displayTime,
|
||||
'Grade: '.$grade,
|
||||
'Reason: '.$reason,
|
||||
'Admin: '.$adminName,
|
||||
]),
|
||||
];
|
||||
}
|
||||
@@ -760,18 +766,19 @@ class ScannerController extends BaseApiController
|
||||
$date = $schoolNow->format('Y-m-d');
|
||||
|
||||
foreach (['H:i:s', 'H:i', 'g:i A', 'h:i A', 'g:i a', 'h:i a'] as $format) {
|
||||
$parsed = \DateTimeImmutable::createFromFormat('!' . $format, $configured, $timezone);
|
||||
$parsed = \DateTimeImmutable::createFromFormat('!'.$format, $configured, $timezone);
|
||||
if ($parsed instanceof \DateTimeImmutable) {
|
||||
return $schoolNow->setTime((int) $parsed->format('H'), (int) $parsed->format('i'), (int) $parsed->format('s'));
|
||||
}
|
||||
}
|
||||
|
||||
$timestamp = strtotime($date . ' ' . $configured);
|
||||
$timestamp = strtotime($date.' '.$configured);
|
||||
if ($timestamp !== false) {
|
||||
return (new \DateTimeImmutable('@' . $timestamp))->setTimezone($timezone);
|
||||
return (new \DateTimeImmutable('@'.$timestamp))->setTimezone($timezone);
|
||||
}
|
||||
|
||||
Log::warning(self::LATE_CUTOFF_CONFIG_KEY . ' has invalid value "' . $configured . '"; using ' . self::DEFAULT_LATE_CUTOFF);
|
||||
Log::warning(self::LATE_CUTOFF_CONFIG_KEY.' has invalid value "'.$configured.'"; using '.self::DEFAULT_LATE_CUTOFF);
|
||||
|
||||
return $schoolNow->setTime(10, 0, 0);
|
||||
}
|
||||
|
||||
@@ -780,6 +787,7 @@ class ScannerController extends BaseApiController
|
||||
$timezone = new \DateTimeZone('America/New_York');
|
||||
try {
|
||||
$utc = new \DateTimeZone('UTC');
|
||||
|
||||
return (new \DateTimeImmutable($scannedAt, $utc))->setTimezone($timezone);
|
||||
} catch (\Throwable) {
|
||||
return new \DateTimeImmutable('now', $timezone);
|
||||
@@ -792,7 +800,7 @@ class ScannerController extends BaseApiController
|
||||
try {
|
||||
$user = User::query()->select('firstname', 'lastname', 'email')->find($operatorId);
|
||||
if ($user) {
|
||||
$name = trim((string) ($user->firstname ?? '') . ' ' . (string) ($user->lastname ?? ''));
|
||||
$name = trim((string) ($user->firstname ?? '').' '.(string) ($user->lastname ?? ''));
|
||||
if ($name !== '') {
|
||||
return $name;
|
||||
}
|
||||
@@ -800,7 +808,7 @@ class ScannerController extends BaseApiController
|
||||
return (string) ($user->email ?? '');
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Badge scan operator lookup failed: ' . $e->getMessage());
|
||||
Log::error('Badge scan operator lookup failed: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,7 +841,7 @@ class ScannerController extends BaseApiController
|
||||
private function logScan(string $badgeCode, ?string $personType, ?int $personId, string $action, string $status, int $operatorId, string $stationId, string $message, string $scannedAt): void
|
||||
{
|
||||
try {
|
||||
if (!Schema::hasTable('badge_scan_logs')) {
|
||||
if (! Schema::hasTable('badge_scan_logs')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -850,7 +858,7 @@ class ScannerController extends BaseApiController
|
||||
'created_at' => utc_now(),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Badge scan log failed: ' . $e->getMessage());
|
||||
Log::error('Badge scan log failed: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user