73 lines
2.5 KiB
PHP
73 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Attendance;
|
|
|
|
use App\Models\Attendance;
|
|
use App\Models\Position;
|
|
use App\Models\PusatMengundi;
|
|
use App\Models\StaffAssignment;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class AttendanceSummaryService
|
|
{
|
|
/**
|
|
* @return array{total_staff: int, present: int, absent: int, not_recorded: int}
|
|
*/
|
|
public function totalsForPusat(PusatMengundi $pusatMengundi): array
|
|
{
|
|
$totalStaff = StaffAssignment::query()
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->where('status', 'active')
|
|
->count();
|
|
|
|
$present = Attendance::query()
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->where('status', 'present')
|
|
->count();
|
|
|
|
$absent = Attendance::query()
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->where('status', 'absent')
|
|
->count();
|
|
|
|
return [
|
|
'total_staff' => $totalStaff,
|
|
'present' => $present,
|
|
'absent' => $absent,
|
|
'not_recorded' => max(0, $totalStaff - $present - $absent),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return Collection<int, mixed>
|
|
*/
|
|
public function roleTotalsForPusat(PusatMengundi $pusatMengundi): Collection
|
|
{
|
|
$assignments = StaffAssignment::query()
|
|
->with(['position', 'attendance'])
|
|
->where('pusat_mengundi_id', $pusatMengundi->id)
|
|
->where('status', 'active')
|
|
->get();
|
|
|
|
return $assignments
|
|
->groupBy(function (StaffAssignment $assignment): string {
|
|
$position = $assignment->position;
|
|
|
|
return $position instanceof Position ? $position->code : 'UNKNOWN';
|
|
})
|
|
->map(function (Collection $items, string $role): array {
|
|
$present = $items->filter(fn (StaffAssignment $assignment): bool => $assignment->attendance instanceof Attendance && $assignment->attendance->status === 'present')->count();
|
|
$absent = $items->filter(fn (StaffAssignment $assignment): bool => $assignment->attendance instanceof Attendance && $assignment->attendance->status === 'absent')->count();
|
|
|
|
return [
|
|
'role' => $role,
|
|
'total_staff' => $items->count(),
|
|
'present' => $present,
|
|
'absent' => $absent,
|
|
'not_recorded' => max(0, $items->count() - $present - $absent),
|
|
];
|
|
})
|
|
->values();
|
|
}
|
|
}
|