fix gitlab tests

This commit is contained in:
root
2026-06-09 02:32:58 -04:00
parent 20a0b6c4e5
commit 6def9993da
1489 changed files with 10449 additions and 11356 deletions
@@ -16,7 +16,7 @@ class AttendanceAutoPublishJobServiceTest extends TestCase
public function test_run_publishes_due_records(): void
{
$autoPublish = new AttendanceAutoPublishService;
$autoPublish = new AttendanceAutoPublishService();
$service = new AttendanceAutoPublishJobService($autoPublish);
$now = new DateTimeImmutable('2025-03-01 10:00:00', new DateTimeZone('UTC'));
@@ -10,7 +10,7 @@ class AttendanceAutoPublishServiceTest extends TestCase
{
public function test_second_sunday_after_end_of_day(): void
{
$service = new AttendanceAutoPublishService;
$service = new AttendanceAutoPublishService();
$result = $service->secondSundayAfterEndOfDay('2025-02-03', 'UTC');
@@ -19,7 +19,7 @@ class AttendanceAutoPublishServiceTest extends TestCase
public function test_second_sunday_backward_date(): void
{
$service = new AttendanceAutoPublishService;
$service = new AttendanceAutoPublishService();
$now = new DateTimeImmutable('2025-02-16 10:00:00', new \DateTimeZone('UTC'));
$result = $service->secondSundayBackwardDate($now, 'UTC');
@@ -28,7 +28,7 @@ class AttendanceCommentServiceTest extends TestCase
],
]);
$service = new AttendanceCommentService;
$service = new AttendanceCommentService();
$comment = $service->commentFromScore(95, 'James');
$this->assertSame("James' attendance is excellent.", $comment);
@@ -43,7 +43,7 @@ class AttendanceCommentServiceTest extends TestCase
'is_active' => 1,
]);
$service = new AttendanceCommentService;
$service = new AttendanceCommentService();
$comment = $service->commentFromScore(70);
$this->assertSame("This student's needs improvement in attendance.", $comment);
@@ -7,7 +7,6 @@ use App\Services\Attendance\AttendanceConsequenceService;
use App\Services\EmailService;
use App\Services\Notifications\UserNotificationDispatchService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Mockery;
use Tests\TestCase;
@@ -31,7 +30,7 @@ class AttendanceConsequenceServiceTest extends TestCase
public function test_send_follow_up_marks_tracking_and_notifies(): void
{
DB::table('students')->insert([
\Illuminate\Support\Facades\DB::table('students')->insert([
'id' => 1,
'school_id' => 1,
'parent_id' => 1,
@@ -12,7 +12,7 @@ class AttendancePolicyServiceTest extends TestCase
public function test_teacher_can_edit_draft(): void
{
$service = new AttendancePolicyService;
$service = new AttendancePolicyService();
$allowed = $service->canEditDay(
['status' => 'draft'],
['roles' => ['Teacher'], 'permissions' => []]
@@ -23,7 +23,7 @@ class AttendancePolicyServiceTest extends TestCase
public function test_teacher_cannot_edit_finalized(): void
{
$service = new AttendancePolicyService;
$service = new AttendancePolicyService();
$allowed = $service->canEditDay(
['status' => 'finalized'],
['roles' => ['Teacher'], 'permissions' => []]
@@ -34,7 +34,7 @@ class AttendancePolicyServiceTest extends TestCase
public function test_admin_like_by_permission(): void
{
$service = new AttendancePolicyService;
$service = new AttendancePolicyService();
$isAdmin = $service->isAdminLike([], ['attendance.manage.daily']);
$this->assertTrue($isAdmin);
@@ -42,7 +42,7 @@ class AttendancePolicyServiceTest extends TestCase
public function test_can_manage_early_dismissals_for_teacher(): void
{
$service = new AttendancePolicyService;
$service = new AttendancePolicyService();
$allowed = $service->canManageEarlyDismissals(['Teacher']);
$this->assertTrue($allowed);
@@ -2,25 +2,7 @@
namespace Tests\Unit\Services\Attendance;
use App\Models\AttendanceData;
use App\Models\AttendanceDay;
use App\Models\AttendanceRecord;
use App\Models\Calendar;
use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Models\User;
use App\Models\UserRole;
use App\Services\Attendance\AttendanceAutoPublishService;
use App\Services\Attendance\AttendancePolicyService;
use App\Services\Attendance\AttendanceQueryService;
use App\Services\Attendance\AttendanceRecordSyncService;
use App\Services\Attendance\AttendanceService;
use App\Services\Attendance\SemesterRangeService;
use App\Services\Attendance\StudentAttendanceWriterService;
use App\Services\Attendance\TeacherAttendanceSubmissionService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
@@ -80,45 +62,45 @@ class AttendanceQueryServiceTest extends TestCase
]);
$service = new AttendanceQueryService(
new Configuration,
new AttendanceData,
new AttendanceDay,
new AttendanceRecord,
new Student,
new StudentClass,
new ClassSection,
new TeacherClass,
new Calendar,
new User,
new UserRole,
new AttendanceService(
new Configuration,
new AttendanceData,
new AttendanceDay,
new ClassSection,
new UserRole,
new AttendancePolicyService,
new StudentAttendanceWriterService(
new AttendanceData,
new Student,
new AttendanceRecordSyncService(new AttendanceRecord)
new \App\Models\Configuration(),
new \App\Models\AttendanceData(),
new \App\Models\AttendanceDay(),
new \App\Models\AttendanceRecord(),
new \App\Models\Student(),
new \App\Models\StudentClass(),
new \App\Models\ClassSection(),
new \App\Models\TeacherClass(),
new \App\Models\Calendar(),
new \App\Models\User(),
new \App\Models\UserRole(),
new \App\Services\Attendance\AttendanceService(
new \App\Models\Configuration(),
new \App\Models\AttendanceData(),
new \App\Models\AttendanceDay(),
new \App\Models\ClassSection(),
new \App\Models\UserRole(),
new \App\Services\Attendance\AttendancePolicyService(),
new \App\Services\Attendance\StudentAttendanceWriterService(
new \App\Models\AttendanceData(),
new \App\Models\Student(),
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
),
new TeacherAttendanceSubmissionService(
new AttendanceDay,
new AttendanceData,
new TeacherClass,
new Student,
new AttendancePolicyService,
new StudentAttendanceWriterService(
new AttendanceData,
new Student,
new AttendanceRecordSyncService(new AttendanceRecord)
new \App\Services\Attendance\TeacherAttendanceSubmissionService(
new \App\Models\AttendanceDay(),
new \App\Models\AttendanceData(),
new \App\Models\TeacherClass(),
new \App\Models\Student(),
new \App\Services\Attendance\AttendancePolicyService(),
new \App\Services\Attendance\StudentAttendanceWriterService(
new \App\Models\AttendanceData(),
new \App\Models\Student(),
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
),
new AttendanceAutoPublishService
new \App\Services\Attendance\AttendanceAutoPublishService()
),
new AttendanceRecordSyncService(new AttendanceRecord)
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
),
new SemesterRangeService
new \App\Services\Attendance\SemesterRangeService()
);
$grid = $service->teacherGrid('Fall', '2025-2026', '2025-01-05', 10);
@@ -2,7 +2,6 @@
namespace Tests\Unit\Services\Attendance;
use App\Models\AttendanceRecord;
use App\Services\Attendance\AttendanceRecordSyncService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
@@ -26,7 +25,7 @@ class AttendanceRecordSyncServiceTest extends TestCase
'school_year' => '2025-2026',
]);
$service = new AttendanceRecordSyncService(new AttendanceRecord);
$service = new AttendanceRecordSyncService(new \App\Models\AttendanceRecord());
$service->updateAttendanceRecord(10, 'S1', 'absent', 'Fall', '2025-2026', 'present', 1);
$row = DB::table('attendance_record')->where('student_id', 10)->first();
@@ -36,7 +35,7 @@ class AttendanceRecordSyncServiceTest extends TestCase
public function test_add_new_attendance_record_creates_row(): void
{
$service = new AttendanceRecordSyncService(new AttendanceRecord);
$service = new AttendanceRecordSyncService(new \App\Models\AttendanceRecord());
$service->addNewAttendanceRecord(1, 10, 'S1', 'present', 'Fall', '2025-2026', 1);
$this->assertDatabaseHas('attendance_record', [
@@ -12,7 +12,7 @@ class AttendanceSemesterRangeServiceTest extends TestCase
public function test_get_semester_range(): void
{
$service = new SemesterRangeService;
$service = new SemesterRangeService();
$range = $service->getSemesterRange('2025-2026', 'fall');
$this->assertSame(['2025-09-21', '2026-01-18'], $range);
@@ -20,7 +20,7 @@ class AttendanceSemesterRangeServiceTest extends TestCase
public function test_build_sunday_list_returns_sundays(): void
{
$service = new SemesterRangeService;
$service = new SemesterRangeService();
$dates = $service->buildSundayList('2025-09-01', '2025-09-30');
$this->assertContains('2025-09-07', $dates);
@@ -34,11 +34,11 @@ class AttendanceServiceTest extends TestCase
$recordSync = Mockery::mock(AttendanceRecordSyncService::class);
$service = new AttendanceService(
new Configuration,
new AttendanceData,
new AttendanceDay,
new ClassSection,
new UserRole,
new Configuration(),
new AttendanceData(),
new AttendanceDay(),
new ClassSection(),
new UserRole(),
$policy,
$writer,
$teacherSubmission,
@@ -70,11 +70,11 @@ class AttendanceServiceTest extends TestCase
$recordSync = Mockery::mock(AttendanceRecordSyncService::class);
$service = new AttendanceService(
new Configuration,
new AttendanceData,
new AttendanceDay,
new ClassSection,
new UserRole,
new Configuration(),
new AttendanceData(),
new AttendanceDay(),
new ClassSection(),
new UserRole(),
$policy,
$writer,
$teacherSubmission,
@@ -46,7 +46,7 @@ class AttendanceSummaryRebuildServiceTest extends TestCase
],
]);
$service = new AttendanceSummaryRebuildService;
$service = new AttendanceSummaryRebuildService();
$result = $service->rebuild();
$this->assertSame(2, $result['inserted']);
@@ -2,13 +2,13 @@
namespace App\Services;
use App\Models\AttendanceData;
use App\Models\AttendanceEmailTemplate;
use App\Models\AttendanceTracking;
use App\Models\Configuration;
use App\Models\ParentNotification;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\Student;
use App\Models\Configuration;
use App\Models\AttendanceData;
use App\Models\ParentNotification;
use App\Models\AttendanceEmailTemplate;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
@@ -19,11 +19,8 @@ use Throwable;
class AttendanceTrackingService
{
protected string $semester;
protected string $schoolYear;
protected array $debugCompute = [];
protected ?array $attendanceReportedColumns = null;
public function __construct(
@@ -43,19 +40,19 @@ class AttendanceTrackingService
public function getPendingViolations(?string $schoolYearParam = null, ?string $semesterParam = null): array
{
$schoolYear = filled($schoolYearParam) ? (string) $schoolYearParam : (string) $this->schoolYear;
$semester = filled($semesterParam) ? (string) $semesterParam : null; // disabled like legacy
$semester = filled($semesterParam) ? (string) $semesterParam : null; // disabled like legacy
$debugInfo = [
'school_year_param' => $schoolYear,
'semester_param' => $semester,
'class_students' => 0,
'student_ids' => 0,
'attendance_rows' => 0,
'filtered_rows' => 0,
'violations' => 0,
'active_weeks' => 0,
'abs_last5' => 0,
'late_last5' => 0,
'semester_param' => $semester,
'class_students' => 0,
'student_ids' => 0,
'attendance_rows' => 0,
'filtered_rows' => 0,
'violations' => 0,
'active_weeks' => 0,
'abs_last5' => 0,
'late_last5' => 0,
];
$classStudentsQuery = $this->studentClassModel->query();
@@ -76,9 +73,9 @@ class AttendanceTrackingService
->orderByDesc('id')
->first();
if ($latestTerm && ! empty($latestTerm->school_year)) {
if ($latestTerm && !empty($latestTerm->school_year)) {
$schoolYear = (string) $latestTerm->school_year;
if (! empty($latestTerm->semester)) {
if (!empty($latestTerm->semester)) {
$semester = (string) $latestTerm->semester;
}
@@ -109,7 +106,7 @@ class AttendanceTrackingService
if (empty($studentIds) && empty($studentCodes)) {
$attendanceStudents = DB::table('attendance_data')
->selectRaw('DISTINCT student_id')
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->orderBy('student_id')
->get();
@@ -126,7 +123,7 @@ class AttendanceTrackingService
$studentIds = array_values(array_unique(array_filter($studentIds, fn ($v) => $v > 0)));
$studentCodes = array_values(array_unique(array_filter($studentCodes, fn ($v) => $v !== '')));
if (! empty($studentIds)) {
if (!empty($studentIds)) {
$inactiveRows = $this->studentModel->query()
->select('id')
->whereIn('id', $studentIds)
@@ -141,11 +138,11 @@ class AttendanceTrackingService
$studentIds = array_values(array_filter(
$studentIds,
static fn ($id) => ! isset($inactiveIdSet[$id])
static fn ($id) => !isset($inactiveIdSet[$id])
));
}
if (! empty($studentCodes)) {
if (!empty($studentCodes)) {
$inactiveCodeRows = $this->studentModel->query()
->select('school_id')
->whereIn('school_id', $studentCodes)
@@ -160,7 +157,7 @@ class AttendanceTrackingService
$studentCodes = array_values(array_filter(
$studentCodes,
static fn ($code) => $code !== '' && ! isset($inactiveCodeSet[$code])
static fn ($code) => $code !== '' && !isset($inactiveCodeSet[$code])
));
}
@@ -177,7 +174,7 @@ class AttendanceTrackingService
}
$students = [];
if (! empty($studentIds)) {
if (!empty($studentIds)) {
$students = $this->studentModel->query()
->whereIn('id', $studentIds)
->where('is_active', 1)
@@ -185,7 +182,7 @@ class AttendanceTrackingService
->toArray();
}
if (! empty($studentCodes)) {
if (!empty($studentCodes)) {
$byCode = $this->studentModel->query()
->whereIn('school_id', $studentCodes)
->where('is_active', 1)
@@ -195,7 +192,7 @@ class AttendanceTrackingService
$seen = array_flip(array_map(fn ($s) => (int) ($s['id'] ?? 0), $students));
foreach ($byCode as $s) {
$sid = (int) ($s['id'] ?? 0);
if ($sid > 0 && ! isset($seen[$sid])) {
if ($sid > 0 && !isset($seen[$sid])) {
$students[] = $s;
$seen[$sid] = true;
}
@@ -211,7 +208,7 @@ class AttendanceTrackingService
}
foreach ($studentCodes as $code) {
if (! isset($knownCodes[$code])) {
if (!isset($knownCodes[$code])) {
$virtualId = abs(crc32($code)) ?: random_int(1000000, 1999999);
$students[] = [
'id' => $virtualId,
@@ -247,7 +244,7 @@ class AttendanceTrackingService
foreach (array_merge($studentIds, $studentCodes) as $sidOrCode) {
if (is_numeric($sidOrCode)) {
$sid = (int) $sidOrCode;
if ($sid > 0 && ! isset($existingIds[$sid])) {
if ($sid > 0 && !isset($existingIds[$sid])) {
$students[] = [
'id' => $sid,
'school_id' => (string) $sid,
@@ -260,7 +257,7 @@ class AttendanceTrackingService
}
} else {
$code = (string) $sidOrCode;
if ($code !== '' && ! isset($studentCodeToId[$code])) {
if ($code !== '' && !isset($studentCodeToId[$code])) {
$virtualId = abs(crc32($code)) ?: random_int(2000000, 2999999);
$students[] = [
'id' => $virtualId,
@@ -298,14 +295,14 @@ class AttendanceTrackingService
'is_reported',
'is_notified',
])
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(! empty($semester), fn ($q) => $q->where('semester', $semester))
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(!empty($semester), fn ($q) => $q->where('semester', $semester))
->where(function ($q) use ($studentIds, $studentCodes) {
if (! empty($studentIds)) {
if (!empty($studentIds)) {
$q->whereIn('student_id', $studentIds);
}
if (! empty($studentCodes)) {
if (! empty($studentIds)) {
if (!empty($studentCodes)) {
if (!empty($studentIds)) {
$q->orWhereIn('student_id', $studentCodes);
} else {
$q->whereIn('student_id', $studentCodes);
@@ -325,16 +322,16 @@ class AttendanceTrackingService
if (empty($termRows)) {
$latestAttendanceTerm = DB::table('attendance_data')
->select('school_year', 'semester', 'date')
->when(! empty($studentIds), fn ($q) => $q->whereIn('student_id', $studentIds))
->when(!empty($studentIds), fn ($q) => $q->whereIn('student_id', $studentIds))
->orderByDesc('date')
->first();
if ($latestAttendanceTerm) {
$schoolYear = ! empty($latestAttendanceTerm->school_year)
$schoolYear = !empty($latestAttendanceTerm->school_year)
? (string) $latestAttendanceTerm->school_year
: $schoolYear;
$semester = ! empty($latestAttendanceTerm->semester)
$semester = !empty($latestAttendanceTerm->semester)
? (string) $latestAttendanceTerm->semester
: $semester;
@@ -357,14 +354,14 @@ class AttendanceTrackingService
'is_reported',
'is_notified',
])
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(! empty($semester), fn ($q) => $q->where('semester', $semester))
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(!empty($semester), fn ($q) => $q->where('semester', $semester))
->where(function ($q) use ($studentIds, $studentCodes) {
if (! empty($studentIds)) {
if (!empty($studentIds)) {
$q->whereIn('student_id', $studentIds);
}
if (! empty($studentCodes)) {
if (! empty($studentIds)) {
if (!empty($studentCodes)) {
if (!empty($studentIds)) {
$q->orWhereIn('student_id', $studentCodes);
} else {
$q->whereIn('student_id', $studentCodes);
@@ -395,7 +392,7 @@ class AttendanceTrackingService
$attendanceRows = [];
foreach ($termRows as $row) {
$dStr = $row['date'] ?? null;
if (! $dStr) {
if (!$dStr) {
continue;
}
@@ -405,7 +402,7 @@ class AttendanceTrackingService
continue;
}
if ($d->lt($start) || ! $d->lt($endEx)) {
if ($d->lt($start) || !$d->lt($endEx)) {
continue;
}
@@ -421,7 +418,7 @@ class AttendanceTrackingService
if ($sid === null) {
$sid = abs(crc32($code)) ?: random_int(3000000, 3999999);
$studentCodeToId[$code] = $sid;
if (! isset($existingIds[$sid])) {
if (!isset($existingIds[$sid])) {
$students[] = [
'id' => $sid,
'school_id' => $code,
@@ -446,7 +443,7 @@ class AttendanceTrackingService
foreach ($attendanceRows as $arow) {
$sid = (int) ($arow['student_id'] ?? 0);
if ($sid > 0 && ! isset($existingIds[$sid])) {
if ($sid > 0 && !isset($existingIds[$sid])) {
$students[] = [
'id' => $sid,
'school_id' => (string) ($arow['student_code'] ?? $arow['student_id']),
@@ -498,13 +495,13 @@ class AttendanceTrackingService
$parentEmail = $data['parent_email'] ?? '';
$parentName = $data['parent_name'] ?? '';
if (! $parentEmail) {
if (!$parentEmail) {
$parent = $this->getPrimaryParentForStudent($sid) ?? [];
$parentEmail = $parent['email'] ?? '';
$parentName = $parent['parent_name'] ?? '';
}
if (! $parentEmail) {
if (!$parentEmail) {
return [
'success' => false,
'message' => 'No parent email found for this student.',
@@ -555,7 +552,7 @@ class AttendanceTrackingService
try {
$this->attendanceMailerService->queueAttendanceEvent($payload);
if ($row && ! empty($row['id']) && method_exists($this->attendanceTrackingModel, 'markAsNotified')) {
if ($row && !empty($row['id']) && method_exists($this->attendanceTrackingModel, 'markAsNotified')) {
$this->attendanceTrackingModel->markAsNotified((int) $row['id']);
}
@@ -565,7 +562,7 @@ class AttendanceTrackingService
'data' => $payload,
];
} catch (Throwable $e) {
Log::error('Attendance record queue failed: '.$e->getMessage());
Log::error('Attendance record queue failed: ' . $e->getMessage());
return [
'success' => false,
@@ -585,7 +582,7 @@ class AttendanceTrackingService
?string $semesterFilter = null
): array {
$student = $this->studentModel->query()->find($studentId);
if (! $student) {
if (!$student) {
return [
'success' => false,
'message' => 'Student not found',
@@ -594,7 +591,7 @@ class AttendanceTrackingService
}
$student = $student->toArray();
$student['name'] = trim(($student['firstname'] ?? '').' '.($student['lastname'] ?? ''));
$student['name'] = trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''));
$codeParam = strtoupper((string) ($codeParam ?? ''));
$incidentDate = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $incidentDate) ? (string) $incidentDate : '';
@@ -659,7 +656,7 @@ class AttendanceTrackingService
])
->where(function ($q) use ($studentIdValues, $studentCodeValues) {
$q->whereIn('student_id', $studentIdValues);
if (! empty($studentCodeValues)) {
if (!empty($studentCodeValues)) {
$q->orWhereIn('student_id', $studentCodeValues);
}
})
@@ -677,7 +674,7 @@ class AttendanceTrackingService
if ($pendingOnly) {
$this->applyUnreportedAttendanceFilter($qb);
if (! $includeNotified) {
if (!$includeNotified) {
$qb->whereRaw("(LOWER(TRIM(COALESCE(is_notified, ''))) NOT IN ('yes','1'))");
}
}
@@ -703,11 +700,11 @@ class AttendanceTrackingService
'semester' => $semester,
];
if ($data['violation_date'] === '' && ! empty($data['attendance'][0]['date'])) {
if ($data['violation_date'] === '' && !empty($data['attendance'][0]['date'])) {
$data['violation_date'] = substr((string) $data['attendance'][0]['date'], 0, 10);
}
if (! empty($data['attendance'][0]['is_notified'])) {
if (!empty($data['attendance'][0]['is_notified'])) {
$data['violation_notified'] = $data['attendance'][0]['is_notified'];
}
@@ -785,17 +782,15 @@ class AttendanceTrackingService
$to = trim((string) ($v['parent_email'] ?? ''));
$pname = (string) ($v['parent_name'] ?? '');
if ($sid <= 0 || ! $code || ! $date || ! $to) {
if ($sid <= 0 || !$code || !$date || !$to) {
$errors++;
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'missing data'];
continue;
}
if ($this->notificationAlreadySent($sid, $code, $date, 'email', $to)) {
$skipped++;
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'duplicate'];
continue;
}
@@ -816,7 +811,7 @@ class AttendanceTrackingService
$tpl = $this->renderTemplate($code, $variant, $context);
if (! $tpl) {
if (!$tpl) {
$subject = match ($code) {
'ABS_1' => 'Attendance Notice: Unreported Absence',
'LATE_2' => 'Attendance Notice: Repeated Lateness',
@@ -824,14 +819,14 @@ class AttendanceTrackingService
};
$studentName = (string) ($v['name'] ?? '');
$body = '<p>Dear '.($pname ?: 'Parent/Guardian').'</p>'
."<p>We'd like to inform you about your student's recent attendance:</p>"
.'<ul>'
."<li><strong>Student:</strong> {$studentName}</li>"
.'<li><strong>Issue:</strong> '.(string) ($v['violation'] ?? '').'</li>'
."<li><strong>As of:</strong> {$date}</li>"
.'</ul>'
.'<p>If you have any questions, please contact the school office.</p>';
$body = "<p>Dear " . ($pname ?: 'Parent/Guardian') . "</p>"
. "<p>We'd like to inform you about your student's recent attendance:</p>"
. "<ul>"
. "<li><strong>Student:</strong> {$studentName}</li>"
. "<li><strong>Issue:</strong> " . (string) ($v['violation'] ?? '') . "</li>"
. "<li><strong>As of:</strong> {$date}</li>"
. "</ul>"
. "<p>If you have any questions, please contact the school office.</p>";
} else {
[$subject, $body] = $tpl;
}
@@ -854,7 +849,7 @@ class AttendanceTrackingService
} catch (Throwable $e) {
$errors++;
$this->logNotification($sid, $code, $date, 'email', $to, $subject, 'failed', $e->getMessage());
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'error: '.$e->getMessage()];
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'error: ' . $e->getMessage()];
}
try {
@@ -880,7 +875,7 @@ class AttendanceTrackingService
}
} catch (Throwable $e) {
$errors++;
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'cc_error: '.$e->getMessage()];
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'cc_error: ' . $e->getMessage()];
}
if ($anyOk) {
@@ -900,10 +895,10 @@ class AttendanceTrackingService
$absDates = array_map(fn ($d) => substr((string) $d, 0, 10), (array) ($v['absences'] ?? []));
$lateDates = array_map(fn ($d) => substr((string) $d, 0, 10), (array) ($v['lates'] ?? []));
if (! empty($absDates)) {
if (!empty($absDates)) {
$allDates = array_merge($allDates, $absDates);
}
if (! empty($lateDates)) {
if (!empty($lateDates)) {
$allDates = array_merge($allDates, $lateDates);
}
if (empty($allDates)) {
@@ -1039,7 +1034,7 @@ class AttendanceTrackingService
foreach ($rows as $row) {
$sid = (int) ($row->student_id ?? 0);
if ($sid > 0 && ! isset($classByStudent[$sid])) {
if ($sid > 0 && !isset($classByStudent[$sid])) {
$classByStudent[$sid] = [
'class_section_id' => $row->class_section_id ?? null,
'class_section_name' => (string) ($row->class_section_name ?? ''),
@@ -1054,7 +1049,7 @@ class AttendanceTrackingService
$mergedData = [];
foreach ($trackingData as $row) {
$sid = (int) ($row['student_id'] ?? 0);
if (! isset($studentMap[$sid])) {
if (!isset($studentMap[$sid])) {
continue;
}
@@ -1062,7 +1057,7 @@ class AttendanceTrackingService
if (isset($classByStudent[$sid])) {
$merged['class_section_name'] = (string) ($classByStudent[$sid]['class_section_name'] ?? '');
$merged['class_name'] = (string) ($classByStudent[$sid]['class_name'] ?? '');
} elseif (! empty($merged['registration_grade'])) {
} elseif (!empty($merged['registration_grade'])) {
$merged['grade'] = (string) $merged['registration_grade'];
}
@@ -1106,7 +1101,7 @@ class AttendanceTrackingService
$violation = [
'id' => $studentId,
'name' => trim(($student['firstname'] ?? '').' '.($student['lastname'] ?? '')),
'name' => trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? '')),
'last_date' => $lastDate,
'violation' => $code,
'violation_code' => $code,
@@ -1115,7 +1110,7 @@ class AttendanceTrackingService
$ctx = $this->buildTemplateContext($violation, $parent);
$rendered = $this->renderTemplate($code, $variant, $ctx);
if (! $rendered) {
if (!$rendered) {
return [
'success' => false,
'message' => "Template not found for {$code} ({$variant}).",
@@ -1193,7 +1188,7 @@ class AttendanceTrackingService
$sec = $this->getSecondaryParentForStudent($sid);
$to2 = trim((string) ($sec['email'] ?? ''));
if ($to2 !== '' && strcasecmp($to2, $to) !== 0) {
if (! $this->notificationAlreadySent($sid, $code, $ymd, 'email', $to2)) {
if (!$this->notificationAlreadySent($sid, $code, $ymd, 'email', $to2)) {
$ok2 = $this->attendanceMailerService->send($to2, $subject, $wrapped);
$this->logNotification(
$sid,
@@ -1211,7 +1206,7 @@ class AttendanceTrackingService
}
}
if (! $anyOk) {
if (!$anyOk) {
return [
'success' => false,
'message' => 'Failed to send email.',
@@ -1256,7 +1251,7 @@ class AttendanceTrackingService
return [
'success' => false,
'message' => 'Error: '.$e->getMessage(),
'message' => 'Error: ' . $e->getMessage(),
'status' => 500,
];
}
@@ -1278,7 +1273,7 @@ class AttendanceTrackingService
->where('id', $studentId)
->first();
if (! $stu) {
if (!$stu) {
return [
'success' => false,
'message' => 'Student not found',
@@ -1303,7 +1298,7 @@ class AttendanceTrackingService
] : null;
$pb = DB::table('parents')->where('firstparent_id', $primaryId);
if (! empty($schoolYear)) {
if (!empty($schoolYear)) {
$pb->where('school_year', $schoolYear);
}
@@ -1330,7 +1325,7 @@ class AttendanceTrackingService
}
}
if (! $secondary) {
if (!$secondary) {
$fallbackEmail = (string) ($pRow->secondparent_email ?? '');
$fallbackPhone = (string) ($pRow->secondparent_phone ?? '');
$fallbackFirst = (string) ($pRow->secondparent_firstname ?? '');
@@ -1356,7 +1351,7 @@ class AttendanceTrackingService
],
];
} catch (Throwable $e) {
Log::error('parentsInfo() failed: '.$e->getMessage());
Log::error('parentsInfo() failed: ' . $e->getMessage());
return [
'success' => false,
@@ -1384,11 +1379,11 @@ class AttendanceTrackingService
->where('school_year', $this->schoolYear)
->where('date', '>=', $start)
->where('date', '<', $end)
->where('reason', 'like', '%'.$code.'%')
->where('reason', 'like', '%' . $code . '%')
->orderByDesc('date')
->first();
if (! $row) {
if (!$row) {
$row = $this->attendanceTrackingModel->query()
->where('student_id', $sid)
->where('semester', $this->semester)
@@ -1399,7 +1394,7 @@ class AttendanceTrackingService
->first();
}
if ($row && ! empty($row->id)) {
if ($row && !empty($row->id)) {
DB::table($this->attendanceTrackingModel->getTable())
->where('id', (int) $row->id)
->update([
@@ -1431,7 +1426,7 @@ class AttendanceTrackingService
} catch (Throwable $e) {
return [
'success' => false,
'message' => 'Failed to save note: '.$e->getMessage(),
'message' => 'Failed to save note: ' . $e->getMessage(),
'status' => 500,
];
}
@@ -1455,14 +1450,13 @@ class AttendanceTrackingService
->where('incident_date', $ymd)
->where('channel', $channel);
if (! empty($to)) {
if (!empty($to)) {
$query->where('to_address', $to);
}
return $query->exists();
} catch (Throwable $e) {
Log::debug('notificationAlreadySent(): '.$e->getMessage());
Log::debug('notificationAlreadySent(): ' . $e->getMessage());
return false;
}
}
@@ -1485,7 +1479,7 @@ class AttendanceTrackingService
'channel' => $channel,
];
if (! empty($to)) {
if (!empty($to)) {
$where['to_address'] = $to;
}
@@ -1494,7 +1488,7 @@ class AttendanceTrackingService
->orderByDesc('id')
->first();
if ($existing && ! empty($existing->id)) {
if ($existing && !empty($existing->id)) {
$existing->update([
'subject' => $subject,
'status' => $status,
@@ -1518,7 +1512,7 @@ class AttendanceTrackingService
]);
}
} catch (Throwable $e) {
Log::debug('logNotification(): '.$e->getMessage());
Log::debug('logNotification(): ' . $e->getMessage());
}
}
@@ -1530,7 +1524,7 @@ class AttendanceTrackingService
->where('s.id', $studentId)
->first();
if (! $row || empty($row->user_id)) {
if (!$row || empty($row->user_id)) {
return null;
}
@@ -1550,7 +1544,7 @@ class AttendanceTrackingService
->where('id', $studentId)
->first();
if (! $stu) {
if (!$stu) {
return null;
}
@@ -1563,7 +1557,7 @@ class AttendanceTrackingService
}
$pRow = $pb->orderByDesc('updated_at')->first();
if (! $pRow) {
if (!$pRow) {
return null;
}
@@ -1574,11 +1568,11 @@ class AttendanceTrackingService
->where('id', $secondId)
->first();
if ($u2 && ! empty($u2->email)) {
if ($u2 && !empty($u2->email)) {
return [
'user_id' => (int) $u2->id,
'email' => (string) $u2->email,
'parent_name' => trim(($u2->firstname ?? '').' '.($u2->lastname ?? '')),
'parent_name' => trim(($u2->firstname ?? '') . ' ' . ($u2->lastname ?? '')),
'phone' => (string) ($u2->cellphone ?? ''),
];
}
@@ -1593,12 +1587,12 @@ class AttendanceTrackingService
return [
'user_id' => $secondId ?: null,
'email' => $fallbackEmail,
'parent_name' => trim($fallbackFirst.' '.$fallbackLast) ?: null,
'parent_name' => trim($fallbackFirst . ' ' . $fallbackLast) ?: null,
'phone' => $fallbackPhone,
];
}
} catch (Throwable $e) {
Log::error('getSecondaryParentForStudent() failed: '.$e->getMessage());
Log::error('getSecondaryParentForStudent() failed: ' . $e->getMessage());
}
return null;
@@ -1637,7 +1631,7 @@ class AttendanceTrackingService
$ymd = substr((string) ($r['date'] ?? ''), 0, 10);
$stat = strtolower(trim((string) ($r['status'] ?? '')));
if (! in_array($stat, ['absent', 'late'], true)) {
if (!in_array($stat, ['absent', 'late'], true)) {
continue;
}
@@ -1649,10 +1643,10 @@ class AttendanceTrackingService
[$syStart, $syEnd] = $this->deriveSchoolYearBounds($schoolYear);
$weekRowsSource = null;
if (! empty($weekRowsFallback)) {
if (!empty($weekRowsFallback)) {
foreach ($weekRowsFallback as $r) {
$st = strtolower(trim((string) ($r['status'] ?? '')));
if ($st !== '' && ! in_array($st, ['absent', 'late'], true)) {
if ($st !== '' && !in_array($st, ['absent', 'late'], true)) {
$weekRowsSource = $weekRowsFallback;
break;
}
@@ -1685,7 +1679,6 @@ class AttendanceTrackingService
}
$out = array_values(array_unique($out));
rsort($out);
return $out;
};
@@ -1696,7 +1689,7 @@ class AttendanceTrackingService
$students
)));
if (! empty($studentIdsForClass)) {
if (!empty($studentIdsForClass)) {
$rows = DB::table('student_class as sc')
->select([
'sc.student_id',
@@ -1714,7 +1707,7 @@ class AttendanceTrackingService
foreach ($rows as $row) {
$sid = (int) ($row->student_id ?? 0);
if ($sid > 0 && ! isset($classByStudent[$sid])) {
if ($sid > 0 && !isset($classByStudent[$sid])) {
$classByStudent[$sid] = [
'class_section_id' => $row->class_section_id ?? null,
'class_section_name' => (string) ($row->class_section_name ?? ''),
@@ -1725,7 +1718,7 @@ class AttendanceTrackingService
}
}
} catch (Throwable $e) {
Log::debug('computeViolations(): class prefetch failed: '.$e->getMessage());
Log::debug('computeViolations(): class prefetch failed: ' . $e->getMessage());
}
$out = [];
@@ -1734,7 +1727,7 @@ class AttendanceTrackingService
foreach ($students as $stu) {
$sid = (int) ($stu['id'] ?? 0);
$name = trim(($stu['firstname'] ?? '').' '.($stu['lastname'] ?? ''));
$name = trim(($stu['firstname'] ?? '') . ' ' . ($stu['lastname'] ?? ''));
$absDatesAll = array_values(array_unique($byStudent[$sid]['absent'] ?? []));
$lateDatesAll = array_values(array_unique($byStudent[$sid]['late'] ?? []));
@@ -1752,7 +1745,7 @@ class AttendanceTrackingService
$lateCountLast5 += count($lateDates);
$absenceViolation = null;
if (! empty($absDates)) {
if (!empty($absDates)) {
$lastAbsDate = $absDates[0];
$A2row = $this->hasNConsecutiveItems($absDates, 2, 7);
$A3row = $this->hasNConsecutiveItems($absDates, 3, 7);
@@ -1799,7 +1792,7 @@ class AttendanceTrackingService
}
$lateViolation = null;
if (! empty($lateDates)) {
if (!empty($lateDates)) {
$lastLateDate = $lateDates[0];
$L2row = $this->hasNConsecutiveItems($lateDates, 2, 7);
@@ -1814,7 +1807,7 @@ class AttendanceTrackingService
$lateWeeksSet = array_flip($lateWeekIdx);
$lateCoversAllWindowWeeks = true;
for ($i = $windowStartIdx; $i <= $currentWeekIdx; $i++) {
if (! isset($lateWeeksSet[$i])) {
if (!isset($lateWeeksSet[$i])) {
$lateCoversAllWindowWeeks = false;
break;
}
@@ -1865,7 +1858,7 @@ class AttendanceTrackingService
$chosen = $this->chooseHigherSeverity($absenceViolation, $lateViolation);
if (! $chosen && count($absDates) === 1) {
if (!$chosen && count($absDates) === 1) {
$chosen = [
'type' => 'absence',
'code' => 'ABS_1',
@@ -1878,7 +1871,7 @@ class AttendanceTrackingService
];
}
if (! $chosen) {
if (!$chosen) {
continue;
}
@@ -1890,7 +1883,7 @@ class AttendanceTrackingService
->where('school_year', $schoolYear)
->where('date', '>=', $start)
->where('date', '<', $end)
->where('reason', 'like', '%'.$chosen['code'].'%');
->where('reason', 'like', '%' . $chosen['code'] . '%');
if ($semester !== null) {
$trackingQ->where('semester', $semester);
@@ -1904,7 +1897,7 @@ class AttendanceTrackingService
$cls = $classByStudent[$sid] ?? [];
$classLabel = (string) ($cls['class_section_name'] ?? '');
if ($classLabel === '' && ! empty($cls['class_name'])) {
if ($classLabel === '' && !empty($cls['class_name'])) {
$classLabel = (string) $cls['class_name'];
}
@@ -1954,7 +1947,6 @@ class AttendanceTrackingService
if ($a && $b) {
if ($a['severity'] === $b['severity']) {
$prio = ['expel_notify' => 3, 'team_notify' => 2, 'auto_email' => 1];
return ($prio[$a['action']] ?? 0) >= ($prio[$b['action']] ?? 0) ? $a : $b;
}
@@ -1984,11 +1976,11 @@ class AttendanceTrackingService
{
$cols = $this->attendanceReportedColumns();
if (! empty($cols['is_reported'])) {
if (!empty($cols['is_reported'])) {
$qb->whereRaw("(LOWER(TRIM(COALESCE(is_reported, ''))) NOT IN ('yes','1','true','y','on'))");
}
if (! empty($cols['reported'])) {
if (!empty($cols['reported'])) {
$qb->whereRaw("(LOWER(TRIM(COALESCE(reported, ''))) NOT IN ('yes','1','true','y','on'))");
}
@@ -2010,10 +2002,9 @@ class AttendanceTrackingService
protected function dayBounds(string $ymd): array
{
$d = substr($ymd, 0, 10);
return [
$d.' 00:00:00',
date('Y-m-d', strtotime($d.' +1 day')).' 00:00:00',
$d . ' 00:00:00',
date('Y-m-d', strtotime($d . ' +1 day')) . ' 00:00:00',
];
}
@@ -2033,10 +2024,9 @@ class AttendanceTrackingService
protected function deriveSchoolYearBounds(string $schoolYear): array
{
if (! preg_match('/^(\d{4})-(\d{4})$/', $schoolYear, $m)) {
if (!preg_match('/^(\d{4})-(\d{4})$/', $schoolYear, $m)) {
$y = (int) date('Y');
$startY = (int) (date('n') >= 8 ? $y : $y - 1);
return [sprintf('%d-08-01', $startY), sprintf('%d-07-31', $startY + 1)];
}
@@ -2076,7 +2066,7 @@ class AttendanceTrackingService
->where('is_active', 1)
->first();
if (! $row) {
if (!$row) {
$row = $this->attendanceEmailTemplateModel->query()
->where('code', $code)
->where('variant', 'default')
@@ -2087,7 +2077,7 @@ class AttendanceTrackingService
$row = $row?->toArray();
}
if (! $row) {
if (!$row) {
return null;
}
@@ -2145,10 +2135,10 @@ class AttendanceTrackingService
$semester = ($semester !== null && $semester !== '') ? (string) $semester : null;
$weeks = [];
if (! empty($weekRowsFallback)) {
if (!empty($weekRowsFallback)) {
foreach ($weekRowsFallback as $r) {
$d = $r['date'] ?? null;
if (! $d) {
if (!$d) {
continue;
}
$ts = strtotime($d);
@@ -2205,38 +2195,25 @@ class AttendanceTrackingService
}
$idx = array_keys($set);
sort($idx);
return $idx;
}
protected function windowWeeksForViolationCode(string $code): int
{
$code = strtoupper(trim($code));
if ($code === '') {
return 5;
}
if (Str::startsWith($code, 'ABS_2') || Str::startsWith($code, 'LATE_2')) {
return 3;
}
if (Str::startsWith($code, 'ABS_3') || Str::startsWith($code, 'LATE_3') || Str::startsWith($code, 'MIX')) {
return 4;
}
if (Str::startsWith($code, 'LATE_4')) {
return 4;
}
if (Str::startsWith($code, 'ABS_4')) {
return 5;
}
if ($code === '') return 5;
if (Str::startsWith($code, 'ABS_2') || Str::startsWith($code, 'LATE_2')) return 3;
if (Str::startsWith($code, 'ABS_3') || Str::startsWith($code, 'LATE_3') || Str::startsWith($code, 'MIX')) return 4;
if (Str::startsWith($code, 'LATE_4')) return 4;
if (Str::startsWith($code, 'ABS_4')) return 5;
return 5;
}
protected function isoWeekStartYmd(string $weekKey): string
{
if (preg_match('/^(\d{4})-W(\d{2})$/', $weekKey, $m)) {
return date('Y-m-d', strtotime($m[1].'-W'.$m[2].'-1'));
return date('Y-m-d', strtotime($m[1] . '-W' . $m[2] . '-1'));
}
return date('Y-m-d');
}
@@ -2257,15 +2234,14 @@ class AttendanceTrackingService
if (empty($activeWeekKeys)) {
$days = ($windowWeeks * 7) - 1;
return date('Y-m-d', strtotime($endBound.' -'.$days.' days'));
return date('Y-m-d', strtotime($endBound . ' -' . $days . ' days'));
}
$activeWeekKeys = array_values($activeWeekKeys);
$weekIndex = array_flip($activeWeekKeys);
$endWeekKey = date('o-\WW', strtotime($endBound));
if (! isset($weekIndex[$endWeekKey])) {
if (!isset($weekIndex[$endWeekKey])) {
$endWeekKey = null;
for ($i = count($activeWeekKeys) - 1; $i >= 0; $i--) {
$wkStart = $this->isoWeekStartYmd($activeWeekKeys[$i]);
@@ -2289,9 +2265,7 @@ class AttendanceTrackingService
protected function hasNConsecutiveItems(array $datesDesc, int $n, int $daysApart): bool
{
$N = count($datesDesc);
if ($N < $n) {
return false;
}
if ($N < $n) return false;
$dates = $datesDesc;
sort($dates);
@@ -2304,9 +2278,7 @@ class AttendanceTrackingService
if ($diff === $daysApart) {
$run++;
if ($run >= $n) {
return true;
}
if ($run >= $n) return true;
} else {
$run = 1;
}
@@ -2318,9 +2290,7 @@ class AttendanceTrackingService
protected function hasNInWActiveWeeks(array $weekIdx, int $n, int $w): bool
{
$N = count($weekIdx);
if ($N < $n) {
return false;
}
if ($N < $n) return false;
$l = 0;
for ($r = 0; $r < $N; $r++) {
@@ -2337,9 +2307,7 @@ class AttendanceTrackingService
protected function twoLatesOneAbsInWWeeks(array $lateIdx, array $absIdx, int $w): bool
{
if (count($lateIdx) < 2 || count($absIdx) < 1) {
return false;
}
if (count($lateIdx) < 2 || count($absIdx) < 1) return false;
$L = $lateIdx;
$A = $absIdx;
@@ -2354,7 +2322,6 @@ class AttendanceTrackingService
if ($L[$iL2] > $windowEnd) {
$iL1++;
$iL2 = $iL1 + 1;
continue;
}
@@ -2375,4 +2342,4 @@ class AttendanceTrackingService
return false;
}
}
}
@@ -9,7 +9,7 @@ class SemesterRangeServiceTest extends TestCase
{
public function test_normalize_semester(): void
{
$service = new SemesterRangeService;
$service = new SemesterRangeService();
$this->assertSame('Fall', $service->normalizeSemester('fall'));
$this->assertSame('Spring', $service->normalizeSemester('SPRING'));
@@ -18,7 +18,7 @@ class SemesterRangeServiceTest extends TestCase
public function test_get_school_year_range(): void
{
$service = new SemesterRangeService;
$service = new SemesterRangeService();
[$start, $end] = $service->getSchoolYearRange('2025-2026');
@@ -28,7 +28,7 @@ class SemesterRangeServiceTest extends TestCase
public function test_build_sunday_list(): void
{
$service = new SemesterRangeService;
$service = new SemesterRangeService();
$sundays = $service->buildSundayList('2025-09-01', '2025-09-30');
@@ -37,4 +37,4 @@ class SemesterRangeServiceTest extends TestCase
$this->assertContains('2025-09-21', $sundays);
$this->assertContains('2025-09-28', $sundays);
}
}
}
@@ -2,11 +2,6 @@
namespace Tests\Unit\Services\Attendance;
use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\StaffAttendance;
use App\Models\TeacherClass;
use App\Services\Attendance\SemesterRangeService;
use App\Services\Attendance\StaffAttendanceService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
@@ -80,11 +75,11 @@ class StaffAttendanceServiceTest extends TestCase
]);
$service = new StaffAttendanceService(
new Configuration,
new StaffAttendance,
new TeacherClass,
new ClassSection,
new SemesterRangeService
new \App\Models\Configuration(),
new \App\Models\StaffAttendance(),
new \App\Models\TeacherClass(),
new \App\Models\ClassSection(),
new \App\Services\Attendance\SemesterRangeService()
);
$payload = $service->monthData('Fall', '2025-2026');
@@ -2,8 +2,6 @@
namespace Tests\Unit\Services\Attendance;
use App\Models\AttendanceData;
use App\Models\Student;
use App\Services\Attendance\AttendanceRecordSyncService;
use App\Services\Attendance\StudentAttendanceWriterService;
use Illuminate\Foundation\Testing\RefreshDatabase;
@@ -31,7 +29,7 @@ class StudentAttendanceWriterServiceTest extends TestCase
]);
$sync = Mockery::mock(AttendanceRecordSyncService::class);
$service = new StudentAttendanceWriterService(new AttendanceData, new Student, $sync);
$service = new StudentAttendanceWriterService(new \App\Models\AttendanceData(), new \App\Models\Student(), $sync);
$this->assertSame('S1', $service->resolveStudentSchoolId(1, null));
}
@@ -67,7 +65,7 @@ class StudentAttendanceWriterServiceTest extends TestCase
$sync = Mockery::mock(AttendanceRecordSyncService::class);
$sync->shouldReceive('updateAttendanceRecord')->once();
$service = new StudentAttendanceWriterService(new AttendanceData, new Student, $sync);
$service = new StudentAttendanceWriterService(new \App\Models\AttendanceData(), new \App\Models\Student(), $sync);
$service->saveOrUpdateStudentAttendance([
'class_section_id' => 1,
@@ -2,16 +2,7 @@
namespace Tests\Unit\Services\Attendance;
use App\Models\AttendanceData;
use App\Models\AttendanceDay;
use App\Models\AttendanceRecord;
use App\Models\Student;
use App\Models\TeacherClass;
use App\Models\User;
use App\Services\Attendance\AttendanceAutoPublishService;
use App\Services\Attendance\AttendancePolicyService;
use App\Services\Attendance\AttendanceRecordSyncService;
use App\Services\Attendance\StudentAttendanceWriterService;
use App\Services\Attendance\TeacherAttendanceSubmissionService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
@@ -35,21 +26,21 @@ class TeacherAttendanceSubmissionServiceTest extends TestCase
$user = $this->seedUser();
$policy = Mockery::mock(AttendancePolicyService::class);
$policy = Mockery::mock(\App\Services\Attendance\AttendancePolicyService::class);
$policy->shouldReceive('canEditDay')->andReturn(true);
$service = new TeacherAttendanceSubmissionService(
new AttendanceDay,
new AttendanceData,
new TeacherClass,
new Student,
new \App\Models\AttendanceDay(),
new \App\Models\AttendanceData(),
new \App\Models\TeacherClass(),
new \App\Models\Student(),
$policy,
new StudentAttendanceWriterService(
new AttendanceData,
new Student,
new AttendanceRecordSyncService(new AttendanceRecord)
new \App\Services\Attendance\StudentAttendanceWriterService(
new \App\Models\AttendanceData(),
new \App\Models\Student(),
new \App\Services\Attendance\AttendanceRecordSyncService(new \App\Models\AttendanceRecord())
),
new AttendanceAutoPublishService
new \App\Services\Attendance\AttendanceAutoPublishService()
);
$this->expectException(\RuntimeException::class);