academico-sis /
academico
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace App\Http\Controllers; |
||||
| 4 | |||||
| 5 | use App\Models\Attendance; |
||||
| 6 | use App\Models\AttendanceType; |
||||
| 7 | use App\Models\Course; |
||||
| 8 | use App\Models\Event; |
||||
| 9 | use App\Models\Student; |
||||
| 10 | use App\Traits\PeriodSelection; |
||||
| 11 | use Carbon\Carbon; |
||||
| 12 | use Illuminate\Http\Request; |
||||
| 13 | use Illuminate\Support\Facades\Gate; |
||||
| 14 | use Illuminate\Support\Facades\Log; |
||||
| 15 | use Prologue\Alerts\Facades\Alert; |
||||
| 16 | |||||
| 17 | class AttendanceController extends Controller |
||||
| 18 | { |
||||
| 19 | use PeriodSelection; |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 20 | |||||
| 21 | public function __construct() |
||||
| 22 | { |
||||
| 23 | parent::__construct(); |
||||
| 24 | $this->middleware('permission:attendance.view', ['except' => ['showCourse', 'showEvent', 'showStudentAttendanceForCourse', 'store']]); |
||||
| 25 | } |
||||
| 26 | |||||
| 27 | /** |
||||
| 28 | * Monitor attendance for all students. |
||||
| 29 | */ |
||||
| 30 | public function index(Request $request) |
||||
| 31 | { |
||||
| 32 | Log::info('Attendance dashboard viewed by '.backpack_user()->id); |
||||
|
0 ignored issues
–
show
|
|||||
| 33 | $selected_period = $this->selectPeriod($request); |
||||
| 34 | |||||
| 35 | // student attendance overview |
||||
| 36 | $absences = (new Attendance())->get_absence_count_per_student($selected_period); |
||||
| 37 | |||||
| 38 | // get all courses for period and preload relations |
||||
| 39 | $courses = $selected_period->courses()->whereHas('events')->whereHas('enrollments')->with('attendance')->with('events')->get(); |
||||
| 40 | |||||
| 41 | // loop through all courses and get the number of events with incomplete attendance |
||||
| 42 | foreach ($courses as $course) { |
||||
| 43 | $eventsWithMissingAttendanceCount = 0; |
||||
| 44 | $coursesdata[$course->id]['name'] = $course->name; |
||||
| 45 | $coursesdata[$course->id]['id'] = $course->id; |
||||
| 46 | $coursesdata[$course->id]['exempt_attendance'] = $course->exempt_attendance; |
||||
| 47 | $coursesdata[$course->id]['teachername'] = $course->course_teacher_name; |
||||
| 48 | |||||
| 49 | foreach ($course->eventsWithExpectedAttendance as $event) { |
||||
| 50 | foreach ($course->enrollments as $enrollment) { |
||||
| 51 | // if a student has no attendance record for the class (event) |
||||
| 52 | $hasNotAttended = $course->attendance->where('student_id', $enrollment->student_id) |
||||
| 53 | ->where('event_id', $event->id) |
||||
| 54 | ->isEmpty(); |
||||
| 55 | |||||
| 56 | // count one and break loop |
||||
| 57 | if ($hasNotAttended) { |
||||
| 58 | $eventsWithMissingAttendanceCount++; |
||||
| 59 | break; |
||||
| 60 | } |
||||
| 61 | } |
||||
| 62 | } |
||||
| 63 | |||||
| 64 | $coursesdata[$course->id]['missing'] = $eventsWithMissingAttendanceCount; |
||||
| 65 | } |
||||
| 66 | |||||
| 67 | // sort by number of events with missing attendance |
||||
| 68 | $courses = collect($coursesdata ?? [])->sortByDesc('missing')->toArray(); |
||||
| 69 | $isadmin = backpack_user()->hasPermissionTo('courses.edit'); |
||||
|
0 ignored issues
–
show
The method
hasPermissionTo() does not exist on Illuminate\Contracts\Auth\Authenticatable. It seems like you code against a sub-type of Illuminate\Contracts\Auth\Authenticatable such as Illuminate\Foundation\Auth\User.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 70 | |||||
| 71 | return view('attendance.monitor', compact('absences', 'courses', 'selected_period', 'isadmin')); |
||||
| 72 | } |
||||
| 73 | |||||
| 74 | /** |
||||
| 75 | * Store a newly created attendance record. |
||||
| 76 | */ |
||||
| 77 | public function store(Request $request) |
||||
| 78 | { |
||||
| 79 | $event = Event::findOrFail($request->input('event_id')); |
||||
| 80 | |||||
| 81 | // If the user is not allowed to perform this action |
||||
| 82 | if (Gate::forUser(backpack_user())->denies('edit-attendance', $event)) { |
||||
| 83 | abort(403); |
||||
| 84 | } |
||||
| 85 | |||||
| 86 | $student = Student::findOrFail($request->input('student_id')); |
||||
| 87 | $attendance_type = AttendanceType::findOrFail($request->input('attendance_type_id')); |
||||
| 88 | |||||
| 89 | $attendance = Attendance::firstOrNew([ |
||||
| 90 | 'student_id' => $student->id, |
||||
| 91 | 'event_id' => $event->id, |
||||
| 92 | ]); |
||||
| 93 | |||||
| 94 | $attendance->attendance_type_id = $attendance_type->id; |
||||
| 95 | |||||
| 96 | $attendance->save(); |
||||
| 97 | |||||
| 98 | Log::info('Attendance recorded by '.backpack_user()->id); |
||||
|
0 ignored issues
–
show
|
|||||
| 99 | |||||
| 100 | return $attendance; |
||||
| 101 | } |
||||
| 102 | |||||
| 103 | /** |
||||
| 104 | * Show the attendance records for a course. |
||||
| 105 | */ |
||||
| 106 | public function showCourse(Course $course) |
||||
| 107 | { |
||||
| 108 | |||||
| 109 | // The current is not allowed to view the page |
||||
| 110 | if (Gate::forUser(backpack_user())->denies('view-course-attendance', $course)) { |
||||
| 111 | abort(403); |
||||
| 112 | } |
||||
| 113 | |||||
| 114 | // get past events for the course |
||||
| 115 | $events = $course->events->filter(fn ($value, $key) => Carbon::parse($value->start) < Carbon::now())->sortByDesc('start'); |
||||
|
0 ignored issues
–
show
The parameter
$key is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||
| 116 | |||||
| 117 | // if the course has any past events |
||||
| 118 | if (($events->count() == 0) || ($course->enrollments()->count() == 0)) { |
||||
| 119 | Alert::add('error', 'This course has no events.')->flash(); |
||||
| 120 | |||||
| 121 | return redirect()->back(); |
||||
| 122 | } |
||||
| 123 | |||||
| 124 | $enrollments = $course->enrollments()->with('student')->get(); |
||||
| 125 | $attendances = []; |
||||
| 126 | |||||
| 127 | foreach ($enrollments as $enrollment) { |
||||
| 128 | foreach ($events as $event) { |
||||
| 129 | if ($event->exempt_attendance == 1) { |
||||
| 130 | $attendances[$enrollment->student->id][]['attendance'] = ''; |
||||
| 131 | } else { |
||||
| 132 | $attendances[$enrollment->student->id]['student'] = $enrollment->student->firstname.' '.$enrollment->student->lastname; |
||||
| 133 | $attendances[$enrollment->student->id][]['attendance'] = $event->attendance->where('student_id', $enrollment->student_id)->first(); |
||||
| 134 | } |
||||
| 135 | } |
||||
| 136 | } |
||||
| 137 | Log::info('Attendance for course viewed by '.backpack_user()->id); |
||||
|
0 ignored issues
–
show
|
|||||
| 138 | |||||
| 139 | $isadmin = backpack_user()->hasPermissionTo('courses.edit'); |
||||
| 140 | |||||
| 141 | return view('attendance/course', compact('attendances', 'isadmin', 'course', 'events')); |
||||
| 142 | } |
||||
| 143 | |||||
| 144 | public function showEvent(Event $event) |
||||
| 145 | { |
||||
| 146 | |||||
| 147 | // The current is not allowed to view the page |
||||
| 148 | if (Gate::forUser(backpack_user())->denies('view-event-attendance', $event)) { |
||||
| 149 | abort(403); |
||||
| 150 | } |
||||
| 151 | |||||
| 152 | // get students |
||||
| 153 | $enrollments = $event->enrollments()->with('student')->get(); |
||||
| 154 | |||||
| 155 | // get the attendance record for the event |
||||
| 156 | $attendance = $event->attendance; |
||||
| 157 | |||||
| 158 | $attendances = []; |
||||
| 159 | |||||
| 160 | $attendance_types = AttendanceType::all(); |
||||
| 161 | |||||
| 162 | // build a collection : for each student, display attendance |
||||
| 163 | |||||
| 164 | foreach ($enrollments as $enrollment) { |
||||
| 165 | $attendances[$enrollment->student->id]['student'] = $enrollment->student->name; |
||||
| 166 | $attendances[$enrollment->student->id]['student_id'] = $enrollment->student->id; |
||||
| 167 | $attendances[$enrollment->student->id]['attendance'] = $attendance->where('student_id', $enrollment->student->id)->first() ?? '[attendance][attendance_type_id]'; |
||||
| 168 | } |
||||
| 169 | Log::info('Attendance for event viewed by '.backpack_user()->id); |
||||
|
0 ignored issues
–
show
|
|||||
| 170 | |||||
| 171 | return view('attendance/event', compact('attendances', 'event', 'attendance_types')); |
||||
| 172 | } |
||||
| 173 | |||||
| 174 | public function showStudentAttendanceForCourse(Student $student, Request $request) |
||||
| 175 | { |
||||
| 176 | if ($request->query('course_id') == null) { |
||||
|
0 ignored issues
–
show
|
|||||
| 177 | $selectedCourse = $student->enrollments->last()->course; |
||||
| 178 | } else { |
||||
| 179 | $selectedCourse = Course::find($request->query('course_id')); |
||||
| 180 | } |
||||
| 181 | |||||
| 182 | // If the current is not allowed to view the page |
||||
| 183 | if (Gate::forUser(backpack_user())->denies('view-course-attendance', $selectedCourse)) { |
||||
| 184 | abort(403); |
||||
| 185 | } |
||||
| 186 | |||||
| 187 | $studentEnrollments = $student->enrollments()->with('course')->get(); |
||||
| 188 | $courseEventIds = $selectedCourse->events->pluck('id'); |
||||
| 189 | |||||
| 190 | $attendances = $student->attendance()->with('event')->get()->whereIn('event_id', $courseEventIds); |
||||
| 191 | $enrollment = $studentEnrollments->where('course_id', $selectedCourse->id)->first(); |
||||
| 192 | $attendanceratio = $enrollment->attendance_ratio; |
||||
| 193 | |||||
| 194 | return view('attendance.student', compact('student', 'selectedCourse', 'studentEnrollments', 'attendances', 'attendanceratio')); |
||||
| 195 | } |
||||
| 196 | |||||
| 197 | public function toggleEventAttendanceStatus(Event $event, Request $request) |
||||
| 198 | { |
||||
| 199 | if (! backpack_user()->hasPermissionTo('courses.edit')) { |
||||
| 200 | abort(403); |
||||
| 201 | } |
||||
| 202 | $event->exempt_attendance = (int) $request->status; |
||||
| 203 | $event->save(); |
||||
| 204 | |||||
| 205 | return (int) $event->exempt_attendance; |
||||
| 206 | } |
||||
| 207 | |||||
| 208 | public function toggleCourseAttendanceStatus(Course $course, Request $request) |
||||
| 209 | { |
||||
| 210 | if (! backpack_user()->hasPermissionTo('courses.edit')) { |
||||
| 211 | abort(403); |
||||
| 212 | } |
||||
| 213 | $course->exempt_attendance = (int) $request->status; |
||||
| 214 | $course->save(); |
||||
| 215 | |||||
| 216 | // apply the same change to all course events |
||||
| 217 | foreach ($course->events as $event) { |
||||
| 218 | $event->exempt_attendance = (int) $request->status; |
||||
| 219 | $event->save(); |
||||
| 220 | } |
||||
| 221 | |||||
| 222 | return (int) $course->exempt_attendance; |
||||
| 223 | } |
||||
| 224 | } |
||||
| 225 |