%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /var/www/html/camillo/camillo-api-master/app/Traits/
Upload File :
Create Path :
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"
                ];
            }
        }
    }
}


Zerion Mini Shell 1.0