add tests batch 20
This commit is contained in:
@@ -7,21 +7,17 @@ use App\Models\LateSlipLog;
|
||||
use App\Models\Student;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AttendanceManagementService
|
||||
{
|
||||
public const STATUS_PRESENT = 'present';
|
||||
|
||||
public const STATUS_ABSENT_PENDING = 'absent_pending_verification';
|
||||
|
||||
public const STATUS_ABSENT = 'absent';
|
||||
|
||||
public const STATUS_LATE = 'late';
|
||||
|
||||
public const STATUS_EARLY_DISMISSAL = 'early_dismissal';
|
||||
|
||||
public const STATUS_LATE_WITHOUT_SLIP = 'late_without_slip';
|
||||
|
||||
public function dashboard(array $filters = []): array
|
||||
@@ -208,7 +204,6 @@ class AttendanceManagementService
|
||||
if ($person['type'] === 'student' && $status === self::STATUS_LATE) {
|
||||
$row['late_slip'] = $this->printLateSlip($row, $actor);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -258,7 +253,6 @@ class AttendanceManagementService
|
||||
if (($data['exit_method'] ?? '') === 'manual_exit') {
|
||||
$this->recordBadgeException((int) $id, $person, $exitAt, 'manual exit entry', $badgeExceptions, $actor, $data['notes'] ?? null);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -298,7 +292,6 @@ class AttendanceManagementService
|
||||
];
|
||||
$id = DB::table('attendance_management_events')->insertGetId($row);
|
||||
$row['id'] = $id;
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -319,7 +312,6 @@ class AttendanceManagementService
|
||||
$update['report_status'] = $this->normalizeReportStatus($data['report_status']);
|
||||
}
|
||||
DB::table('attendance_management_events')->where('id', $id)->update($update);
|
||||
|
||||
return (array) DB::table('attendance_management_events')->where('id', $id)->first();
|
||||
}
|
||||
|
||||
@@ -355,7 +347,6 @@ class AttendanceManagementService
|
||||
'final_decision' => 'Late slip reprinted',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -376,24 +367,12 @@ class AttendanceManagementService
|
||||
|
||||
$student = null;
|
||||
$user = null;
|
||||
if ($type === 'student' && $id > 0) {
|
||||
$student = Student::query()->find($id);
|
||||
}
|
||||
if (in_array($type, ['staff', 'user', 'teacher', 'administrator'], true) && $id > 0) {
|
||||
$user = User::query()->find($id);
|
||||
}
|
||||
if (! $student && $badge !== '') {
|
||||
$student = Student::query()->where('rfid_tag', $badge)->first();
|
||||
}
|
||||
if (! $student && ! $user && $badge !== '') {
|
||||
$user = User::query()->where('rfid_tag', $badge)->first();
|
||||
}
|
||||
if (! $student && ! $user && $id > 0) {
|
||||
$student = Student::query()->find($id);
|
||||
}
|
||||
if (! $student && ! $user && $id > 0) {
|
||||
$user = User::query()->find($id);
|
||||
}
|
||||
if ($type === 'student' && $id > 0) $student = Student::query()->find($id);
|
||||
if (in_array($type, ['staff', 'user', 'teacher', 'administrator'], true) && $id > 0) $user = User::query()->find($id);
|
||||
if (! $student && $badge !== '') $student = Student::query()->where('rfid_tag', $badge)->first();
|
||||
if (! $student && ! $user && $badge !== '') $user = User::query()->where('rfid_tag', $badge)->first();
|
||||
if (! $student && ! $user && $id > 0) $student = Student::query()->find($id);
|
||||
if (! $student && ! $user && $id > 0) $user = User::query()->find($id);
|
||||
|
||||
if ($student) {
|
||||
return [
|
||||
@@ -418,7 +397,6 @@ class AttendanceManagementService
|
||||
if ($name === '') {
|
||||
throw new \InvalidArgumentException('Person could not be resolved. Provide person_id, badge_id, or person_name.');
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => $type !== '' ? $type : 'visitor',
|
||||
'id' => $id > 0 ? $id : null,
|
||||
@@ -441,7 +419,6 @@ class AttendanceManagementService
|
||||
'admin_name' => $actor ? trim(($actor->firstname ?? '').' '.($actor->lastname ?? '')) : 'System',
|
||||
];
|
||||
$logged = LateSlipLog::logSlip($payload, $actor?->id);
|
||||
|
||||
return [
|
||||
'printed' => $logged,
|
||||
'slip_number' => 'AME-'.($event['id'] ?? time()),
|
||||
@@ -481,16 +458,9 @@ class AttendanceManagementService
|
||||
$absence = (clone $q)->where('attendance_status', self::STATUS_ABSENT)->count();
|
||||
$late = (clone $q)->whereIn('attendance_status', [self::STATUS_LATE, self::STATUS_LATE_WITHOUT_SLIP])->count();
|
||||
$ed = (clone $q)->where('attendance_status', self::STATUS_EARLY_DISMISSAL)->count();
|
||||
if ($newStatus === self::STATUS_ABSENT) {
|
||||
$absence++;
|
||||
}
|
||||
if (in_array($newStatus, [self::STATUS_LATE, self::STATUS_LATE_WITHOUT_SLIP], true)) {
|
||||
$late++;
|
||||
}
|
||||
if ($newStatus === self::STATUS_EARLY_DISMISSAL) {
|
||||
$ed++;
|
||||
}
|
||||
|
||||
if ($newStatus === self::STATUS_ABSENT) $absence++;
|
||||
if (in_array($newStatus, [self::STATUS_LATE, self::STATUS_LATE_WITHOUT_SLIP], true)) $late++;
|
||||
if ($newStatus === self::STATUS_EARLY_DISMISSAL) $ed++;
|
||||
return ['absence_count' => $absence, 'late_count' => $late, 'early_dismissal_count' => $ed];
|
||||
}
|
||||
|
||||
@@ -558,7 +528,6 @@ class AttendanceManagementService
|
||||
private function schoolStartFor(Carbon $date): Carbon
|
||||
{
|
||||
$configured = Configuration::getConfigValueByKey('school_start_time') ?: config('attendance.school_start_time', '09:00:00');
|
||||
|
||||
return Carbon::parse($date->toDateString().' '.$configured, $date->timezone);
|
||||
}
|
||||
|
||||
@@ -647,20 +616,12 @@ class AttendanceManagementService
|
||||
}));
|
||||
}
|
||||
|
||||
private function dateTime($value): Carbon
|
||||
{
|
||||
return $value instanceof Carbon ? $value : Carbon::parse((string) $value);
|
||||
}
|
||||
|
||||
private function dateOnly($value): string
|
||||
{
|
||||
return Carbon::parse((string) $value)->toDateString();
|
||||
}
|
||||
private function dateTime($value): Carbon { return $value instanceof Carbon ? $value : Carbon::parse((string) $value); }
|
||||
private function dateOnly($value): string { return Carbon::parse((string) $value)->toDateString(); }
|
||||
|
||||
private function normalizeReportStatus($value): string
|
||||
{
|
||||
$v = strtolower(str_replace(['-', ' '], '_', trim((string) $value)));
|
||||
|
||||
return in_array($v, ['reported', 'not_reported', 'pending_clarification'], true) ? $v : 'pending_clarification';
|
||||
}
|
||||
|
||||
@@ -680,61 +641,30 @@ class AttendanceManagementService
|
||||
private function combinationCode(int $abs, int $late, int $ed, int $badge): string
|
||||
{
|
||||
$parts = [];
|
||||
if ($abs > 0) {
|
||||
$parts[] = min($abs, 5).'ABS';
|
||||
}
|
||||
if ($late > 0) {
|
||||
$parts[] = min($late, 5).'Late';
|
||||
}
|
||||
if ($ed > 0) {
|
||||
$parts[] = min($ed, 3).'ED';
|
||||
}
|
||||
if ($badge > 0) {
|
||||
$parts[] = min($badge, 5).'Badge Exceptions';
|
||||
}
|
||||
|
||||
if ($abs > 0) $parts[] = min($abs, 5).'ABS';
|
||||
if ($late > 0) $parts[] = min($late, 5).'Late';
|
||||
if ($ed > 0) $parts[] = min($ed, 3).'ED';
|
||||
if ($badge > 0) $parts[] = min($badge, 5).'Badge Exceptions';
|
||||
return $parts ? implode(' + ', $parts) : 'Clear';
|
||||
}
|
||||
|
||||
private function riskLevel(int $abs, int $late, int $ed, int $badge): string
|
||||
{
|
||||
if ($abs >= 5 && $late >= 5) {
|
||||
return 'severe';
|
||||
}
|
||||
if ($abs >= 5 || $late >= 5) {
|
||||
return 'critical';
|
||||
}
|
||||
if ($abs + $late + $ed + $badge >= 6 || $abs >= 4 || $late >= 4) {
|
||||
return 'very_high';
|
||||
}
|
||||
if ($abs + $late + $ed + $badge >= 4 || $abs >= 3 || $late >= 3 || $badge >= 4) {
|
||||
return 'high';
|
||||
}
|
||||
if ($abs + $late + $ed + $badge >= 2 || $badge >= 2) {
|
||||
return 'medium';
|
||||
}
|
||||
|
||||
if ($abs >= 5 && $late >= 5) return 'severe';
|
||||
if ($abs >= 5 || $late >= 5) return 'critical';
|
||||
if ($abs + $late + $ed + $badge >= 6 || $abs >= 4 || $late >= 4) return 'very_high';
|
||||
if ($abs + $late + $ed + $badge >= 4 || $abs >= 3 || $late >= 3 || $badge >= 4) return 'high';
|
||||
if ($abs + $late + $ed + $badge >= 2 || $badge >= 2) return 'medium';
|
||||
return 'low';
|
||||
}
|
||||
|
||||
private function actionNeeded(string $status, string $reportStatus, int $badgeCount): string
|
||||
{
|
||||
if ($badgeCount >= 5) {
|
||||
return 'Leadership review for badge compliance';
|
||||
}
|
||||
if ($badgeCount >= 4) {
|
||||
return 'Formal badge follow-up required';
|
||||
}
|
||||
if ($status === self::STATUS_LATE && $reportStatus !== 'reported') {
|
||||
return 'Print late slip and contact parent or staff';
|
||||
}
|
||||
if ($status === self::STATUS_ABSENT && $reportStatus !== 'reported') {
|
||||
return 'Same-day contact required';
|
||||
}
|
||||
if ($status === self::STATUS_EARLY_DISMISSAL && $reportStatus !== 'reported') {
|
||||
return 'Verify authorization and contact guardian/supervisor';
|
||||
}
|
||||
|
||||
if ($badgeCount >= 5) return 'Leadership review for badge compliance';
|
||||
if ($badgeCount >= 4) return 'Formal badge follow-up required';
|
||||
if ($status === self::STATUS_LATE && $reportStatus !== 'reported') return 'Print late slip and contact parent or staff';
|
||||
if ($status === self::STATUS_ABSENT && $reportStatus !== 'reported') return 'Same-day contact required';
|
||||
if ($status === self::STATUS_EARLY_DISMISSAL && $reportStatus !== 'reported') return 'Verify authorization and contact guardian/supervisor';
|
||||
return 'Record and monitor';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user