CourseCrudController::setupCreateOperation()   B
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 334
Code Lines 210

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 4
eloc 210
c 1
b 1
f 0
nc 8
nop 0
dl 0
loc 334
rs 8

How to fix   Long Method   

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\Http\Controllers\Admin\Operations\ShowStudentPhotoRosterOperation;
6
use App\Http\Controllers\Admin\Operations\ShowStudentListOperation;
7
use App\Http\Requests\CourseRequest;
8
use App\Models\Book;
9
use App\Models\Course;
10
use App\Models\Enrollment;
11
use App\Models\EvaluationType;
12
use App\Models\Event;
13
use App\Models\Level;
14
use App\Models\Period;
15
use App\Models\Rhythm;
16
use App\Models\Room;
17
use App\Models\SchedulePreset;
18
use App\Models\Teacher;
19
use Backpack\CRUD\app\Http\Controllers\CrudController;
20
use Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
21
use Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
22
use Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
23
use Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
24
use Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
25
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
26
use Illuminate\Support\Facades\Gate;
27
use Prologue\Alerts\Facades\Alert;
28
29
class CourseCrudController 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\Admin\CourseCrudController: $model, $query, $entity_name_plural
Loading history...
32
    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...
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\Admin\CourseCrudController: $entity_name, $model
Loading history...
34
    use DeleteOperation;
35
    use ShowStudentPhotoRosterOperation;
36
    use ShowStudentListOperation;
37
38
    public function __construct()
39
    {
40
        parent::__construct();
41
        $this->middleware('permission:courses.view', ['except' => ['showstudentlist', 'showstudentphotoroster']]);
42
        $this->middleware('permission:courses.edit', ['only' => ['update', 'create', 'store', 'destroy']]);
43
    }
44
45
    public function setup()
46
    {
47
        CRUD::setModel(Course::class);
48
        CRUD::setRoute(config('backpack.base.route_prefix').'/course');
49
        CRUD::setEntityNameStrings(__('course'), __('courses'));
50
//        $this->crud->enableDetailsRow();
51
        CRUD::addClause('internal');
52
        $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

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

68
        if (backpack_user()->/** @scrutinizer ignore-call */ hasRole('admin')) {
Loading history...
69
            CRUD::enableExportButtons();
70
            CRUD::addButtonFromView('line', 'evaluation', 'evaluation', 'end');
71
        }
72
73
        CRUD::addButtonFromView('top', 'courses-view-switcher', 'courses-view-switcher', 'end');
74
    }
75
76
    protected function setupListOperation()
