Passed
Push — master ( 26caeb...0e28f7 )
by Thomas
11:18
created

CourseCrudController::show()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 12
rs 10
1
<?php
2
3
namespace App\Http\Controllers\Admin;
4
5
use App\Http\Controllers\Admin\Operations\ShowStudentPhotoRosterOperation;
6
use App\Http\Requests\CourseRequest;
7
use App\Models\Book;
8
use App\Models\Course;
9
use App\Models\Enrollment;
10
use App\Models\EvaluationType;
11
use App\Models\Event;
12
use App\Models\Level;
13
use App\Models\Period;
14
use App\Models\Rhythm;
15
use App\Models\Room;
16
use App\Models\SchedulePreset;
17
use App\Models\Teacher;
18
use Backpack\CRUD\app\Http\Controllers\CrudController;
19
use Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
20
use Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
21
use Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
22
use Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
23
use Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
24
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
25
use Illuminate\Support\Facades\Gate;
26
use Prologue\Alerts\Facades\Alert;
27
28
class CourseCrudController extends CrudController
29
{
30
    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\Admin\CourseCrudController: $model, $query, $entity_name_plural
Loading history...
31
    use CreateOperation { store as traitStore; }
0 ignored issues
show
Bug introduced by
The trait Backpack\CRUD\app\Http\C...rations\CreateOperation requires the property $entity_name which is not provided by App\Http\Controllers\Admin\CourseCrudController.
Loading history...
32
    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\Admin\CourseCrudController: $entity_name, $model
Loading history...
33
    use DeleteOperation;
34
    use ShowStudentPhotoRosterOperation;
35
36
    public function __construct()
37
    {
38
        parent::__construct();
39
        $this->middleware('permission:courses.view', ['except' => 'show']);
40
        $this->middleware('permission:courses.edit', ['only' => ['update', 'create', 'store', 'destroy']]);
41
    }
42
43
    public function setup()
44
    {
45
        /*
46
        |--------------------------------------------------------------------------
47
        | CrudPanel Basic Information
48
        |--------------------------------------------------------------------------
49
        */
50
        CRUD::setModel(Course::class);
51
        CRUD::setRoute(config('backpack.base.route_prefix').'/course');
52
        CRUD::setEntityNameStrings(__('course'), __('courses'));
0 ignored issues
show
Bug introduced by
It seems like __('course') can also be of type array and array; however, parameter $singular of Backpack\CRUD\app\Librar...:setEntityNameStrings() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

52
        CRUD::setEntityNameStrings(/** @scrutinizer ignore-type */ __('course'), __('courses'));
Loading history...
Bug introduced by
It seems like __('courses') can also be of type array and array; however, parameter $plural of Backpack\CRUD\app\Librar...:setEntityNameStrings() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

52
        CRUD::setEntityNameStrings(__('course'), /** @scrutinizer ignore-type */ __('courses'));
Loading history...
53
54
        CRUD::addClause('internal');
55
        $permissions = backpack_user()->getAllPermissions();
0 ignored issues
show
Bug introduced by
The method getAllPermissions() 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

55
        $permissions = backpack_user()->/** @scrutinizer ignore-call */ getAllPermissions();
Loading history...
56
57
        if (! $permissions->contains('name', 'courses.edit')) {
58
            CRUD::denyAccess(['update', 'create']);
59
        }
60
61
        if ($permissions->contains('name', 'courses.view')) {
62
            CRUD::addButtonFromView('line', 'showEnrollments', 'showEnrollmentsForCourse');
63
        }
64
65
        CRUD::addButtonFromView('line', 'children_badge', 'children_badge', 'beginning');
66
67
        if (! $permissions->contains('name', 'courses.delete')) {
68
            CRUD::denyAccess(['delete']);
69
        }
70
71
        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

71
        if (backpack_user()->/** @scrutinizer ignore-call */ hasRole('admin')) {
Loading history...
72
            CRUD::enableExportButtons();
73
            CRUD::addButtonFromView('line', 'evaluation', 'evaluation', 'end');
74
        }
75
76
        CRUD::addButtonFromView('top', 'courses-view-switcher', 'courses-view-switcher', 'end');
77
    }
78
79
    protected function setupListOperation()
80
    {
81
        CRUD::setColumns([
82
            [
83
                // RYTHM
84
                'label' => __('Rhythm'), // Table column heading
85
                'type' => 'select',
86
                'name' => 'rhythm_id', // the column that contains the ID of that connected entity;
87
                'entity' => 'rhythm', // the method that defines the relationship in your Model
88
                'attribute' => 'name', // foreign key attribute that is shown to user
89
                'model' => Rhythm::class, // foreign key model
90
                'searchLogic' => false,
91
            ],
92
93
            [
94
                // LEVEL
95
                'label' => __('Level'), // Table column heading
96
                'type' => 'select',
97
                'name' => 'level_id', // the column that contains the ID of that connected entity;
98
                'entity' => 'level', // the method that defines the relationship in your Model
99
                'attribute' => 'name', // foreign key attribute that is shown to user
100
                'model' => Level::class, // foreign key model
101
                'searchLogic' => false,
102
            ],
103
104
            [
105
                'name' => 'name', // The db column name
106
                'label' => __('Name'), // Table column heading
107
            ],
108
109
            [
110
                'name' => 'volume', // The db column name
111
                'label' => __('Presential volume'), // Table column heading
112
                'suffix' => 'h',
113
                'type' => 'number',
114
                'searchLogic' => false,
115
            ],
116
117
            [
118
                'name' => 'remote_volume', // The db column name
119
                'label' => __('Remote volume'), // Table column heading
120
                'suffix' => 'h',
121
                'type' => 'number',
122
                'searchLogic' => false,
123
            ],
124
125
            [
126
                // TEACHER
127
                'label' => __('Teacher'), // Table column heading
128
                'type' => 'select',
129
                'name' => 'teacher_id', // the column that contains the ID of that connected entity;
130
                'entity' => 'teacher', // the method that defines the relationship in your Model
131
                'attribute' => 'name', // foreign key attribute that is shown to user
132
                'model' => Teacher::class, // foreign key model
133
                'searchLogic' => false,
134
            ],
135
136
            [
137
                // ROOM
138
                'label' => __('Room'), // Table column heading
139
                'type' => 'select',
140
                'name' => 'room_id', // the column that contains the ID of that connected entity;
141
                'entity' => 'room', // the method that defines the relationship in your Model
142
                'attribute' => 'name', // foreign key attribute that is shown to user
143
                'model' => Room::class, // foreign key model
144
                'searchLogic' => false,
145
            ],
146
147
            // COURSE SCHEDULED TIMES
148
            [
149
                'name' => 'times',
150
                'label' => __('Schedule'), // Table column heading
151
                'type' => 'model_function',
152
                'function_name' => 'getCourseTimesAttribute', // the method in your Model
153
                'limit' => 150, // Limit the number of characters shown
154
                'searchLogic' => false,
155
            ],
156
157
            // ENROLLMENTS COUNT
158
            [
159
                'name' => 'enrollments',
160
                'label' => __('Enrollments'), // Table column heading
161
                'type' => 'model_function',
162
                'function_name' => 'getCourseEnrollmentsCountAttribute', // the method in your Model
163
                // 'limit' => 100, // Limit the number of characters shown
164
                'searchLogic' => false,
165
            ],
166
167
            [
168
                'name' => 'start_date', // The db column name
169
                'label' => __('Start Date'), // Table column heading
170
                'type' => 'date',
171
                // 'format' => 'l j F Y', // use something else than the base.default_date_format config value
172
                'searchLogic' => false,
173
            ],
174
175
            [
176
                'name' => 'end_date', // The db column name
177
                'label' => __('End Date'), // Table column heading
178
                'type' => 'date',
179
                // 'format' => 'l j F Y', // use something else than the base.default_date_format config value
180
                'searchLogic' => false,
181
            ],
182
183
        ]);
184
185
        CRUD::addFilter([
186
            'name' => 'rhythm_id',
187
            'type' => 'select2',
188
            'label'=> __('Rhythm'),
189
        ], fn () => Rhythm::all()->pluck('name', 'id')->toArray(), function ($value) {
0 ignored issues
show
Bug introduced by
The method toArray() does not exist on Illuminate\Support\Collection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

189
        ], fn () => Rhythm::all()->pluck('name', 'id')->/** @scrutinizer ignore-call */ toArray(), function ($value) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
190
            // if the filter is active
191
            CRUD::addClause('where', 'rhythm_id', $value);
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...anelFacade::addClause() has too many arguments starting with 'rhythm_id'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

191
            CRUD::/** @scrutinizer ignore-call */ 
192
                  addClause('where', 'rhythm_id', $value);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
192
        },
193
        function () {
194
            // if the filter is NOT active (the GET parameter "checkbox" does not exit)
195
        });
196
197
        CRUD::addFilter([
198
            'name' => 'teacher_id',
199
            'type' => 'select2',
200
            'label'=> __('Teacher'),
201
        ], fn () => Teacher::all()->pluck('name', 'id')->toArray(), function ($value) {
202
            // if the filter is active
203
            CRUD::addClause('where', 'teacher_id', $value);
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...anelFacade::addClause() has too many arguments starting with 'teacher_id'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

203
            CRUD::/** @scrutinizer ignore-call */ 
204
                  addClause('where', 'teacher_id', $value);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
204
        },
205
        function () {
206
            // if the filter is NOT active (the GET parameter "checkbox" does not exit)
207
        });
208
209
        CRUD::addFilter([
210
            'name' => 'level_id',
211
            'type' => 'select2',
212
            'label'=> __('Level'),
213
        ], fn () => Level::all()->pluck('name', 'id')->toArray(), function ($value) {
214
            // if the filter is active
215
            CRUD::addClause('where', 'level_id', $value);
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...anelFacade::addClause() has too many arguments starting with 'level_id'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

215
            CRUD::/** @scrutinizer ignore-call */ 
216
                  addClause('where', 'level_id', $value);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
216
        },
217
        function () {
218
            // if the filter is NOT active (the GET parameter "checkbox" does not exit)
219
        });
220
221
        CRUD::addFilter([
222
            'name' => 'period_id',
223
            'type' => 'select2',
224
            'label'=> __('Period'),
225
        ],
226
            fn () => \App\Models\Period::all()->sortByDesc('id')->pluck('name', 'id')->toArray(),
0 ignored issues
show
Bug introduced by
The method sortByDesc() does not exist on Illuminate\Database\Eloquent\Collection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

226
            fn () => \App\Models\Period::all()->/** @scrutinizer ignore-call */ sortByDesc('id')->pluck('name', 'id')->toArray(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
227
            function ($value) { // if the filter is active
228
                CRUD::addClause('where', 'period_id', $value);
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...anelFacade::addClause() has too many arguments starting with 'period_id'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

228
                CRUD::/** @scrutinizer ignore-call */ 
229
                      addClause('where', 'period_id', $value);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
229
            },
230
            function () { // if the filter is NOT active (the GET parameter "checkbox" does not exit)
231
                $period = \App\Models\Period::get_default_period()->id;
232
                CRUD::addClause('where', 'period_id', $period);
0 ignored issues
show
Unused Code introduced by
The call to Backpack\CRUD\app\Librar...anelFacade::addClause() has too many arguments starting with 'period_id'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

232
                CRUD::/** @scrutinizer ignore-call */ 
233
                      addClause('where', 'period_id', $period);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
233
                $this->crud->getRequest()->request->add(['period_id' => $period]); // to make the filter look active
0 ignored issues
show
Bug introduced by
The property request does not seem to exist on Illuminate\Http\Request.
Loading history...
234
            }
235
        );
236
237
        CRUD::addFilter(
238
            [ // add a "simple" filter called Draft
239
                'type' => 'simple',
240
                'name' => 'parent',
241
                'label'=> __('Hide Children Courses'),
242
            ],
243
            false,
244
            function () {
245
                CRUD::addClause('parent');
246
            }
247
        );
248
249
        $this->crud->addFilter([
250
            'type'  => 'date_range',
251
            'name'  => 'start_date',
252
            'label' => __('Start'),
253
        ],
254
            false,
255
            function ($value) { // if the filter is active, apply these constraints
256
                $dates = json_decode($value, null, 512, JSON_THROW_ON_ERROR);
257
                $this->crud->addClause('where', 'start_date', '>=', $dates->from);
258
                $this->crud->addClause('where', 'start_date', '<=', $dates->to.' 23:59:59');
259
            });
260
261
        $this->crud->addFilter([
262
            'type'  => 'date_range',
263
            'name'  => 'end_date',
264
            'label' => __('End'),
265
        ],
266
            false,
267
            function ($value) { // if the filter is active, apply these constraints
268
                $dates = json_decode($value, null, 512, JSON_THROW_ON_ERROR);
269
                $this->crud->addClause('where', 'end_date', '>=', $dates->from);
270
                $this->crud->addClause('where', 'end_date', '<=', $dates->to.' 23:59:59');
271
            });
272
    }
273
274
    protected function setupCreateOperation()
275
    {
276
        if (config('app.currency_position') === 'before') {
277
            $currency = ['prefix' => config('app.currency_symbol')];
278
        } else {
279
            $currency = ['suffix' => config('app.currency_symbol')];
280
        }
281
282
        CRUD::addFields([
283
            [
284
                // RYTHM
285
                'label' => __('Rhythm'), // Table column heading
286
                'type' => 'select',
287
                'name' => 'rhythm_id', // the column that contains the ID of that connected entity;
288
                'entity' => 'rhythm', // the method that defines the relationship in your Model
289
                'attribute' => 'name', // foreign key attribute that is shown to user
290
                'model' => Rhythm::class, // foreign key model
291
                'tab' => __('Course info'),
292
            ],
293
294
            [
295
                // LEVEL
296
                'label' => __('Level'), // Table column heading
297
                'type' => 'select',
298
                'name' => 'level_id', // the column that contains the ID of that connected entity;
299
                'entity' => 'level', // the method that defines the relationship in your Model
300
                'attribute' => 'name', // foreign key attribute that is shown to user
301
                'model' => Level::class, // foreign key model
302
                'tab' => __('Course info'),
303
            ],
304
305
            [
306
                'name' => 'name', // The db column name
307
                'label' => __('Name'), // Table column heading
308
                'tab' => __('Course info'),
309
            ],
310
311
            array_merge([
312
                'name' => 'price', // The db column name
313
                'label' => __('Price'), // Table column heading
314
                'tab' => __('Course info'),
315
                'type' => 'number',
316
            ], $currency),
317
        ]);
318
319
        if (config('invoicing.price_categories_enabled')) {
320
            CRUD::addFields([
321
                array_merge([
322
                    'name' => 'price_b',
323
                    'label' => __('Price B'),
324
                    'tab' => __('Course info'), 'type' => 'number',
325
                ], $currency),
326
327
                array_merge([
328
                    'name' => 'price_c',
329
                    'label' => __('PriceC'),
330
                    'tab' => __('Course info'), 'type' => 'number',
331
                ], $currency),
332
            ]);
333
        }
334
335
        CRUD::addFields([
336
            [
337
                'name' => 'volume', // The db column name
338
                'label' => __('Presential volume'), // Table column heading
339
                'suffix' => 'h',
340
                'tab' => __('Course info'),
341
            ],
342
343
            [
344
                'name' => 'remote_volume', // The db column name
345
                'label' => __('Remote volume'), // Table column heading
346
                'suffix' => 'h',
347
                'tab' => __('Course info'),
348
            ],
349
350
            [
351
                'name' => 'spots', // The db column name
352
                'label' => __('Spots'), // Table column heading
353
                'tab' => __('Course info'),
354
            ],
355
356
            [
357
                'name' => 'exempt_attendance', // The db column name
358
                'label' => __('Exempt Attendance'), // Table column heading
359
                'type' => 'checkbox',
360
                'tab' => __('Course info'),
361
            ],
362
363
            [   // repeatable
364
                'name'  => 'sublevels',
365
                'label' => __('Course sublevels'),
366
                'type'  => 'repeatable',
367
                'fields' => [
368
                    [
369
                        'name' => 'name', // The db column name
370
                        'label' => __('Name'), // Table column heading
371
                    ],
372
                    [
373
                        'name'    => 'level_id',
374
                        'label'    => __('Level'),
375
                        'type' => 'select',
376
                        'entity' => 'level', // the method that defines the relationship in your Model
377
                        'attribute' => 'name', // foreign key attribute that is shown to user
378
                        'model' => Level::class, // foreign key model
379
                        'allows_null' => true,
380
                        'wrapper' => ['class' => 'form-group col-md-4'],
381
                    ],
382
383
                    array_merge([
384
                        'name' => 'price', // The db column name
385
                        'label' => __('Price'), // Table column heading
386
                        'type' => 'number',
387
                    ], $currency),
388
389
                    [
390
                        'name' => 'volume', // The db column name
391
                        'label' => __('Presential volume'), // Table column heading
392
                        'suffix' => 'h',
393
                    ],
394
395
                    [
396
                        'name' => 'remote_volume', // The db column name
397
                        'label' => __('Remote volume'), // Table column heading
398
                        'suffix' => 'h',
399
                    ],
400
401
                    [
402
                        'name'    => 'start_date',
403
                        'type'    => 'date',
404
                        'label'   => __('Start Date'),
405
                        'wrapper' => ['class' => 'form-group col-md-4'],
406
                    ],
407
                    [
408
                        'name'    => 'end_date',
409
                        'type'    => 'date',
410
                        'label'   => __('End Date'),
411
                        'wrapper' => ['class' => 'form-group col-md-4'],
412
                    ],
413
                ],
414
                'tab' => __('Course sublevels'),
415
                'init_rows' => 0, // number of empty rows to be initialized, by default 1
416
417
            ],
418
        ]);
419
420
        if (config('lms.sync_to') == 'apolearn') {
421
            CRUD::addField([
422
                'name' => 'sync_to_lms', // The db column name
423
                'label' => __('Sync to LMS'), // Table column heading
424
                'type' => 'checkbox',
425
                'tab' => __('Course info'),
426
            ]);
427
        }
428
429
        CRUD::addFields([
430
            [
431
                'name' => 'color', // The db column name
432
                'label' => __('Color'), // Table column heading
433
                'tab' => __('Course info'),
434
                'type' => 'color_picker',
435
            ],
436
437
            [
438
                // TEACHER
439
                'label' => __('Teacher'), // Table column heading
440
                'type' => 'select',
441
                'name' => 'teacher_id', // the column that contains the ID of that connected entity;
442
                'entity' => 'teacher', // the method that defines the relationship in your Model
443
                'attribute' => 'name', // foreign key attribute that is shown to user
444
                'model' => Teacher::class, // foreign key model
445
                'tab' => __('Resources'),
446
            ],
447
448
            [
449
                // ROOM
450
                'label' => __('Room'), // Table column heading
451
                'type' => 'select',
452
                'name' => 'room_id', // the column that contains the ID of that connected entity;
453
                'entity' => 'room', // the method that defines the relationship in your Model
454
                'attribute' => 'name', // foreign key attribute that is shown to user
455
                'model' => Room::class, // foreign key model
456
                'tab' => __('Resources'),
457
            ],
458
459
            [
460
                // RYTHM
461
                'label' => __('Campus'), // Table column heading
462
                'type' => 'hidden',
463
                'name' => 'campus_id', // the column that contains the ID of that connected entity;
464
                'value' => 1,
465
            ],
466
467
            [
468
                // n-n relationship (with pivot table)
469
                'label' => __('Books'), // Table column heading
470
                'type' => 'select_multiple',
471
                'name' => 'books', // the method that defines the relationship in your Model
472
                'entity' => 'books', // the method that defines the relationship in your Model
473
                'attribute' => 'name', // foreign key attribute that is shown to user
474
                'model' => Book::class, // foreign key model
475
                'pivot' => true, // on create&update, do you need to add/delete pivot table entries?
476
                'tab' => __('Pedagogy'),
477
            ],
478
479
            [
480
                'label' => __('Evaluation method'), // Table column heading
481
                'type' => 'select2',
482
                'name' => 'evaluationType', // the method that defines the relationship in your Model
483
                'entity' => 'evaluationType', // the method that defines the relationship in your Model
484
                'attribute' => 'name', // foreign key attribute that is shown to user
485
                'model' => EvaluationType::class, // foreign key model
486
                'tab' => __('Pedagogy'),
487
            ],
488
489
            [
490
                // PERIOD
491
                'label' => __('Period'), // Table column heading
492
                'type' => 'select',
493
                'name' => 'period_id', // the column that contains the ID of that connected entity;
494
                'entity' => 'period', // the method that defines the relationship in your Model
495
                'attribute' => 'name', // foreign key attribute that is shown to user
496
                'model' => Period::class, // foreign key model
497
                'tab' => __('Schedule'),
498
                'default' => Period::get_enrollments_period()->id,
499
            ],
500
501
            [
502
                'name' => 'start_date', // The db column name
503
                'label' => __('Start Date'),
504
                'type' => 'date',
505
                // 'format' => 'l j F Y', // use something else than the base.default_date_format config value
506
                'tab' => __('Schedule'),
507
                'default' => Period::get_enrollments_period()->start,
508
509
            ],
510
511
            [
512
                'name' => 'end_date', // The db column name
513
                'label' => __('End Date'), // Table column heading
514
                'type' => 'date',
515
                // 'format' => 'l j F Y', // use something else than the base.default_date_format config value
516
                'tab' => __('Schedule'),
517
                'default' => Period::get_enrollments_period()->end,
518
            ],
519
520
            [   // repeatable
521
                'name'  => 'times',
522
                'label' => __('Course Schedule'),
523
                'type'  => 'repeatable',
524
                'fields' => [
525
                    [
526
                        'name'    => 'day',
527
                        'label'    => __('Day'),
528
                        'type'        => 'select_from_array',
529
                        'options'     => [
530
                            0 => __('Sunday'),
531
                            1 => __('Monday'),
532
                            2 => __('Tuesday'),
533
                            3 => __('Wednesday'),
534
                            4 => __('Thursday'),
535
                            5 => __('Friday'),
536
                            6 => __('Saturday'),
537
                        ],
538
                        'allows_null' => false,
539
                        'default'     => 1,
540
                        'wrapper' => ['class' => 'form-group col-md-4'],
541
                    ],
542
                    [
543
                        'name'    => 'start',
544
                        'type'    => 'time',
545
                        'label'   => __('Start'),
546
                        'wrapper' => ['class' => 'form-group col-md-4'],
547
                    ],
548
                    [
549
                        'name'    => 'end',
550
                        'type'    => 'time',
551
                        'label'   => __('End'),
552
                        'wrapper' => ['class' => 'form-group col-md-4'],
553
                    ],
554
                ],
555
                'init_rows' => 0,
556
                'tab' => __('Schedule'),
557
            ],
558
559
            [
560
                'name' => 'remoteevents',
561
                'label' => __('Remote events'),
562
                'type' => 'repeatable',
563
                'fields' => [
564
                    [
565
                        'name' => 'name',
566
                        'type' => 'text',
567
                        'label' => __('Name'),
568
                        'wrapper' => ['class' => 'form-group col-md-6'],
569
                    ],
570
                    [
571
                        'name' => 'worked_hours',
572
                        'type' => 'number',
573
                        'attributes' => ['step' => '0.25'],
574
                        'suffix'     => 'h',
575
                        'label' => __('Weekly Volume'),
576
                        'wrapper' => ['class' => 'form-group col-md-6'],
577
                    ],
578
                ],
579
                'tab' => __('Schedule'),
580
                'init_rows' => 0, // number of empty rows to be initialized, by default 1
581
            ],
582
583
            [   // view
584
                'name' => 'custom-ajax-button',
585
                'type' => 'view',
586
                'view' => 'courses/schedule-preset-alert',
587
                'tab' => __('Schedule'),
588
            ],
589
590
            [   // select_from_array
591
                'name'        => 'schedulepreset',
592
                'label'       => __('Schedule Preset'),
593
                'type'        => 'select_from_array',
594
                'options'     => array_column(SchedulePreset::all()->toArray(), 'name', 'presets'),
0 ignored issues
show
Bug introduced by
The method toArray() does not exist on Illuminate\Database\Eloquent\Collection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

594
                'options'     => array_column(SchedulePreset::all()->/** @scrutinizer ignore-call */ toArray(), 'name', 'presets'),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
595
                'allows_null' => true,
596
                'tab' => __('Schedule'),
597
            ],
598
599
        ]);
600
601
        // add asterisk for fields that are required in CourseRequest
602
        CRUD::setValidation(CourseRequest::class);
603
    }
604
605
    protected function setupUpdateOperation()
606
    {
607
        if (config('app.currency_position') === 'before') {
608
            $currency = ['prefix' => config('app.currency_symbol')];
609
        } else {
610
            $currency = ['suffix' => config('app.currency_symbol')];
611
        }
612
613
        if ($this->crud->getCurrentEntry()->children->count() > 0) {
0 ignored issues
show
Bug introduced by
The method count() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

613
        if ($this->crud->getCurrentEntry()->children->/** @scrutinizer ignore-call */ count() > 0) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method count() does not exist on Illuminate\Support\Collection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

613
        if ($this->crud->getCurrentEntry()->children->/** @scrutinizer ignore-call */ count() > 0) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
614
            CRUD::addField([   // view
615
                'name' => 'custom-ajax-button',
616
                'type' => 'view',
617
                'view' => 'courses/parent-course-alert',
618
            ]);
619
        }
620
621
        if ($this->crud->getCurrentEntry()->parent_course_id !== null) {
622
            CRUD::addField([   // view
623
                'name' => 'custom-ajax-button',
624
                'type' => 'view',
625
                'view' => 'courses/child-course-alert',
626
            ]);
627
        }
628
629
        CRUD::addField([
630
            // RYTHM
631
            'label' => __('Rhythm'), // Table column heading
632
            'type' => 'select',
633
            'name' => 'rhythm_id', // the column that contains the ID of that connected entity;
634
            'entity' => 'rhythm', // the method that defines the relationship in your Model
635
            'attribute' => 'name', // foreign key attribute that is shown to user
636
            'model' => Rhythm::class, // foreign key model
637
            'tab' => __('Course info'),
638
        ]);
639
640
        // unless the course has children, show the level field
641
        if ($this->crud->getCurrentEntry()->children->count() == 0) {
642
            CRUD::addField([
643
                // LEVEL
644
                'label' => __('Level'), // Table column heading
645
                'type' => 'select',
646
                'name' => 'level_id', // the column that contains the ID of that connected entity;
647
                'entity' => 'level', // the method that defines the relationship in your Model
648
                'attribute' => 'name', // foreign key attribute that is shown to user
649
                'model' => Level::class, // foreign key model
650
                'tab' => __('Course info'),
651
            ]);
652
        }
653
654
        CRUD::addFields([
655
            [
656
                'name' => 'name', // The db column name
657
                'label' => __('Name'), // Table column heading
658
                'tab' => __('Course info'),
659
            ],
660
661
            array_merge([
662
                'name' => 'price', // The db column name
663
                'label' => __('Price'), // Table column heading
664
                'tab' => __('Course info'),
665
                'type' => 'number',
666
            ], $currency),
667
        ]);
668
669
        if (config('invoicing.price_categories_enabled')) {
670
            CRUD::addFields([
671
                array_merge([
672
                    'name' => 'price_b',
673
                    'label' => __('Price B'),
674
                    'tab' => __('Course info'), 'type' => 'number',
675
                ], $currency),
676
677
                array_merge([
678
                    'name' => 'price_c',
679
                    'label' => __('PriceC'),
680
                    'tab' => __('Course info'), 'type' => 'number',
681
                ], $currency),
682
            ]);
683
        }
684
685
        CRUD::addFields([
686
            [
687
                'name' => 'volume', // The db column name
688
                'label' => __('Presential volume'), // Table column heading
689
                'suffix' => 'h',
690
                'tab' => __('Course info'),
691
            ],
692
693
            [
694
                'name' => 'remote_volume', // The db column name
695
                'label' => __('Remote volume'), // Table column heading
696
                'suffix' => 'h',
697
                'tab' => __('Course info'),
698
            ],
699
700
            [
701
                'name' => 'spots', // The db column name
702
                'label' => __('Spots'), // Table column heading
703
                'tab' => __('Course info'),
704
            ],
705
706
            [
707
                'name' => 'exempt_attendance', // The db column name
708
                'label' => __('Exempt Attendance'), // Table column heading
709
                'type' => 'checkbox',
710
                'tab' => __('Course info'),
711
            ],
712
        ]);
713
714
        // unless the course has children, show the resources tab
715
        if ($this->crud->getCurrentEntry()->children->count() == 0) {
716
            CRUD::addFields([
717
                [
718
                    // TEACHER
719
                    'label' => __('Teacher'), // Table column heading
720
                    'type' => 'select',
721
                    'name' => 'teacher_id', // the column that contains the ID of that connected entity;
722
                    'entity' => 'teacher', // the method that defines the relationship in your Model
723
                    'attribute' => 'name', // foreign key attribute that is shown to user
724
                    'model' => Teacher::class, // foreign key model
725
                    'tab' => __('Resources'),
726
                ],
727
728
                [
729
                    // ROOM
730
                    'label' => __('Room'), // Table column heading
731
                    'type' => 'select',
732
                    'name' => 'room_id', // the column that contains the ID of that connected entity;
733
                    'entity' => 'room', // the method that defines the relationship in your Model
734
                    'attribute' => 'name', // foreign key attribute that is shown to user
735
                    'model' => Room::class, // foreign key model
736
                    'tab' => __('Resources'),
737
                ],
738
            ]);
739
        }
740
741
        CRUD::addFields([
742
            [
743
                // CAMPUS
744
                'label' => __('Campus'), // Table column heading
745
                'type' => 'hidden',
746
                'name' => 'campus_id', // the column that contains the ID of that connected entity;
747
                'value' => 1,
748
            ],
749
            [
750
                // n-n relationship (with pivot table)
751
                'label' => __('Books'), // Table column heading
752
                'type' => 'select_multiple',
753
                'name' => 'books', // the method that defines the relationship in your Model
754
                'entity' => 'books', // the method that defines the relationship in your Model
755
                'attribute' => 'name', // foreign key attribute that is shown to user
756
                'model' => Book::class, // foreign key model
757
                'pivot' => true, // on create&update, do you need to add/delete pivot table entries?
758
                'tab' => __('Pedagogy'),
759
            ],
760
761
            [
762
                'label' => __('Evaluation method'), // Table column heading
763
                'type' => 'select2',
764
                'name' => 'evaluationType', // the method that defines the relationship in your Model
765
                'entity' => 'evaluationType', // the method that defines the relationship in your Model
766
                'attribute' => 'name', // foreign key attribute that is shown to user
767
                'model' => EvaluationType::class, // foreign key model
768
                'tab' => __('Pedagogy'),
769
            ],
770
771
            [
772
                'label' => __('Evaluation ready'),
773
                'name' => 'marked',
774
                'tab' => __('Pedagogy'),
775
            ],
776
777
            [
778
                // PERIOD
779
                'label' => __('Period'), // Table column heading
780
                'type' => 'select',
781
                'name' => 'period_id', // the column that contains the ID of that connected entity;
782
                'entity' => 'period', // the method that defines the relationship in your Model
783
                'attribute' => 'name', // foreign key attribute that is shown to user
784
                'model' => Period::class, // foreign key model
785
                'tab' => __('Schedule'),
786
            ],
787
788
            [
789
                'name' => 'start_date', // The db column name
790
                'label' => __('Start Date'),
791
                'type' => 'date',
792
                // 'format' => 'l j F Y', // use something else than the base.default_date_format config value
793
                'tab' => __('Schedule'),
794
795
            ],
796
797
            [
798
                'name' => 'end_date', // The db column name
799
                'label' => __('End Date'), // Table column heading
800
                'type' => 'date',
801
                // 'format' => 'l j F Y', // use something else than the base.default_date_format config value
802
                'tab' => __('Schedule'),
803
            ],
804
805
        ]);
806
807
        // unless the course has children, show the coursetimes tab
808
        if ($this->crud->getCurrentEntry()->children->count() == 0) {
809
            CRUD::addField([
810
                'name' => 'times',
811
                'label' => __('Course Schedule'),
812
                'type' => 'repeatable',
813
                'fields' => [
814
                    [
815
                        'name' => 'day',
816
                        'label' => __('Day'),
817
                        'type' => 'select_from_array',
818
                        'options' => [
819
                            0 => __('Sunday'),
820
                            1 => __('Monday'),
821
                            2 => __('Tuesday'),
822
                            3 => __('Wednesday'),
823
                            4 => __('Thursday'),
824
                            5 => __('Friday'),
825
                            6 => __('Saturday'),
826
                        ],
827
                        'allows_null' => false,
828
                        'default' => 1,
829
                        'wrapper' => ['class' => 'form-group col-md-4'],
830
                    ],
831
                    [
832
                        'name' => 'start',
833
                        'type' => 'time',
834
                        'label' => __('Start'),
835
                        'wrapper' => ['class' => 'form-group col-md-4'],
836
                    ],
837
                    [
838
                        'name' => 'end',
839
                        'type' => 'time',
840
                        'label' => __('End'),
841
                        'wrapper' => ['class' => 'form-group col-md-4'],
842
                    ],
843
                ],
844
                'tab' => __('Schedule'),
845
                'init_rows' => 0, // number of empty rows to be initialized, by default 1
846
            ]);
847
848
            if ($this->crud->getCurrentEntry()->children->count() == 0) {
849
                CRUD::addField([
850
                    'name' => 'remoteevents',
851
                    'label' => __('Remote events'),
852
                    'type' => 'repeatable',
853
                    'fields' => [
854
                        [
855
                            'name' => 'name',
856
                            'type' => 'text',
857
                            'label' => __('Name'),
858
                            'wrapper' => ['class' => 'form-group col-md-6'],
859
                        ],
860
                        [
861
                            'name' => 'worked_hours',
862
                            'type' => 'number',
863
                            'attributes' => ['step' => '0.25'],
864
                            'suffix'     => 'h',
865
                            'label' => __('Weekly Volume'),
866
                            'wrapper' => ['class' => 'form-group col-md-6'],
867
                        ],
868
                    ],
869
                    'tab' => __('Schedule'),
870
                    'init_rows' => 0, // number of empty rows to be initialized, by default 1
871
                ]);
872
            }
873
        }
874
875
        // add asterisk for fields that are required in CourseRequest
876
        CRUD::setValidation(CourseRequest::class);
877
    }
878
879
    protected function createSublevels($course, $sublevels, $courseTimes, $teacherId, $roomId) : void
880
    {
881
        foreach ($sublevels as $sublevel) {
882
            // create the subcourse and link it to the parent
883
            $childCourse = Course::create([
884
                'campus_id' => $course->campus_id,
885
                'rhythm_id' => $course->rhythm_id,
886
                'level_id' => $sublevel->level_id,
887
                'volume' => $sublevel->volume,
888
                'remote_volume' => $sublevel->remote_volume,
889
                'name' => $sublevel->name,
890
                'price' => $sublevel->price,
891
                'start_date' => $sublevel->start_date,
892
                'end_date' => $sublevel->end_date,
893
                'room_id' => $roomId,
894
                'teacher_id' => $teacherId,
895
                'parent_course_id' => $course->id,
896
                'exempt_attendance' => $course->exempt_attendance,
897
                'period_id' => $course->period_id,
898
                'spots' => $course->spots,
899
            ]);
900
901
            $childCourse->saveCourseTimes($courseTimes);
902
            $childCourse->books()->attach($course->books);
903
        }
904
    }
905
906
    public function update()
907
    {
908
        $course = $this->crud->getCurrentEntry();
909
        $newCourseTimes = collect(json_decode($this->crud->getRequest()->input('times'), null, 512, JSON_THROW_ON_ERROR));
0 ignored issues
show
Bug introduced by
The method input() does not exist on Illuminate\Http\Request. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

909
        $newCourseTimes = collect(json_decode($this->crud->getRequest()->/** @scrutinizer ignore-call */ input('times'), null, 512, JSON_THROW_ON_ERROR));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
910
        $course->saveCourseTimes($newCourseTimes);
911
912
        $remoteEvents = collect(json_decode($this->crud->getRequest()->input('remoteevents'), null, 512, JSON_THROW_ON_ERROR));
913
        $course->saveRemoteEvents($remoteEvents);
914
915
        // update model
916
        $response = $this->traitUpdate();
917
918
        return $response;
919
    }
920
921
    public function store()
922
    {
923
        $teacherId = $this->crud->getRequest()->input('teacher_id');
924
        $roomId = $this->crud->getRequest()->input('room_id');
925
926
        $response = $this->traitStore();
927
        $course = $this->crud->getCurrentEntry();
928
929
        // if a schedule preset was applied, use it
930
        if ($this->crud->getRequest()->input('schedulepreset') !== null) {
931
            $courseTimes = collect(json_decode($this->crud->getRequest()->input('schedulepreset'), null, 512, JSON_THROW_ON_ERROR));
932
        } else {
933
            // otherwise, use any user-defined course times
934
            $courseTimes = collect(json_decode($this->crud->getRequest()->input('times'), null, 512, JSON_THROW_ON_ERROR));
935
        }
936
937
        $remoteEvents = collect(json_decode($this->crud->getRequest()->input('remoteevents'), null, 512, JSON_THROW_ON_ERROR));
938
        $course->saveRemoteEvents($remoteEvents);
939
940
        $sublevels = collect(json_decode($this->crud->getRequest()->input('sublevels'), null, 512, JSON_THROW_ON_ERROR));
941
942
        // if subcourses were added
943
        if ($sublevels->count() > 0) {
944
            // do not persist level on parent
945
            $this->crud->getRequest()->request->remove('level_id');
0 ignored issues
show
Bug introduced by
The property request does not seem to exist on Illuminate\Http\Request.
Loading history...
946
947
            // do not persist resources on parent but on children
948
            $this->crud->getRequest()->request->remove('teacher_id');
949
            $this->crud->getRequest()->request->remove('room_id');
950
951
            // do not persist course times on parent but on children
952
            $this->crud->getRequest()->request->remove('times');
953
        }
954
955
        if ($sublevels->count() > 0) {
956
            // create sublevels and apply coursetimes to them
957
            $this->createSublevels($course, $sublevels, $courseTimes, $teacherId, $roomId);
958
        } else {
959
            // otherwise, apply course times to the parent.
960
            $course->saveCourseTimes($courseTimes);
961
        }
962
963
        return $response;
964
    }
965
}
966