%PDF- %PDF-
Direktori : /var/www/html/camillo/camillo-api-master/app/Traits/ |
Current File : /var/www/html/camillo/camillo-api-master/app/Traits/MinorTrackerTrait.php |
<?php namespace App\Traits; use App\Models\Absence; use App\Models\ArrivalException; use App\Models\Classroom; use App\Models\Event; use App\Models\Festivity; use App\Models\Individual; use App\Models\Institute; use Carbon\Carbon; use Illuminate\Http\Response; use Illuminate\Support\Facades\Log; use Symfony\Component\HttpKernel\Exception\HttpException; trait MinorTrackerTrait { use EventEmitterTrait; /** * @param Institute $institute * @param bool $httpException * @return bool * @internal param $throwException */ public function attendsInstitute(Institute $institute, $httpException = true) { $attends = $this->institute == $institute; if($httpException && !$attends){ throw new HttpException(Response::HTTP_BAD_REQUEST, __('minor_doesnt_attend_institute')); } return $attends; } /** * @param $institute * @param bool $httpException * @param null $classroom * * @return mixed * @internal param bool $throwException */ public function getClassroomFromInstitute($institute, $httpException = true, $classroom = null) { $this->attendsInstitute($institute, $httpException); if(!$classroom) { $classroom = $this->getExpectedClassroom($institute->id); } if($httpException && !$classroom) { throw new HttpException(Response::HTTP_PRECONDITION_FAILED, __('classroom not found')); } return $classroom; } /** * checks whether the minor is part of the given classroom * @param Classroom $classroom * @param bool $throwException * @return bool */ public function attendsClassroom(Classroom $classroom, $throwException = false) { $attends = true; if($throwException && !$attends) { throw new HttpException(Response::HTTP_PRECONDITION_FAILED, __('minor_does_not_attend_classroom')); } return $attends; } /** * checks all classrooms arrival and leaving time and return the one that matches the closest to current time * @return Classroom */ public function getExpectedClassroom($institute_id = null) { $classrooms = $this->classrooms()->wherePivot('active', true); if ($classrooms->count() === 0) { return null; } $weekDay = mb_strtolower(date('D')); $classrooms->where($weekDay, true); if ($classrooms->count() === 0) { return $this->classrooms()->wherePivot('active', true)->first(); } if ($classrooms->count() === 1) { return $classrooms->first(); } if ($institute_id) { return $classrooms->where('institute_id', $institute_id)->first(); } $now_time = date("H:i:s"); $classrooms->wherePivot('arrival_time', '<=', date("H:i:s", strtotime("+15 minutes", strtotime($now_time)))) ->where('classrooms.arrival_time', '<=', date("H:i:s", strtotime("+15 minutes", strtotime($now_time)))) ->where('leaving_time', '>=', $now_time)->orderBy('classrooms.arrival_time', 'desc'); $classroom = $classrooms->first(); return $classroom ? : $this->classrooms()->wherePivot('active', true)->first(); } /** * @param Classroom $classroom * @return bool */ public function isClassroomStillClosed(Classroom $classroom) { $opening_time = strtotime($classroom->arrival_time); if (time() < $opening_time) return true; return false; } /** * @param \App\Models\Classroom $classroom * * @return bool */ public function isDayOfClosure(Classroom $classroom) { $today = date('Y-m-d'); $schoolyear = $classroom->schoolyear; if ($schoolyear->start_date->format("Y-m-d") > $today || $schoolyear->end_date->format("Y-m-d") < $today) { return true; } $weekDay = date('N'); $isClosingDay = false; switch($weekDay){ case "1": $isClosingDay = ($classroom->mon == false) ? true : false; break; case "2": $isClosingDay = ($classroom->tue == false) ? true : false; break; case "3": $isClosingDay = ($classroom->wed == false) ? true : false; break; case "4": $isClosingDay = ($classroom->thu == false) ? true : false; break; case "5": $isClosingDay = ($classroom->fri == false) ? true : false; break; case "6": $isClosingDay = ($classroom->sat == false) ? true : false; break; case "7": $isClosingDay = ($classroom->sun == false) ? true : false; break; } if($isClosingDay) { return true; } $festivity = Festivity::where('schoolyear_id', $schoolyear->id) ->whereDate('start_date', '<=', $today) ->whereDate('end_date', '>=', $today) ->first(); if ($festivity) return true; return false; } /** * checks whether an absence had been inserted for today and for this classroom * @param Classroom $classroom * @return bool */ public function absenceExpectedToday(Classroom $classroom) { $today = date('Y-m-d'); $absence= Absence::where('date', $today) ->where('minor_id', $this->id) ->where('classroom_id', $classroom->id)->first(); if($absence) return true; return false; } /** * calculates the current expected arrival time * @param Classroom $classroom * @return false|int */ public function dynamicArrivalTime($classroom = null) { $today = date('Y-m-d'); if(!$classroom){ $classroom = $this->getExpectedClassroom(); } if ($classroom) { $arrival_time = $this->classrooms()->where('classroom_id', $classroom->id)->first()->pivot->arrival_time; //checks whether an arrival time exception has been inserted for today and for this classroom $arrival_exception = ArrivalException::where('date', $today)->where('minor_id', $this->id) ->where('classroom_id', $classroom->id)->first(); if ($arrival_exception != null) { $arrival_time = $arrival_exception->arrival_time; } return $arrival_time; } return null; } /** * Checks whether the tutor scanned the qr code when the minor arrived at the institute * @param $events * @return mixed */ public function hasQRarrived($events) { return $this->hasEventWithType($events, 'qr_minor_arrived'); } /** * Checks whether the tutor scanned the qr code when the minor left the institute * @param $events * @return mixed */ public function hasQRleft($events) { return $this->hasEventWithType($events, 'qr_minor_left'); } /** * checks whether the teacher said the minor left the class * @param $events * @return array */ public function hasLeftAlready($events) { return $this->hasEventWithType($events, 'minor_left_class'); } public function hasEventWithType($events, $event_type) { $filteredEvents = $events->where('event_type', $event_type); $check = $filteredEvents->count() > 0; $ret = ["check" => $check]; if($check){ $event = $filteredEvents->first(); $ret["time"] = $event->date->format("H:i:s"); } return $ret; } /** * Checks whether the teacher said the minor is in class * @param $events * @return array */ public function isAlreadyPresent($events) { return $this->hasEventWithType($events, 'presence_confirmed'); } /** * Checks whether the minor was in danger and no tutor answered to the emergency calls * @param $events * @return array */ public function noTutorAnswered($events) { return $this->hasEventWithType($events, 'no_tutor_answered'); } /** * Checks whether the teacher said this minor is not in class * @param $events * @return mixed */ public function isAbsent($events) { $isAbsent = $this->hasEventWithType($events, 'minor_absence_teacher'); return !!$isAbsent["check"]; } /** * checks if a tutor said he/che is aware of the absence by answering the emergency call * @param $events * @return mixed */ public function isAbsenceAware($events) { $isAbsenceAware = $this->hasEventWithType($events, 'emergency_call_answered'); return !!$isAbsenceAware["check"]; } /** * calculates and returns the minor status * @param Classroom|null $classroom * @return array */ public function status($classroom = null){ //detects the correct classroom if not provided if(!$classroom){ $classroom = $this->getExpectedClassroom(); } $today = (int)date('Ymd'); $events = Event::where('date_as_int', $today)->where('classroom_id', $classroom->id)->where('minor_id', $this->id)->join('event_types', 'event_types.id', '=', 'events.event_type_id')->select(['events.date', 'event_types.event_type'])->get(); //check whether it is a festivity or a closure day for the classroom if($classroom) { $closure_day = $this->isDayOfClosure($classroom); if ($closure_day) { return ["status" => "ok", "description" => "day_of_closure", "color" => "light_grey", "weight" => "1"]; } //checks whether a teacher signalled the absence $isAbsent = $this->isAbsent($events); if ($isAbsent) { return ["status" => "ok", "description" => "minor_absent_by_teacher", "color" => "purple", "weight" => "3" ]; } //if an absence was inserted for today, status is ok $absence_expected = $this->absenceExpectedToday($classroom); if ($absence_expected) { return ["status" => "ok", "description" => "absence_expected", "color" => "purple", "weight" => "3"]; } //checks whether the minor has left the classroom according to the teacher $hasLeft = $this->hasLeftAlready($events); if ($hasLeft["check"]) { return ["status" => "left", "description" => "minor_left_class", "color" => "dark_grey", "time" => $hasLeft["time"], "weight" => "0" ]; }//checks whether the minor has left the classroom according to qr code $hasQRLeft = $this->hasQRleft($events); if ($hasQRLeft["check"]) { return ["status" => "left", "description" => "qr_left", "color" => "dark_grey", "time" => $hasQRLeft["time"], "weight" => "0" ]; } //checks whether the classroom is still closed $classroom_still_closed = $this->isClassroomStillClosed($classroom); if ($classroom_still_closed) { return ["status" => "ok", "description" => "still_closed", "color" => "light_grey", "weight" => "2"]; } //checks whether the child was absent and a tutor answered the emergency call $isAbsenceAware = $this->isAbsenceAware($events); if ($isAbsenceAware) { return ["status" => "ok", "description" => "emergency_call_answered", "color" => "purple", "weight" => "4" ]; } //check whether the minor has already in class $isPresent = $this->isAlreadyPresent($events); if ($isPresent["check"]) { return ["status" => "ok", "description" => "minor_in_class", "color" => "light_green", "time" => $isPresent["time"], "weight" => "0" ]; } //checks whether the minor has arrived according to qr code $hasQRArrived = $this->hasQRarrived($events); if ($hasQRArrived["check"]) { return ["status" => "ok", "description" => "qr_arrived", "color" => "blinking_blue", "time" => $hasQRArrived["time"], "weight" => "5" ]; } //get the expected arrival time for today for this class $arrival_time = strtotime($this->dynamicArrivalTime($classroom)); $warning_time = strtotime("-15 minutes", $arrival_time); $danger_time = strtotime("+1 minutes", $arrival_time); $x_cally_time = strtotime("+15 minutes", $arrival_time); if (time() < $warning_time) { //if classroom open, but more than 15 minutes left to the expected arrival time return ["status" => "ok", "description" => "minor_not_yet_expected", "color" => "blue", "weight" => "6" ]; } elseif (time() > $warning_time && time() < $danger_time) { // if less than 15 minutes left to the expected arrival time return ["status" => "warning", "description" => "minor_warning", "color" => "orange", "weight" => "7"]; } elseif (time() > $danger_time && time() < $x_cally_time) { // if minor is in delay but no more than 15 minutes after the expected arrival time $this->registerEvent('danger_status', $this, $classroom); return ["status" => "danger", "description" => "minor_danger", "color" => "red", "weight" => "8"]; } elseif (time() >= $x_cally_time) { // if minor has more than 15 minutes of delay after the expected arrival time //check if a ring round has already been done and no tutor answered $noTutorAnswered = $this->noTutorAnswered($events); if ($noTutorAnswered["check"]) { return ["status" => "danger", "description" => "no_tutor_answered", "color" => "red_orange_blinking", "time" => $noTutorAnswered["time"], "weight" => "10" ]; } //set the status of max danger $this->registerEvent('max_danger_status', $this, $classroom); return ["status" => "danger", "description" => "minor_max_danger", "color" => "red_orange_blinking", "weight" => "9" ]; } } } }