77
    {
78
        CRUD::setColumns([
79
            [
80
                'label' => __('Rhythm'),
81
                'type' => 'select',
82
                'name' => 'rhythm_id',
83
                'entity' => 'rhythm',
84
                'attribute' => 'name',
85
                'model' => Rhythm::class,
86
                'searchLogic' => false,
87
            ],
88
89
            [
90
                'label' => __('Level'),
91
                'type' => 'select',
92
                'name' => 'level_id',
93
                'entity' => 'level',
94
                'attribute' => 'name',
95
                'model' => Level::class,
96
                'searchLogic' => false,
97
            ],
98
99
            [
100
                'name' => 'name',
101
                'label' => __('Name'),
102
            ],
103
104
            [
105
                'name' => 'volume',
106
                'label' => __('Presential volume'),
107
                'suffix' => 'h',
108
                'type' => 'number',
109
                'searchLogic' => false,
110
            ],
111
112
            [
113
                'name' => 'remote_volume',
114
                'label' => __('Remote volume'),
115
                'suffix' => 'h',
116
                'type' => 'number',
117
                'searchLogic' => false,
118
            ],
119
120
            [
121
                'label' => __('Teacher'),
122
                'type' => 'select',
123
                'name' => 'teacher_id',
124
                'entity' => 'teacher',
125
                'attribute' => 'name',
126
                'model' => Teacher::class,
127
                'searchLogic' => false,
128
            ],
129
130
            [
131
                'label' => __('Room'),
132
                'type' => 'select',
133
                'name' => 'room_id',
134
                'entity' => 'room',
135
                'attribute' => 'name',
136
                'model' => Room::class,
137
                'searchLogic' => false,
138
            ],
139
140
            [
141
                'name' => 'times',
142
                'label' => __('Schedule'),
143
                'type' => 'model_function',
144
                'function_name' => 'getCourseTimesAttribute',
145
                'limit' => 150,
146
                'searchLogic' => false,
147
            ],
148
149
            [
150
                'name' => 'enrollments',
151
                'label' => __('Enrollments'),
152
                'type' => 'model_function',
153
                'function_name' => 'getCourseEnrollmentsCountAttribute',
154
                'searchLogic' => false,
155
            ],
156
157
            [
158
                'name' => 'start_date',
159
                'label' => __('Start Date'),
160
                'type' => 'date',
161
                'searchLogic' => false,
162
            ],
163
164
            [
165
                'name' => 'end_date',
166
                'label' => __('End Date'),
167
                'type' => 'date',
168
                'searchLogic' => false,
169
            ],
170
171
            [
172
                'name'  => 'marked',
173
                'label' => __('Evaluation ready'),
174
                'type'  => 'check',
175
            ],
176
        ]);
177
178
        CRUD::addFilter(
179
            [
180
                'name' => 'rhythm_id',
181
                'type' => 'select2',
182
                'label' => __('Rhythm'),
183
            ],
184
            fn () => Rhythm::all()->pluck('name', 'id')->toArray(),
185
            function ($value) {
186
                CRUD::addClause('where', 'rhythm_id', $value);
187
            },
188
            function () {
189
                // if the filter is NOT active (the GET parameter "checkbox" does not exit)
190
            }
191
        );
192
193
        CRUD::addFilter(
194
            [
195
                'name' => 'teacher_id',
196
                'type' => 'select2',
197
                'label' => __('Teacher'),
198
            ],
199
            fn () => Teacher::all()->pluck('name', 'id')->toArray(),
200
            function ($value) {
201
                CRUD::addClause('where', 'teacher_id', $value);
202
            },
203
            function () {
204
                // if the filter is NOT active (the GET parameter "checkbox" does not exit)
205
            }
206
        );
207
208
        CRUD::addFilter(
209
            [
210
                'name' => 'level_id',
211
                'type' => 'select2',
212
                'label' => __('Level'),
213
            ],
214
            fn () => Level::all()->pluck('name', 'id')->toArray(),
215
            function ($value) {
216
                CRUD::addClause('where', 'level_id', $value);
217
            },
218
            function () {
219
                // if the filter is NOT active (the GET parameter "checkbox" does not exit)
220
            }
221
        );
222
223
        CRUD::addFilter(
224
            [
225
                'name' => 'period_id',
226
                'type' => 'select2',
227
                'label' => __('Period'),
228
            ],
229
            fn () => \App\Models\Period::all()->sortByDesc('id')->pluck('name', 'id')->toArray(),
230
            function ($value) {
231
                CRUD::addClause('where', 'period_id', $value);
232
            },
233
            function () { // if the filter is NOT active (the GET parameter "checkbox" does not exit)
234
                $period = \App\Models\Period::get_default_period()->id;
235
                CRUD::addClause('where', 'period_id', $period);
236
                $this->crud->getRequest()->request->add(['period_id' => $period]); // to make the filter look active
237
            }
238
        );
239
240
        CRUD::addFilter(
241
            [ // add a "simple" filter called Draft
242
                'type' => 'simple',
243
                'name' => 'parent',
244
                'label' => __('Hide Children Courses'),
245
            ],
246
            false,
247
            function () {
248
                CRUD::addClause('parent');
249
            }
250
        );
251
252
        $this->crud->addFilter(
253
            [
254
                'type' => 'date_range',
255
                'name' => 'start_date',
256
                'label' => __('Start'),
257
            ],
258
            false,
259
            function ($value) { // if the filter is active, apply these constraints
260
                $dates = json_decode($value, null, 512, JSON_THROW_ON_ERROR);
261
                $this->crud->addClause('where', 'start_date', '>=', $dates->from);
262
                $this->crud->addClause('where', 'start_date', '<=', $dates->to.' 23:59:59');
263
            }
264
        );
265
266
        $this->crud->addFilter(
267
            [
268
                'type' => 'date_range',
269
                'name' => 'end_date',
270
                'label' => __('End'),
271
            ],
272
            false,
273
            function ($value) { // if the filter is active, apply these constraints
274
                $dates = json_decode($value, null, 512, JSON_THROW_ON_ERROR);
275
                $this->crud->addClause('where', 'end_date', '>=', $dates->from);
276
                $this->crud->addClause('where', 'end_date', '<=', $dates->to.' 23:59:59');
277
            }
278
        );
279
    }
