Files
alrahma_sunday_school_api/app/Services/Attendance/StudentAttendanceWriterService.php
T
2026-06-09 02:32:58 -04:00

181 lines
5.3 KiB
PHP

<?php
namespace App\Services\Attendance;
use App\Models\AttendanceData;
use App\Models\Student;
use RuntimeException;
class StudentAttendanceWriterService
{
public function __construct(
protected AttendanceData $attendanceData,
protected Student $student,
protected AttendanceRecordSyncService $attendanceRecordSyncService,
) {}
public function updateAttendanceData(
int $attendanceId,
string $newStatus,
?string $newReason = null,
?string $reported = null,
?int $userId = null
): void {
$payload = [
'status' => strtolower($newStatus),
'reason' => $newReason ?: null,
'modified_by' => $userId,
'updated_at' => now(),
];
if ($reported !== null) {
$payload['is_reported'] = in_array(strtolower($reported), ['yes', 'no'], true)
? strtolower($reported)
: 'no';
}
AttendanceData::query()->whereKey($attendanceId)->update($payload);
}
public function insertAttendanceData(
int $classSectionId,
int $studentId,
string $studentSchoolId,
string $status,
?string $reason,
string $reported,
string $semester,
string $schoolYear,
string $date,
int $classId,
?int $userId = null
): void {
AttendanceData::query()->create([
'class_id' => $classId,
'class_section_id' => $classSectionId,
'student_id' => $studentId,
'school_id' => $studentSchoolId,
'status' => strtolower($status),
'reason' => $reason ?: null,
'is_reported' => $reported,
'is_notified' => 'no',
'semester' => $semester,
'school_year' => $schoolYear,
'date' => $date,
'modified_by' => $userId,
'created_at' => now(),
'updated_at' => now(),
]);
}
public function resolveStudentSchoolId(int $studentId, ?string $studentSchoolId = null): string
{
$studentSchoolId = trim((string)$studentSchoolId);
if ($studentSchoolId !== '') {
return $studentSchoolId;
}
$studentRow = $this->student->query()->select('school_id')->find($studentId);
if (!$studentRow || empty($studentRow->school_id)) {
throw new RuntimeException('Student school ID not found.');
}
return (string)$studentRow->school_id;
}
public function saveOrUpdateStudentAttendance(array $payload): array
{
$classSectionId = (int)$payload['class_section_id'];
$studentId = (int)$payload['student_id'];
$studentSchoolId = $this->resolveStudentSchoolId($studentId, $payload['school_id'] ?? null);
$status = strtolower((string)$payload['status']);
$reason = $payload['reason'] ?? null;
$reported = $payload['is_reported'] ?? null;
$semester = (string)$payload['semester'];
$schoolYear = (string)$payload['school_year'];
$date = (string)$payload['date'];
$classId = (int)$payload['class_id'];
$userId = $payload['user_id'] ?? null;
$existing = AttendanceData::query()
->where('student_id', $studentId)
->whereDate('date', $date)
->where('semester', $semester)
->where('school_year', $schoolYear)
->first();
if ($existing) {
$oldStatus = $existing->status;
$this->updateAttendanceData(
(int)$existing->id,
$status,
$reason,
$reported,
$userId
);
if ($status !== $oldStatus) {
$this->attendanceRecordSyncService->updateAttendanceRecord(
$studentId,
$studentSchoolId,
$status,
$semester,
$schoolYear,
$oldStatus,
$userId
);
}
return [
'mode' => 'updated',
'attendance_id' => (int)$existing->id,
'old_status' => $oldStatus,
'new_status' => $status,
'school_id' => $studentSchoolId,
];
}
$this->insertAttendanceData(
$classSectionId,
$studentId,
$studentSchoolId,
$status,
$reason,
$reported ?? 'no',
$semester,
$schoolYear,
$date,
$classId,
$userId
);
$this->attendanceRecordSyncService->addNewAttendanceRecord(
$classSectionId,
$studentId,
$studentSchoolId,
$status,
$semester,
$schoolYear,
$userId
);
$created = AttendanceData::query()
->where('student_id', $studentId)
->whereDate('date', $date)
->where('semester', $semester)
->where('school_year', $schoolYear)
->latest('id')
->first();
return [
'mode' => 'created',
'attendance_id' => (int)($created->id ?? 0),
'old_status' => null,
'new_status' => $status,
'school_id' => $studentSchoolId,
];
}
}