Teacher::getUpcomingLeavesAttribute()   B
last analyzed

Complexity

Conditions 9
Paths 7

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 21
c 0
b 0
f 0
nc 7
nop 0
dl 0
loc 37
rs 8.0555
1
<?php
2
3
namespace App\Models;
4
5
use App\Events\TeacherDeleted;
0 ignored issues
show
Bug introduced by
The type App\Events\TeacherDeleted was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use App\Events\TeacherUpdated;
7
use Backpack\CRUD\app\Models\Traits\CrudTrait;
8
use Carbon\Carbon;
9
use Illuminate\Database\Eloquent\Builder;
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Database\Eloquent\SoftDeletes;
12
use Spatie\Activitylog\Traits\LogsActivity;
13
14
/**
15
 * @mixin IdeHelperTeacher
16
 */
17
class Teacher extends Model
18
{
19
    use CrudTrait;
0 ignored issues
show
introduced by
The trait Backpack\CRUD\app\Models\Traits\CrudTrait requires some properties which are not provided by App\Models\Teacher: $fakeColumns, $identifiableAttribute, $Type
Loading history...
20
    use SoftDeletes;
21
    use LogsActivity;
22
23
    public $timestamps = true;
24
25
    protected $guarded = [];
26
27
    public $incrementing = false;
28
29
    protected $with = ['user'];
30
31
    protected $appends = ['firstname', 'lastname', 'name', 'email'];
32
33
    protected static bool $logUnguarded = true;
34
35
    protected $dispatchesEvents = [
36
        'updated' => TeacherUpdated::class,
37
    ];
38
39
    /** relations */
40
    public function user()
41
    {
42
        return $this->belongsTo(User::class, 'id', 'id')->withTrashed();
43
    }
44
45
    /** attributes */
46
    public function getFirstnameAttribute(): ?string
47
    {
48
        return $this?->user?->firstname;
49
    }
50
51
    public function getLastnameAttribute(): ?string
52
    {
53
        return $this?->user?->lastname;
54
    }
55
56
    public function getEmailAttribute(): ?string
57
    {
58
        return $this?->user?->email;
59
    }
60
61
    public function getNameAttribute(): ?string
62
    {
63
        return $this?->user?->firstname.' '.$this?->user?->lastname;
64
    }
65
66
    public function period_courses(Period $period)
67
    {
68
        return $this->courses()
69
            ->where('period_id', $period->id)
70
            ->withCount('children')
71
            ->withCount('enrollments')
72
            ->get()
73
            ->where('children_count', 0);
74
    }
75
76
    public function period_events(Period $period)
77
    {
78
        return $this->events
79
            ->where('start', '>=', Carbon::parse($period->start)->setTime(0, 0, 0)->toDateTimeString())
80
            ->where('end', '<=', Carbon::parse($period->end)->setTime(23, 59, 0)->toDateTimeString());
81
    }
82
83
    public function period_remote_events(Period $period)
84
    {
85
        return $this->remote_events
86
            ->where('period_id', $period->id);
87
    }
88
89
    public function events()
90
    {
91
        return $this->hasMany(Event::class);
92
    }
93
94
    public function remote_events()
95
    {
96
        return $this->hasMany(RemoteEvent::class);
97
    }
98
99
    public function leaves()
100
    {
101
        return $this->hasMany(Leave::class)->with('leaveType');
102
    }
103
104
    public function getUpcomingLeavesAttribute()
105
    {
106
        $dates = $this->leaves->where('date', '>=', Carbon::now()->format('Y-m-d'))->sortBy('date')->values()->all();
107
        if ((is_countable($dates) ? count($dates) : 0) == 0) {
108
            return [];
109
        }
110
        $formatted_leaves = [];
111
        $range_start = Carbon::parse($dates[0]['date']);
112
113
        // loop through all leave dates
114
        for ($i = 0; $i < (is_countable($dates) ? count($dates) : 0); $i++) {
115
116
            // if the next date does not touch current range
117
            if (isset($dates[$i + 1])) {
118
                if (Carbon::parse($dates[$i]['date'])->addDay() != Carbon::parse($dates[$i + 1]['date'])) {
119
                    // push the range to result array
120
                    $range_end = Carbon::parse($dates[$i]['date']);
121
                    if ($range_start == $range_end) {
122
                        array_push($formatted_leaves, $range_start->format('d/m/Y'));
123
                    } else {
124
                        array_push($formatted_leaves, $range_start->format('d/m/Y').' - '.$range_end->format('d/m/Y'));
125
                    }
126
127
                    $range_start = Carbon::parse($dates[$i + 1]['date']);
128
                }
129
            } else {
130
                // if there is no further date
131
                $range_end = Carbon::parse($dates[$i]['date']);
132
                if ($range_start == $range_end) {
133
                    array_push($formatted_leaves, $range_start->format('d/m/Y'));
134
                } else {
135
                    array_push($formatted_leaves, $range_start->format('d/m/Y').' - '.$range_end->format('d/m/Y'));
136
                }
137
            }
138
        }
139
140
        return $formatted_leaves;
141
    }
142
143
    public function courses()
144
    {
145
        return $this->hasMany(Course::class);
146
    }
147
148
    public function plannedHoursInPeriod($start, $end)
149
    {
150
        return $this->events()
151
            ->where('start', '>=', Carbon::parse($start)->setTime(0, 0, 0)->toDateTimeString())
152
            ->where('end', '<=', Carbon::parse($end)->setTime(23, 59, 0)->toDateTimeString())
153
            ->get()
154
            ->sum('length');
155
    }
156
157
    public function plannedRemoteHoursInPeriod($start, $end)
158
    {
159
        $total = 0;
160
        // retrieve courses within period
161
        foreach ($this->courses()->realcourses()->whereDate('start_date', '<=', $end)->get() as $course) {
162
163
            // the number of days (selected period) overlapping the course length
164
            // latest of course and report start dates.
165
            $startDate = Carbon::parse($course->start_date)->max($start);
166
167
            // only process if the course ends AFTER the start date
168
            if ($startDate <= $course->end_date) {
169
                $endDate = Carbon::parse($course->end_date)->min($end);
170
171
                // add 1 to include current week.
172
                $numberOfWeeks = $startDate->diffInWeeks($endDate) + 1;
173
174
                $total += $course->remoteEvents->sum('worked_hours') * $numberOfWeeks;
175
            }
176
        }
177
178
        return $total;
179
    }
180
181
    /* Return the events with incomplete attendance for this teacher */
182
    public function events_with_pending_attendance(Period $period)
183
    {
184
        $eventsWithMissingAttendance = [];
185
186
        $eventsWithExpectedAttendance = $this->events()
187
        ->where(function ($query) {
188
            $query->where('exempt_attendance', '!=', true);
189
            $query->where('exempt_attendance', '!=', 1);
190
            $query->orWhereNull('exempt_attendance');
191
        })
192
        ->where('course_id', '!=', null)
193
        ->whereHas('course', fn (Builder $query) => $query->where('period_id', $period->id)
194
            ->where(function ($query) {
195
                $query->where('exempt_attendance', '!=', true);
196
                $query->where('exempt_attendance', '!=', 1);
197
                $query->orWhereNull('exempt_attendance');
198
            }))
199
        ->with('course')
200
        ->where('start', '<', Carbon::now(config('settings.courses_timezone'))->addMinutes(20)->toDateTimeString())
201
        ->get();
202
203
        foreach ($eventsWithExpectedAttendance as $event) {
204
            foreach ($event->enrollments as $enrollment) {
205
206
                // if a student has no attendance record for the class (event)
207
                $hasNotAttended = $event->attendance->where('student_id', $enrollment->student_id)->isEmpty();
208
209
                // count one and break loop
210
                if ($hasNotAttended) {
211
                    $eventsWithMissingAttendance[] = $event;
212
                    break;
213
                }
214
            }
215
        }
216
217
        return collect($eventsWithMissingAttendance);
218
    }
219
220
    // SETTERS
221
    public function setFirstnameAttribute($value)
222
    {
223
        $this->user->update(['firstname' => $value]);
224
    }
225
226
    public function setLastnameAttribute($value)
227
    {
228
        $this->user->update(['lastname' => $value]);
229
    }
230
231
    public function setEmailAttribute($value)
232
    {
233
        $this->user->update(['email' => $value]);
234
    }
235
}
236