280
281
    protected function setupCreateOperation()
282
    {
283
        if (config('app.currency_position') === 'before') {
284
            $currency = ['prefix' => config('app.currency_symbol')];
285
        } else {
286
            $currency = ['suffix' => config('app.currency_symbol')];
287
        }
288
289
        CRUD::addFields([
290
            [
291
                // RYTHM
292
                'label' => __('Rhythm'),
293
                'type' => 'select',
294
                'name' => 'rhythm_id',
295
                'entity' => 'rhythm',
296
                'attribute' => 'name',
297
                'model' => Rhythm::class,
298
                'tab' => __('Course info'),
299
            ],
300
301
            [
302
                // LEVEL
303
                'label' => __('Level'),
304
                'type' => 'select',
305
                'name' => 'level_id',
306
                'entity' => 'level',
307
                'attribute' => 'name',
308
                'model' => Level::class,
309
                'tab' => __('Course info'),
310
            ],
311
312
            [
313
                'name' => 'name',
314
                'label' => __('Name'),
315
                'tab' => __('Course info'),
316
            ],
317
318
            array_merge([
319
                'name' => 'price',
320
                'label' => __('Price'),
321
                'tab' => __('Course info'),
322
                'type' => 'number',
323
            ], $currency),
324
        ]);
325
326
        if (config('invoicing.price_categories_enabled')) {
327
            CRUD::addFields([
328
                array_merge([
329
                    'name' => 'price_b',
330
                    'label' => __('Price B'),
331
                    'tab' => __('Course info'),
332
                    'type' => 'number',
333
                ], $currency),
334
335
                array_merge([
336
                    'name' => 'price_c',
337
                    'label' => __('PriceC'),
338
                    'tab' => __('Course info'),
339
                    'type' => 'number',
340
                ], $currency),
341
            ]);
342
        }
343
344
        CRUD::addFields([
345
            [
346
                'name' => 'volume',
347
                'label' => __('Presential volume'),
348
                'suffix' => 'h',
349
                'tab' => __('Course info'),
350
            ],
351
352
            [
353
                'name' => 'remote_volume',
354
                'label' => __('Remote volume'),
355
                'suffix' => 'h',
356
                'tab' => __('Course info'),
357
            ],
358
359
            [
360
                'name' => 'spots',
361
                'label' => __('Spots'),
362
                'tab' => __('Course info'),
363
            ],
364
365
            [
366
                'name' => 'exempt_attendance',
367
                'label' => __('Exempt Attendance'),
368
                'type' => 'checkbox',
369
                'tab' => __('Course info'),
370
            ],
371
372
            [   // repeatable
373
                'name' => 'sublevels',
374
                'label' => __('Course sublevels'),
375
                'type' => 'repeatable',
376
                'fields' => [
377
                    [
378
                        'name' => 'name',
379
                        // The db column name
380
                        'label' => __('Name'),
381
                    ],
382
                    [
383
                        'name' => 'level_id',
384
                        'label' => __('Level'),
385
                        'type' => 'select',
386
                        'entity' => 'level',
387
                        'attribute' => 'name',
388
                        'model' => Level::class,
389
                        'allows_null' => true,
390
                        'wrapper' => ['class' => 'form-group col-md-4'],
391
                    ],
392
393
                    array_merge([
394
                        'name' => 'price',
395
                        // The db column name
396
                        'label' => __('Price'),
397
                        'type' => 'number',
398
                    ], $currency),
399
400
                    [
401
                        'name' => 'volume',
402
                        // The db column name
403
                        'label' => __('Presential volume'),
404
                        'suffix' => 'h',
405
                    ],
406
407
                    [
408
                        'name' => 'remote_volume',
409
                        // The db column name
410
                        'label' => __('Remote volume'),
411
                        'suffix' => 'h',
412
                    ],
413
414
                    [
415
                        'name' => 'start_date',
416
                        'type' => 'date',
417
                        'label' => __('Start Date'),
418
                        'wrapper' => ['class' => 'form-group col-md-4'],
419
                    ],
420
                    [
421
                        'name' => 'end_date',
422
                        'type' => 'date',
423
                        'label' => __('End Date'),
424
                        'wrapper' => ['class' => 'form-group col-md-4'],
425
                    ],
426
                ],
427
                'tab' => __('Course sublevels'),
428
                'init_rows' => 0,
429
430
            ],
431
        ]);
432
433
        if (config('lms.sync_to') == 'apolearn') {
434
            CRUD::addField([
435
                'name' => 'sync_to_lms',
436
                'label' => __('Sync to LMS'),
437
                'type' => 'checkbox',
438
                'tab' => __('Course info'),
439
            ]);
440
        }
441
442
        CRUD::addFields([
443
            [
444
                'name' => 'color',
445
                'label' => __('Color'),
446
                'tab' => __('Course info'),
447
                'type' => 'color_picker',
448
            ],
449
450
            [
451
                // TEACHER
452
                'label' => __('Teacher'),
453
                'type' => 'select',
454
                'name' => 'teacher_id',
455
                'entity' => 'teacher',
456
                'attribute' => 'name',
457
                'model' => Teacher::class,
458
                'tab' => __('Resources'),
459
            ],
460
461
            [
462
                // ROOM
463
                'label' => __('Room'),
464
                'type' => 'select',
465
                'name' => 'room_id',
466
                'entity' => 'room',
467
                'attribute' => 'name',
468
                'model' => Room::class,
469
                'tab' => __('Resources'),
470
            ],
471
472
            [
473
                // RYTHM
474
                'label' => __('Campus'),
475
                'type' => 'hidden',
476
                'name' => 'campus_id',
477
                'value' => 1,
478
            ],
479
480
            [
481
                // n-n relationship (with pivot table)
482
                'label' => __('Books'),
483
                'type' => 'select_multiple',
484
                'name' => 'books',
485
                'entity' => 'books',
486
                'attribute' => 'name',
487
                'model' => Book::class,
488
                'pivot' => true,
489
                // on create&update, do you need to add/delete pivot table entries?
490
                'tab' => __('Pedagogy'),
491
            ],
492
493
            [
494
                'label' => __('Evaluation method'),
495
                'type' => 'select2',
496
                'name' => 'evaluationType',
497
                'entity' => 'evaluationType',
498
                'attribute' => 'name',
499
                'model' => EvaluationType::class,
500
                'tab' => __('Pedagogy'),
501
            ],
502
503
            [
504
                // PERIOD
505
                'label' => __('Period'),
506
                'type' => 'select',
507
                'name' => 'period_id',
508
                'entity' => 'period',
509
                'attribute' => 'name',
510
                'model' => Period::class,
511
                'tab' => __('Schedule'),
512
                'default' => Period::get_enrollments_period()->id,
513
            ],
514
515
            [
516
                'name' => 'start_date',
517
                'label' => __('Start Date'),
518
                'type' => 'date',
519
                'tab' => __('Schedule'),
520
                'default' => Period::get_enrollments_period()->start,
521
522
            ],
523
524
            [
525
                'name' => 'end_date',
526
                'label' => __('End Date'),
527
                'type' => 'date',
528
                'tab' => __('Schedule'),
529
                'default' => Period::get_enrollments_period()->end,
530
            ],
531
532
            [   // repeatable
533
                'name' => 'times',
534
                'label' => __('Course Schedule'),
535
                'type' => 'repeatable',
536
                'fields' => [
537
                    [
538
                        'name' => 'day',
539
                        'label' => __('Day'),
540
                        'type' => 'select_from_array',
541
                        'options' => [
542
                            0 => __('Sunday'),
543
                            1 => __('Monday'),
544
                            2 => __('Tuesday'),
545
                            3 => __('Wednesday'),
546
                            4 => __('Thursday'),
547
                            5 => __('Friday'),
548
                            6 => __('Saturday'),
549
                        ],
550
                        'allows_null' => false,
551
                        'default' => 1,
552
                        'wrapper' => ['class' => 'form-group col-md-4'],
553
                    ],
554
                    [
555
                        'name' => 'start',
556
                        'type' => 'time',
557
                        'label' => __('Start'),
558
                        'wrapper' => ['class' => 'form-group col-md-4'],
559
                    ],
560
                    [
561
                        'name' => 'end',
562
                        'type' => 'time',
563
                        'label' => __('End'),
564
                        'wrapper' => ['class' => 'form-group col-md-4'],
565
                    ],
566
                ],
567
                'init_rows' => 0,
568
                'tab' => __('Schedule'),
569
            ],
570
571
            [
572
                'name' => 'remoteevents',
573
                'label' => __('Remote events'),
574
                'type' => 'repeatable',
575
                'fields' => [
576
                    [
577
                        'name' => 'name',
578
                        'type' => 'text',
579
                        'label' => __('Name'),
580
                        'wrapper' => ['class' => 'form-group col-md-6'],
581
                    ],
582
                    [
583
                        'name' => 'worked_hours',
584
                        'type' => 'number',
585
                        'attributes' => ['step' => '0.25'],
586
                        'suffix' => 'h',
587
                        'label' => __('Weekly Volume'),
588
                        'wrapper' => ['class' => 'form-group col-md-6'],
589
                    ],
590
                ],
591
                'tab' => __('Schedule'),
592
                'init_rows' => 0,
593
            ],
594
595
            [   // view
596
                'name' => 'custom-ajax-button',
597
                'type' => 'view',
598
                'view' => 'courses/schedule-preset-alert',
599
                'tab' => __('Schedule'),
600
            ],
601
602
            [   // select_from_array
603
                'name' => 'schedulepreset',
604
                'label' => __('Schedule Preset'),
605
                'type' => 'select_from_array',
606
                'options' => array_column(SchedulePreset::all()->toArray(), 'name', 'presets'),
607
                'allows_null' => true,
608
                'tab' => __('Schedule'),
609
            ],
610
611
        ]);
612
613
        // add asterisk for fields that are required in CourseRequest
614
        CRUD::setValidation(CourseRequest::class);
615
    }
