This commit is contained in:
Saufi
2026-06-03 08:51:22 +08:00
commit a14d43fe34
347 changed files with 38197 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
<?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();
}
}