- AttendanceService: staffCheckin and walkInRegister methods - CheckinController: QR-based check-in (staff & walk-in external) - AttendanceCheckController: semak kehadiran & sijil status - Views: checkin show/success/already/unavailable, semak show/result Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
124 lines
5.0 KiB
PHP
124 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Attendance;
|
|
use App\Models\Participant;
|
|
use App\Models\Program;
|
|
use App\Models\ProgramParticipant;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class AttendanceService
|
|
{
|
|
public function staffCheckin(Program $program, string $noKp, Request $request): array
|
|
{
|
|
$noKp = preg_replace('/[^0-9]/', '', $noKp);
|
|
|
|
// Find participant
|
|
$participant = Participant::where('no_kp', $noKp)->first();
|
|
if (! $participant) {
|
|
return ['status' => 'not_found'];
|
|
}
|
|
|
|
// Check if registered in this program
|
|
$pp = ProgramParticipant::where('program_id', $program->id)
|
|
->where('participant_id', $participant->id)
|
|
->first();
|
|
|
|
if (! $pp) {
|
|
return ['status' => 'not_registered', 'participant' => $participant];
|
|
}
|
|
|
|
// Already checked in
|
|
if (Attendance::where('program_id', $program->id)->where('participant_id', $participant->id)->exists()) {
|
|
$att = Attendance::where('program_id', $program->id)->where('participant_id', $participant->id)->first();
|
|
return ['status' => 'already_checked_in', 'participant' => $participant, 'attendance' => $att];
|
|
}
|
|
|
|
// Record attendance
|
|
$attendance = DB::transaction(function () use ($program, $participant, $pp, $request) {
|
|
$session = $pp->pre_registered_session ?? $program->default_staff_session ?? 'full_day';
|
|
|
|
$pp->update(['status' => 'checked_in']);
|
|
|
|
return Attendance::create([
|
|
'program_id' => $program->id,
|
|
'participant_id' => $participant->id,
|
|
'program_participant_id' => $pp->id,
|
|
'attendance_source' => 'pre_registered_staff',
|
|
'attendance_session' => $session,
|
|
'checked_in_at' => now(),
|
|
'checked_in_ip' => $request->ip(),
|
|
'user_agent' => substr($request->userAgent() ?? '', 0, 500),
|
|
]);
|
|
});
|
|
|
|
return ['status' => 'success', 'participant' => $participant, 'attendance' => $attendance];
|
|
}
|
|
|
|
public function walkInRegister(Program $program, array $data, Request $request): array
|
|
{
|
|
$noKp = preg_replace('/[^0-9]/', '', $data['no_kp']);
|
|
|
|
// Check duplicate in this program
|
|
$existing = Participant::where('no_kp', $noKp)->first();
|
|
if ($existing) {
|
|
$alreadyRegistered = ProgramParticipant::where('program_id', $program->id)
|
|
->where('participant_id', $existing->id)
|
|
->exists();
|
|
if ($alreadyRegistered) {
|
|
// Check if already attended
|
|
$att = Attendance::where('program_id', $program->id)
|
|
->where('participant_id', $existing->id)
|
|
->first();
|
|
if ($att) {
|
|
return ['status' => 'already_checked_in', 'participant' => $existing, 'attendance' => $att];
|
|
}
|
|
}
|
|
}
|
|
|
|
$result = DB::transaction(function () use ($program, $data, $noKp, $existing, $request) {
|
|
$participant = $existing ?? Participant::create([
|
|
'name' => $data['name'],
|
|
'no_kp' => $noKp,
|
|
'email' => $data['email'] ?: null,
|
|
'phone' => $data['phone'] ?: null,
|
|
'agency' => $data['agency'] ?: null,
|
|
'participant_type' => 'external',
|
|
]);
|
|
|
|
// Create program_participant if not exists
|
|
$pp = ProgramParticipant::firstOrCreate(
|
|
['program_id' => $program->id, 'participant_id' => $participant->id],
|
|
[
|
|
'registration_source' => 'walk_in',
|
|
'is_pre_registered' => false,
|
|
'pre_registered_session'=> $program->default_external_session,
|
|
'status' => 'registered',
|
|
'registered_at' => now(),
|
|
]
|
|
);
|
|
|
|
$session = $program->default_external_session ?? 'full_day';
|
|
|
|
$pp->update(['status' => 'checked_in']);
|
|
|
|
$attendance = Attendance::create([
|
|
'program_id' => $program->id,
|
|
'participant_id' => $participant->id,
|
|
'program_participant_id' => $pp->id,
|
|
'attendance_source' => 'walk_in_external',
|
|
'attendance_session' => $session,
|
|
'checked_in_at' => now(),
|
|
'checked_in_ip' => $request->ip(),
|
|
'user_agent' => substr($request->userAgent() ?? '', 0, 500),
|
|
]);
|
|
|
|
return ['status' => 'success', 'participant' => $participant, 'attendance' => $attendance];
|
|
});
|
|
|
|
return $result;
|
|
}
|
|
}
|