616
617
    protected function setupUpdateOperation()
618
    {
619
        if (config('app.currency_position') === 'before') {
620
            $currency = ['prefix' => config('app.currency_symbol')];
621
        } else {
622
            $currency = ['suffix' => config('app.currency_symbol')];
623
        }
624
625
        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

625
        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...
626
            CRUD::addField([   // view
627
                'name' => 'custom-ajax-button',
628
                'type' => 'view',
629
                'view' => 'courses/parent-course-alert',
630
            ]);
631
        }
632
633
        if ($this->crud->getCurrentEntry()->parent_course_id !== null) {
634
            CRUD::addField([   // view
635
                'name' => 'custom-ajax-button',
636
                'type' => 'view',
637
                'view' => 'courses/child-course-alert',
638
            ]);
639
        }
640
641
        CRUD::addField([
642
            // RYTHM
643
            'label' => __('Rhythm'),
644
            'type' => 'select',
645
            'name' => 'rhythm_id',
646
            'entity' => 'rhythm',
647
            'attribute' => 'name',
648
            'model' => Rhythm::class,
649
            'tab' => __('Course info'),
650
        ]);
651
652
        // unless the course has children, show the level field
653
        if ($this->crud->getCurrentEntry()->children->count() == 0) {
654
            CRUD::addField([
655
                // LEVEL
656
                'label' => __('Level'),
657
                'type' => 'select',
658
                'name' => 'level_id',
659
                'entity' => 'level',
660
                'attribute' => 'name',
661
                'model' => Level::class,
662
                'tab' => __('Course info'),
663
            ]);
664
        }
