Passed
Push — master ( 73ff1c...c96fe8 )
by Thomas
07:34
created

EnrollmentCrudController::setupListOperation()   F

Complexity

Conditions 19
Paths 1536

Size

Total Lines 233
Code Lines 138

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 19
eloc 138
c 2
b 1
f 0
nc 1536
nop 0
dl 0
loc 233
rs 0.2799

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Http\Controllers\Admin;
4
5
use App\Models\Course;
6
use App\Models\Enrollment;
7
use App\Models\EnrollmentStatusType;
8
use App\Models\Invoice;
9
use App\Models\Paymentmethod;
10
use App\Models\Period;
11
use App\Models\PhoneNumber;
12
use App\Models\ScheduledPayment;
13
use App\Models\Scholarship;
14
use Backpack\CRUD\app\Http\Controllers\CrudController;
15
use Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
16
use Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
17
use Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
18
use Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
19
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
20
use Backpack\CRUD\app\Library\Widget;
21
use Illuminate\Support\Facades\Gate;
22
use Illuminate\Support\Facades\Log;
23
24
/**
25
 * Class EnrollmentCrudController
26
 * This controller is used to view enrollments only.
27
 * No enrollments may be created or updated from here.
28
 */
29
class EnrollmentCrudController extends CrudController
30
{
31
    use ListOperation;
0 ignored issues
show
introduced by
The trait Backpack\CRUD\app\Http\C...perations\ListOperation requires some properties which are not provided by App\Http\Controllers\Adm...nrollmentCrudController: $model, $query, $entity_name_plural
Loading history...
32
    use ShowOperation { show as traitShow; }
0 ignored issues
show
introduced by
The trait Backpack\CRUD\app\Http\C...perations\ShowOperation requires some properties which are not provided by App\Http\Controllers\Adm...nrollmentCrudController: $route, $entity_name
Loading history...
33
    use UpdateOperation { update as traitUpdate; }
0 ignored issues
show
introduced by
The trait Backpack\CRUD\app\Http\C...rations\UpdateOperation requires some properties which are not provided by App\Http\Controllers\Adm...nrollmentCrudController: $entity_name, $model
Loading history...
34
    use DeleteOperation;
35
36
    protected string $mode = 'global';
37
38
    protected ?Course $course = null;
39
40
    public function __construct()
41
    {
42
        parent::__construct();
43
        $this->middleware(['permission:enrollments.view']);
44
        $this->middleware('permission:enrollments.delete', ['only' => ['destroy']]);
45
    }
46
47
    public function setup()
48
    {
49
        CRUD::setModel(Enrollment::class);
50
        CRUD::setRoute(config('backpack.base.route_prefix').'/enrollment');
51
        CRUD::setEntityNameStrings(__('enrollment'), __('enrollments'));
52
    }
53
54
    /*
55
    |--------------------------------------------------------------------------
56
    | CrudPanel Configuration
57
    |--------------------------------------------------------------------------
58
    */
59
60
    public function setupListOperation()
61
    {
62
        if ($this->crud->getRequest()->has('course_id')) {
63
            $this->mode = 'course';
64
            $this->course = Course::findOrFail($this->crud->getRequest()->course_id);
65
66
            if (Gate::forUser(backpack_user())->denies('view-course', $this->course)) {
67
                abort(403);
68
            }
69
            CRUD::addClause('course', $this->course->id);
70
        }
71
72
        if ($this->mode === 'course') {
73
            CRUD::denyAccess(['create', 'update', 'delete']);
74
        }
75
76
        if (backpack_user()->hasRole('admin')) {
0 ignored issues
show
Bug introduced by
The method hasRole() 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 ignore-call  annotation

76
        if (backpack_user()->/** @scrutinizer ignore-call */ hasRole('admin')) {
Loading history...
77
            CRUD::enableExportButtons();
78
        }
79
80
        if ($this->mode === 'course') {
81
            Widget::add(['type' => 'view', 'view' => 'partials.course_info', 'course' => $this->course])->to('before_content');
82
83
            CRUD::denyAccess(['show']);
84
            CRUD::addButtonFromView('line', 'showStudent', 'showStudentForEnrollment');
85
86
            CRUD::addButtonFromView('top', 'enroll-student-in-course', 'enroll-student-in-course', 'end');
87
            CRUD::addButtonFromView('top', 'switch-to-photo-roster', 'switch-to-photo-roster', 'end');
88
        }
89
90
        if (config('app.currency_position') === 'before') {
91
            $currency = ['prefix' => config('app.currency_symbol')];
92
        } else {
93
            $currency = ['suffix' => config('app.currency_symbol')];
94
        }
95
96
        CRUD::addColumns([
97
            [
98
                'name' => 'id',
99
                'label' => 'ID',
100
                'wrapper' => [
101
                    'element' => function ($crud, $column, $entry) {
102
                        return $entry->status_id > 2 ? 'del' : 'span';
103
                    },
104
                ],
105
            ],
106
107
            [
108
                'label' => __('ID number'),
109
                'type' => 'text',
110
                'name' => 'student.idnumber',
111
                'wrapper' => [
112
                    'element' => function ($crud, $column, $entry) {
113
                        return $entry->status_id > 2 ? 'del' : 'span';
114
                    },
115
                ],
116
            ],
117
118
            [
119
                'name' => 'user',
120
                'key'       => 'user_lastname',
121
                'attribute' => 'lastname',
122
                'label' => __('Last Name'),
123
                'type' => 'relationship',
124
                'wrapper' => [
125
                    'element' => function ($crud, $column, $entry) {
126
                        return $entry->status_id > 2 ? 'del' : 'span';
127
                    },
128
                ],
129
                'searchLogic' => function ($query, $column, $searchTerm) {
130
                    $query->orWhereHas('student', function ($q) use ($searchTerm) {
131
                        $q->whereHas('user', function ($q) use ($searchTerm) {
132
                            $q->where('lastname', 'like', '%'.$searchTerm.'%');
133
                        });
134
                    });
135
                },
136
            ],
137
138
            [
139
                'name' => 'user',
140
                'key'       => 'user_firstname',
141
                'attribute' => 'firstname',
142
                'label' => __('First Name'),
143
                'type' => 'relationship',
144
                'wrapper' => [
145
                    'element' => function ($crud, $column, $entry) {
146
                        return $entry->status_id > 2 ? 'del' : 'span';
147
                    },
148
                ],
149
                'searchLogic' => function ($query, $column, $searchTerm) {
150
                    $query->orWhereHas('student', function ($q) use ($searchTerm) {
151
                        $q->whereHas('user', function ($q) use ($searchTerm) {
152
                            $q->where('firstname', 'like', '%'.$searchTerm.'%');
153
                        });
154
                    });
155
                },
156
            ],
157
158
            [
159
                'label' => __('Age'),
160
                'name' => 'student_age',
161
            ],
162
163
            [
164
                'label' => __('Birthdate'),
165
                'name' => 'student_birthdate',
166
            ],
167
        ]);
168
169
        if ($this->mode === 'global') {
170
            CRUD::addColumns([
171
                [
172
                    'label' => __('Course'),
173
                    'type' => 'select',
174
                    'name' => 'course_id',
175
                    'entity' => 'course',
176
                    'attribute' => 'name',
177
                    'model' => Course::class,
178
                ],
179
                [
180
                    'type' => 'relationship',
181
                    'name' => 'course.period',
182
                    'label' => __('Period'),
183
                    'attribute' => 'name', ],
184
            ]);
185
        }
186
187
        CRUD::addColumns([
188
            [
189
                'label' => __('Status'),
190
                'type' => 'select',
191
                'name' => 'status_id',
192
                'entity' => 'enrollmentStatus',
193
                'attribute' => 'name',
194
                'model' => EnrollmentStatusType::class,
195
                'wrapper' => [
196
                    'element' => 'span',
197
                    'class' => function ($crud, $column, $entry) {
198
                        return 'badge badge-pill badge-'.$entry->enrollmentStatus->styling();
199
                    },
200
                ],
201
            ],
202
        ]);
203
204
        if (config('invoicing.allow_scheduled_payments')) {
205
            CRUD::addColumn([
206
                'name' => 'scheduledPayments',
207
                'type' => 'relationship', 'label' => __('Scheduled Payments'), // OPTIONAL
208
                'attribute' => 'date', 'model' => ScheduledPayment::class,
209
            ]);
210
        }
211
212
        CRUD::addColumn(array_merge([
213
            'name' => 'price', // The db column name
214
            'label' => __('Price'),
215
            'type' => 'number',
216
        ], $currency));
217
218
219
        if (config('invoicing.invoices_contain_enrollments_only')) {
220
            CRUD::addColumn(array_merge(['name' => 'balance', 'label' => __('Balance'), 'type' => 'number',], $currency));
221
        }
222
223
        CRUD::addColumns([
224
225
            [
226
                'name'         => 'scholarships',
227
                'type'         => 'relationship',
228
                'label'        => __('Scholarship'),
229
                'attribute' => 'name',
230
                'model'     => Scholarship::class,
231
            ],
232
233
            [
234
                'label'     => __('Email'),
235
                'name' => 'user',
236
                'attribute' => 'email',
237
                'type' => 'relationship',
238
            ],
239
240
            [
241
                'label'     => __('Phone Number'),
242
                'type'      => 'select_multiple',
243
                'name'      => 'student.phone',
244
                'attribute' => 'phone_number',
245
                'model' => PhoneNumber::class,
246
            ],
247
        ]);
248
249
        if ($this->mode === 'global') {
250
            CRUD::addFilter(
251
                [
252
                    'name' => 'status_id',
253
                    'type' => 'select2_multiple',
254
                    'label'=> __('Status'),
255
                ],
256
                fn () => EnrollmentStatusType::all()->pluck('name', 'id')->toArray(),
257
                function ($values) {
258
                foreach (json_decode($values, null, 512, JSON_THROW_ON_ERROR) as $value) {
259
                    CRUD::addClause('orWhere', 'status_id', $value);
260
                }
261
            }
262
            );
263
264
            CRUD::addFilter([
265
                'name' => 'period_id',
266
                'type' => 'select2',
267
                'label'=> __('Period'),
268
            ], fn () => Period::all()->pluck('name', 'id')->toArray(), function ($value) {
269
                CRUD::addClause('period', $value);
270
            });
271
272
            CRUD::addFilter(
273
                [
274
                    'name' => 'scholarship',
275
                    'type' => 'select2',
276
                    'label'=> __('Scholarship'),
277
                ],
278
                fn () => Scholarship::all()->pluck('name', 'id')->toArray(),
279
                function ($value) { // if the filter is active
280
                    if ($value == 'all') {
281
                        CRUD::addClause('whereHas', 'scholarships');
282
                    } else {
283
                        CRUD::addClause('whereHas', 'scholarships', function ($q) use ($value) {
284
                            $q->where('scholarships.id', $value);
285
                        });
286
                    }
287
                }
288
            );
289
        }
290
291
        if ($this->mode === 'global' && $this->crud->getOperation() === 'list') {
292
            Widget::add()->type('view')->view('enrollments.total_balance_widget')->to('before_content');
293
        }
294
295
    }
296
297
    public function show($enrollment)
298
    {
299
        $enrollment = Enrollment::findOrFail($enrollment);
300
301
        // then load the page
302
        return view('enrollments.show', [
303
            'enrollment' => $enrollment,
304
            'comments' => $enrollment->comments,
305
            'scholarships' => Scholarship::all(),
306
            'availablePaymentMethods' => Paymentmethod::all(),
307
            'writeaccess' => $enrollment->status_id !== 2 && backpack_user()->can('enrollments.edit'),
308
        ]);
309
    }
310
311
    protected function setupUpdateOperation()
312
    {
313
        if (config('app.currency_position') === 'before') {
314
            $currency = ['prefix' => config('app.currency_symbol')];
315
        } else {
316
            $currency = ['suffix' => config('app.currency_symbol')];
317
        }
318
319
        CRUD::addField([
320
            'label'     => __('Course'),
321
            'type'      => 'select2',
322
            'name'      => 'course_id',
323
324
            'entity'    => 'course',
325
            'model'     => Course::class,
326
            'attribute' => 'name',
327
328
            'options'   => (fn ($query) => $query->orderBy('level_id', 'ASC')->where('period_id', $this->crud->getCurrentEntry()->course->period_id)->get()),
0 ignored issues
show
Bug introduced by
The property period_id does not seem to exist on Illuminate\Database\Eloquent\Relations\Relation.
Loading history...
329
        ]);
330
331
        CRUD::addField(array_merge([
332
            'name' => 'price', // The db column name
333
            'label' => __('Price'),
334
            'type' => 'number',
335
        ], $currency));
336
337
        if (config('invoicing.allow_scheduled_payments')) {
338
            CRUD::addField(['name' => 'scheduledPayments', 'label' => __('Scheduled Payments'), 'type' => 'repeatable', 'fields' => [['name' => 'date', 'type' => 'date', 'label' => __('Date'), 'wrapper' => ['class' => 'form-group col-md-4']], array_merge(['name' => 'value', 'type' => 'number', 'attributes' => ['step' => 0.01, 'min' => 0], 'label' => __('Value'), 'wrapper' => ['class' => 'form-group col-md-4']], $currency), ['name' => 'status', 'type' => 'radio', 'label' => __('Status'), 'wrapper' => ['class' => 'form-group col-md-4'], 'options' => [1 => __('Pending'), 2 => __('Paid')], 'inline' => true]]]);
339
        }
340
341
        CRUD::addField([
342
            'label'     => __('Status'),
343
            'type'      => 'select',
344
            'name'      => 'status_id',
345
            'entity'    => 'enrollmentStatus',
346
            'model'     => EnrollmentStatusType::class,
347
            'attribute' => 'name',
348
        ]);
349
    }
350
351
    public function update()
352
    {
353
        $enrollment = $this->crud->getCurrentEntry();
354
        if ($this->crud->getRequest()->has('scheduledPayments')) {
355
            $newScheduledPayments = collect(json_decode($this->crud->getRequest()->input('scheduledPayments'), null, 512, JSON_THROW_ON_ERROR));
356
            $enrollment->saveScheduledPayments($newScheduledPayments);
357
        }
358
        $response = $this->traitUpdate();
359
360
        return $response;
361
    }
362
363
    public function destroy($enrollment)
364
    {
365
        $enrollment = Enrollment::findOrFail($enrollment);
366
        $enrollment->cancel();
367
368
        Log::notice('Enrollment canceled by user '.backpack_user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
369
    }
370
}
371