Passed
Push — master ( 8c9d15...53e72a )
by Thomas
07:13
created

Enrollment::skill_evaluations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Models;
4
5
use App\Models\Skills\SkillEvaluation;
6
use Backpack\CRUD\app\Models\Traits\CrudTrait;
7
use Carbon\Carbon;
8
use Illuminate\Database\Eloquent\Builder;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Database\Eloquent\SoftDeletes;
11
use Illuminate\Support\Facades\App;
12
use Spatie\Activitylog\Traits\LogsActivity;
13
14
class Enrollment extends Model
15
{
16
    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\Enrollment: $fakeColumns, $identifiableAttribute, $Type
Loading history...
17
    use SoftDeletes;
18
    use LogsActivity;
19
20
    protected $guarded = ['id'];
21
    protected $appends = ['result_name', 'product_code', 'price'];
22
    protected $with = ['student', 'course', 'childrenEnrollments', 'payments'];
23
    protected static $logUnguarded = true;
24
25
    protected static function boot()
26
    {
27
        parent::boot();
28
29
        // when creating a new enrollment, also add past attendance
30
        static::created(function (self $enrollment) {
31
            $events = $enrollment->course->events->where('start', '<', (new Carbon())->toDateString());
32
            foreach ($events as $event) {
33
                $event->attendance()->create([
34
                    'student_id' => $enrollment->student_id,
35
                    'attendance_type_id' => 3,
36
                ]);
37
            }
38
        });
39
    }
40
41
    /**
42
     * return all pending enrollments, without the child enrollments.
43
     */
44
    public function scopeParent($query)
45
    {
46
        return $query
47
        ->where('parent_id', null)
48
        ->get();
49
    }
50
51
    public function scopeReal($query)
52
    {
53
        return $query
54
            ->whereDoesntHave('childrenEnrollments')
55
            ->get();
56
    }
57
58
    public function scopeWithoutChildren($query)
59
    {
60
        return $query
61
            ->where(function ($query) {
62
                $query->whereDoesntHave('childrenEnrollments')
63
                ->where('parent_id', null);
64
            })
65
            ->orWhere(function ($query) {
66
                $query->where('parent_id', null);
67
            })
68
            ->get();
69
    }
70
71
    /** only pending enrollments */
72
    public function scopePending($query)
73
    {
74
        return $query
75
            ->where('status_id', 1)
76
            ->where('parent_id', null)
77
            ->get();
78
    }
79
80
    public function scopeNoresult($query)
81
    {
82
        return $query->doesntHave('result');
83
    }
84
85
    public function scopePeriod(Builder $query, $period)
86
    {
87
        return $query->whereHas('course', function ($q) use ($period) {
88
            $q->where('period_id', $period);
89
        });
90
    }
91
92
    /** FUNCTIONS */
93
    public function changeCourse(Course $newCourse)
94
    {
95
        $this->course_id = $newCourse->id;
96
        $this->save();
97
    }
98
99
    public function markAsPaid()
100
    {
101
        $this->status_id = 2;
102
        $this->save();
103
104
        // also mark children as paid
105
        foreach ($this->childrenEnrollments as $child) {
106
            $child->status_id = 2;
107
            $child->save();
108
        }
109
    }
110
111
    public function markAsUnpaid()
112
    {
113
        $this->status_id = 1;
114
        $this->save();
115
116
        // also mark children as unpaid
117
        foreach ($this->childrenEnrollments as $child) {
118
            $child->status_id = 1;
119
            $child->save();
120
        }
121
    }
122
123
    public function isPaid()
124
    {
125
        return $this->status_id == 2;
126
    }
127
128
    /** RELATIONS */
129
    public function student()
130
    {
131
        return $this->belongsTo(Student::class, 'student_id');
132
    }
133
134
    public function user()
135
    {
136
        return $this->student->user();
137
    }
138
139
    public function course()
140
    {
141
        return $this->belongsTo(Course::class, 'course_id');
142
    }
143
144
    public function payments()
145
    {
146
        return $this->hasMany(Payment::class);
147
    }
148
149
    public function comments()
150
    {
151
        return $this->morphMany(Comment::class, 'commentable');
152
    }
153
154
    public function result()
155
    {
156
        return $this->hasOne(Result::class)
157
            ->with('result_name')
158
            ->with('comments');
159
    }
160
161
    public function childrenEnrollments()
162
    {
163
        return $this->hasMany(self::class, 'parent_id');
164
    }
165
166
    public function enrollmentStatus()
167
    {
168
        return $this->belongsTo(EnrollmentStatusType::class, 'status_id');
169
    }
170
171
    public function grades()
172
    {
173
        return $this->hasMany(Grade::class);
174
    }
175
176
    /* Accessors */
177
178
    public function getResultNameAttribute()
179
    {
180
        return $this->result->result_name->name ?? '-';
181
    }
182
183
    public function skill_evaluations()
184
    {
185
        return $this->hasMany(SkillEvaluation::class);
186
    }
187
188
    public function getStudentNameAttribute()
189
    {
190
        return $this->student['name'];
191
    }
192
193
    /*     public function getStudentIdAttribute()
194
        {
195
            return $this->student['id'];
196
        } */
197
198
    public function getStudentAgeAttribute()
199
    {
200
        return $this->student->age;
0 ignored issues
show
Bug introduced by
The property age does not seem to exist on App\Models\Student. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
201
    }
202
203
    public function getStudentBirthdateAttribute()
204
    {
205
        return $this->student->birthdate;
206
    }
207
208
    public function getStudentEmailAttribute()
209
    {
210
        return $this->student['email'];
211
    }
212
213
    public function getDateAttribute()
214
    {
215
        return Carbon::parse($this->created_at, 'UTC')->locale(App::getLocale())->isoFormat('LL');
216
    }
217
218
    public function getChildrenCountAttribute()
219
    {
220
        return self::where('parent_id', $this->id)->count();
221
    }
222
223
    public function getChildrenAttribute()
224
    {
225
        return self::where('parent_id', $this->id)->with('course')->get();
226
    }
227
228
    public function getStatusAttribute()
229
    {
230
        return $this->enrollmentStatus->name;
231
    }
232
233
    public function getProductCodeAttribute()
234
    {
235
        return $this->course->rhythm->product_code ?? ' ';
236
    }
237
238
    public function getAttendanceRatioAttribute()
239
    {
240
        $courseEventIds = $this->course->events->pluck('id');
241
        $attendances = $this->student->attendance()->with('event')->get()->whereIn('event_id', $courseEventIds);
242
        if ($attendances->count() > 0) {
243
            return round(100 * (($attendances->where('attendance_type_id', 1)->count() + $attendances->where('attendance_type_id', 2)->count() * 0.75) / $attendances->count()));
244
        } else {
245
            return;
246
        }
247
    }
248
249
    public function getAbsenceCountAttribute()
250
    {
251
        $courseEventIds = $this->course->events->pluck('id');
252
        $attendances = $this->student->attendance()->with('event')->get()->whereIn('event_id', $courseEventIds);
253
254
        return $attendances->where('attendance_type_id', 3)->count() + $attendances->where('attendance_type_id', 4)->count();
255
    }
256
257
    public function getPriceAttribute()
258
    {
259
        // if the enrollment has a price, we always consider it first
260
        if ($this->total_price !== null) {
261
            return $this->total_price;
262
        } else {
263
            // otherwise retrieve the default price category for the student
264
            $price_category = $this->student->price_category ?? 'priceA';
0 ignored issues
show
Bug introduced by
The property price_category does not seem to exist on App\Models\Student. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
265
266
            return $this->course->$price_category ?? 0;
267
        }
268
    }
269
270
    public function getBalanceAttribute()
271
    {
272
        $balance = $this->price;
273
        foreach ($this->payments as $payment) {
274
            $balance -= $payment->value;
275
        }
276
277
        return $balance;
278
    }
279
280
    public function cancel()
281
    {
282
        // if the enrollment had children, delete them entirely
283
        if ($this->childrenEnrollments && ($this->childrenEnrollments->count() > 0)) {
284
            foreach ($this->childrenEnrollments as $child) {
285
                $child->delete();
286
            }
287
        }
288
289
        // delete attendance records related to the enrollment
290
        $attendances = $this->course->attendance->where('student_id', $this->student->id);
291
        Attendance::destroy($attendances->map(function ($item, $key) {
0 ignored issues
show
Unused Code introduced by
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 ignore-unused  annotation

291
        Attendance::destroy($attendances->map(function ($item, /** @scrutinizer ignore-unused */ $key) {

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...
292
            return $item->id;
293
        }));
294
295
        foreach ($this->course->children as $child) {
296
            $attendances = $child->attendance->where('student_id', $this->student->id);
297
            Attendance::destroy($attendances->map(function ($item, $key) {
0 ignored issues
show
Unused Code introduced by
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 ignore-unused  annotation

297
            Attendance::destroy($attendances->map(function ($item, /** @scrutinizer ignore-unused */ $key) {

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...
298
                return $item->id;
299
            }));
300
        }
301
302
        $this->delete();
303
    }
304
}
305