665
666
        CRUD::addFields([
667
            [
668
                'name' => 'name',
669
                'label' => __('Name'),
670
                'tab' => __('Course info'),
671
            ],
672
673
            array_merge([
674
                'name' => 'price',
675
                'label' => __('Price'),
676
                'tab' => __('Course info'),
677
                'type' => 'number',
678
            ], $currency),
679
        ]);
680
681
        if (config('invoicing.price_categories_enabled')) {
682
            CRUD::addFields([
683
                array_merge([
684
                    'name' => 'price_b',
685
                    'label' => __('Price B'),
686
                    'tab' => __('Course info'),
687
                    'type' => 'number',
688
                ], $currency),
689
690
                array_merge([
691
                    'name' => 'price_c',
692
                    'label' => __('PriceC'),
693
                    'tab' => __('Course info'),
694
                    'type' => 'number',
695
                ], $currency),
696
            ]);
697
        }
698
699
        CRUD::addFields([
700
            [
701
                'name' => 'volume',
702
                'label' => __('Presential volume'),
703
                'suffix' => 'h',
704
                'tab' => __('Course info'),
705
            ],
706
707
            [
708
                'name' => 'remote_volume',
709
                'label' => __('Remote volume'),
710
                'suffix' => 'h',
711
                'tab' => __('Course info'),
712
            ],
713
714
            [
715
                'name' => 'spots',
716
                'label' => __('Spots'),
717
                'tab' => __('Course info'),
718
            ],
719
720
            [
721
                'name' => 'exempt_attendance',
722
                'label' => __('Exempt Attendance'),
723
                'type' => 'checkbox',
724
                'tab' => __('Course info'),
725
            ],
726
727
            [
728
                'name' => 'color',
729
                'label' => __('Color'),
730
                'tab' => __('Course info'),
731
                'type' => 'color_picker',
732
            ],
733
        ]);
734
735
        // unless the course has children, show the resources tab
736
        if ($this->crud->getCurrentEntry()->children->count() == 0) {
737
            CRUD::addFields([
738
                [
739
                    // TEACHER
740
                    'label' => __('Teacher'),
741
                    'type' => 'select',
742
                    'name' => 'teacher_id',
743
                    'entity' => 'teacher',
744
                    'attribute' => 'name',
745
                    'model' => Teacher::class,
746
                    'tab' => __('Resources'),
747
                ],
748
749
                [
750
                    // ROOM
751
                    'label' => __('Room'),
752
                    'type' => 'select',
753
                    'name' => 'room_id',
754
                    'entity' => 'room',
755
                    'attribute' => 'name',
756
                    'model' => Room::class,
757
                    'tab' => __('Resources'),
758
                ],
759
            ]);
760
        }
761
762
        CRUD::addFields([
763
            [
764
                // CAMPUS
765
                'label' => __('Campus'),
766
                'type' => 'hidden',
767
                'name' => 'campus_id',
768
                'value' => 1,
769
            ],
770
            [
771
                // n-n relationship (with pivot table)
772
                'label' => __('Books'),
773
                'type' => 'select_multiple',
774
                'name' => 'books',
775
                'entity' => 'books',
776
                'attribute' => 'name',
777
                'model' => Book::class,
778
                'pivot' => true,
779
                // on create&update, do you need to add/delete pivot table entries?
780
                'tab' => __('Pedagogy'),
781
            ],
782
783
            [
784
                'label' => __('Evaluation method'),
785
                'type' => 'select2',
786
                'name' => 'evaluationType',
787
                'entity' => 'evaluationType',
788
                'attribute' => 'name',
789
                'model' => EvaluationType::class,
790
                'tab' => __('Pedagogy'),
791
            ],
792
793
            [
794
                'label' => __('Evaluation ready'),
795
                'name' => 'marked',
796
                'tab' => __('Pedagogy'),
797
            ],
798
799
            [
800
                // PERIOD
801
                'label' => __('Period'),
802
                'type' => 'select',
803
                'name' => 'period_id',
804
                'entity' => 'period',
805
                'attribute' => 'name',
806
                'model' => Period::class,
807
                'tab' => __('Schedule'),
808
            ],
809
810
            [
811
                'name' => 'start_date',
812
                'label' => __('Start Date'),
813
                'type' => 'date',
814
                'tab' => __('Schedule'),
815
816
            ],
817
818
            [
819
                'name' => 'end_date',
820
                'label' => __('End Date'),
821
                'type' => 'date',
822
                'tab' => __('Schedule'),
823
            ],
824
825
        ]);
826
827
        // unless the course has children, show the coursetimes tab
828
        if ($this->crud->getCurrentEntry()->children->count() == 0) {
829
            CRUD::addField([
830
                'name' => 'times',
831
                'label' => __('Course Schedule'),
832
                'type' => 'repeatable',
833
                'fields' => [
834
                    [
835
                        'name' => 'day',
836
                        'label' => __('Day'),
837
                        'type' => 'select_from_array',
838
                        'options' => [
839
                            0 => __('Sunday'),
840
                            1 => __('Monday'),
841
                            2 => __('Tuesday'),
842
                            3 => __('Wednesday'),
843
                            4 => __('Thursday'),
844
                            5 => __('Friday'),
845
                            6 => __('Saturday'),
846
                        ],
847
                        'allows_null' => false,
848
                        'default' => 1,
849
                        'wrapper' => ['class' => 'form-group col-md-4'],
850
                    ],
851
                    [
852
                        'name' => 'start',
853
                        'type' => 'time',
854
                        'label' => __('Start'),
855
                        'wrapper' => ['class' => 'form-group col-md-4'],
856
                    ],
857
                    [
858
                        'name' => 'end',
859
                        'type' => 'time',
860
                        'label' => __('End'),
861
                        'wrapper' => ['class' => 'form-group col-md-4'],
862
                    ],
863
                ],
864
                'tab' => __('Schedule'),
865
                'init_rows' => 0,
866
            ]);
867
868
            if ($this->crud->getCurrentEntry()->children->count() == 0) {
869
                CRUD::addField([
870
                    'name' => 'remoteevents',
871
                    'label' => __('Remote events'),
872
                    'type' => 'repeatable',
873
                    'fields' => [
874
                        [
875
                            'name' => 'name',
876
                            'type' => 'text',
877
                            'label' => __('Name'),
878
                            'wrapper' => ['class' => 'form-group col-md-6'],
879
                        ],
880
                        [
881
                            'name' => 'worked_hours',
882
                            'type' => 'number',
883
                            'attributes' => ['step' => '0.25'],
884
                            'suffix' => 'h',
885
                            'label' => __('Weekly Volume'),
886
                            'wrapper' => ['class' => 'form-group col-md-6'],
887
                        ],
888
                    ],
889
                    'tab' => __('Schedule'),
890
                    'init_rows' => 0,
891
                ]);
892
            }
893
        }
894
895
        // add asterisk for fields that are required in CourseRequest
896
        CRUD::setValidation(CourseRequest::class);
897
    }
898
899
    protected function createSublevels($course, $sublevels, $courseTimes, $teacherId, $roomId): void
900
    {
901
        foreach ($sublevels as $sublevel) {
902
            // create the subcourse and link it to the parent
903
            $childCourse = Course::create([
904
                'campus_id' => $course->campus_id,
905
                'rhythm_id' => $course->rhythm_id,
906
                'level_id' => $sublevel->level_id,
907
                'volume' => $sublevel->volume,
908
                'remote_volume' => $sublevel->remote_volume,
909
                'name' => $sublevel->name,
910
                'price' => $sublevel->price,
911
                'start_date' => $sublevel->start_date,
912
                'end_date' => $sublevel->end_date,
913
                'room_id' => $roomId,
914
                'teacher_id' => $teacherId,
915
                'parent_course_id' => $course->id,
916
                'exempt_attendance' => $course->exempt_attendance,
917
                'period_id' => $course->period_id,
918
                'spots' => $course->spots,
919
            ]);
920
921
            $childCourse->saveCourseTimes($courseTimes);
922
            $childCourse->books()->attach($course->books);
923
        }
924
    }
925
926
    public function update()
927
    {
928
        $course = $this->crud->getCurrentEntry();
929
        $newCourseTimes = collect(json_decode($this->crud->getRequest()->input('times'), null, 512, JSON_THROW_ON_ERROR));
930
        $course->saveCourseTimes($newCourseTimes);
931
932
        $remoteEvents = collect(json_decode($this->crud->getRequest()->input('remoteevents'), null, 512, JSON_THROW_ON_ERROR));
933
        $course->saveRemoteEvents($remoteEvents);
934
935
        // update model
936
        $response = $this->traitUpdate();
937
938
        return $response;
939
    }
940
941
    public function store()
942
    {
943
        $teacherId = $this->crud->getRequest()->input('teacher_id');
944
        $roomId = $this->crud->getRequest()->input('room_id');
945
946
        $response = $this->traitStore();
947
        $course = $this->crud->getCurrentEntry();
948
949
        // if a schedule preset was applied, use it
950
        if ($this->crud->getRequest()->input('schedulepreset') !== null) {
951
            $courseTimes = collect(json_decode($this->crud->getRequest()->input('schedulepreset'), null, 512, JSON_THROW_ON_ERROR));
952
        } else {
953
            // otherwise, use any user-defined course times
954
            $courseTimes = collect(json_decode($this->crud->getRequest()->input('times'), null, 512, JSON_THROW_ON_ERROR));
955
        }
956
957
        $remoteEvents = collect(json_decode($this->crud->getRequest()->input('remoteevents'), null, 512, JSON_THROW_ON_ERROR));
958
        $course->saveRemoteEvents($remoteEvents);
959
960
        $sublevels = collect(json_decode($this->crud->getRequest()->input('sublevels'), null, 512, JSON_THROW_ON_ERROR));
961
962
        // if subcourses were added
963
        if ($sublevels->count() > 0) {
964
            // do not persist level on parent
965
            $this->crud->getRequest()->request->remove('level_id');
966
967
            // do not persist resources on parent but on children
968
            $this->crud->getRequest()->request->remove('teacher_id');
969
            $this->crud->getRequest()->request->remove('room_id');
970
971
            // do not persist course times on parent but on children
972
            $this->crud->getRequest()->request->remove('times');
973
        }
974
975
        if ($sublevels->count() > 0) {
976
            // create sublevels and apply coursetimes to them
977
            $this->createSublevels($course, $sublevels, $courseTimes, $teacherId, $roomId);
978
        } else {
979
            // otherwise, apply course times to the parent.
980
            $course->saveCourseTimes($courseTimes);
981
        }
982
983
        return $response;
984
    }
985
}
986