Passed
Push — master ( 2624ac...bdb8ac )
by Adam
07:17
created

ReservationController   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 508
Duplicated Lines 0 %

Test Coverage

Coverage 69.09%

Importance

Changes 0
Metric Value
dl 0
loc 508
ccs 190
cts 275
cp 0.6909
rs 8.2608
c 0
b 0
f 0
wmc 40

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B chooseFreeRoom() 0 48 4
A store() 0 22 3
A delete() 0 15 2
B searchFreeRooms() 0 27 2
B add() 0 37 3
A future() 0 23 2
A current() 0 23 2
A postSearchFreeRooms() 0 15 2
A chooseGuest() 0 20 2
A index() 0 22 2
B showEditForm() 0 29 2
B editChooseRoom() 0 35 3
B getFields() 0 39 2
B editChooseGuest() 0 32 3
B getActionButtons() 0 28 1
A getGuestField() 0 10 1
A isReservationDataInSessionCorrect() 0 11 2
A getRoomField() 0 10 1

How to fix   Complexity   

Complex Class

Complex classes like ReservationController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ReservationController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Http\Interfaces\ManageTableInterface;
6
use App\Http\Requests\ReservationSearchRequest;
7
use App\Models\Guest;
8
use App\Models\Reservation;
9
use App\Models\Room;
10
use App\Services\GuestTableService;
11
use App\Services\ReservationTableService;
12
use App\Services\RoomTableService;
13
use Carbon\Carbon;
14
use Illuminate\Database\Eloquent\ModelNotFoundException;
15
use Illuminate\Support\Facades\Log;
16
use Illuminate\Support\Facades\Session;
17
18
class ReservationController extends Controller implements ManageTableInterface
19
{
20
    protected $reservationTableService;
21
22 14
    public function __construct(ReservationTableService $reservationTableService)
23
    {
24 14
        $this->reservationTableService = $reservationTableService;
25 14
    }
26
27 4
    public function index()
28
    {
29 4
        $title = trans('navigation.all_reservations');
30
31 4
        $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
32 4
            ->with('guest:id,first_name,last_name')
33 4
            ->with('room:id,number')
34 4
            ->orderBy('date_end', 'DESC')
35 4
            ->paginate($this->getItemsPerPage());
36
37 4
        if ($dataset->isEmpty()) {
38 2
            $this->addFlashMessage(trans('general.no_reservations_in_database'), 'alert-danger');
39
        }
40
41
        $viewData = [
42 4
            'columns'       => $this->reservationTableService->getColumns(),
43 4
            'dataset'       => $dataset,
44 4
            'routeName'     => $this->reservationTableService->getRouteName(),
45 4
            'title'         => $title,
46
        ];
47
48 4
        return view('list', $viewData);
49
    }
50
51 2
    public function current()
52
    {
53 2
        $title = trans('navigation.current_reservations');
54
55 2
        $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
56 2
            ->with('guest:id,first_name,last_name')
57 2
            ->with('room:id,number')
58 2
            ->getCurrentReservations()
59 2
            ->orderBy('date_end')
60 2
            ->paginate($this->getItemsPerPage());
61
62 2
        if ($dataset->isEmpty()) {
63 1
            $this->addFlashMessage(trans('general.no_reservations_in_database'), 'alert-danger');
64
        }
65
66
        $viewData = [
67 2
            'columns'       => $this->reservationTableService->getColumns(),
68 2
            'dataset'       => $dataset,
69 2
            'routeName'     => $this->reservationTableService->getRouteName(),
70 2
            'title'         => $title,
71
        ];
72
73 2
        return view('list', $viewData);
74
    }
75
76 2
    public function future()
77
    {
78 2
        $title = trans('navigation.future_reservations');
79
80 2
        $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
81 2
            ->with('guest:id,first_name,last_name')
82 2
            ->with('room:id,number')
83 2
            ->getFutureReservations()
84 2
            ->orderBy('date_end')
85 2
            ->paginate($this->getItemsPerPage());
86
87 2
        if ($dataset->isEmpty()) {
88 1
            $this->addFlashMessage(trans('general.no_reservations_in_database'), 'alert-danger');
89
        }
90
91
        $viewData = [
92 2
            'columns'       => $this->reservationTableService->getColumns(),
93 2
            'dataset'       => $dataset,
94 2
            'routeName'     => $this->reservationTableService->getRouteName(),
95 2
            'title'         => $title,
96
        ];
97
98 2
        return view('list', $viewData);
99
    }
100
101 3
    public function chooseGuest(GuestTableService $guestTableService)
102
    {
103 3
        $title = trans('navigation.choose_guest');
104
105 3
        $dataset = Guest::select('id', 'first_name', 'last_name', 'address', 'zip_code', 'place', 'PESEL', 'contact')
106 3
            ->paginate($this->getItemsPerPage());
107
108 3
        if ($dataset->isEmpty()) {
109 1
            $this->addFlashMessage(trans('general.no_guests_in_database'), 'alert-danger');
110
        }
111
112
        $viewData = [
113 3
            'columns'         => $guestTableService->getColumns(),
114 3
            'dataset'         => $dataset,
115 3
            'routeName'       => $guestTableService->getRouteName(),
116 3
            'title'           => $title,
117 3
            'routeChooseName' => $this->reservationTableService->getRouteName().'.search_free_rooms',
118
        ];
119
120 3
        return view('list', $viewData);
121
    }
122
123 3
    public function searchFreeRooms($guestId)
124
    {
125
        try {
126 3
            $guest = Guest::select('id', 'first_name', 'last_name')->findOrFail($guestId);
127
        } catch (ModelNotFoundException $e) {
128
            return $this->returnBack([
129
                'message'     => trans('general.object_not_found'),
130
                'alert-class' => 'alert-danger',
131
            ]);
132
        }
133
134 3
        $dataset = new Reservation();
135 3
        $dataset->guest()->associate($guest);
136 3
        $title = trans('navigation.search_free_rooms');
137 3
        $submitRoute = route($this->reservationTableService->getRouteName().'.post_search_free_rooms', $dataset->guest->id);
0 ignored issues
show
Bug introduced by
$dataset->guest->id of type integer is incompatible with the type array expected by parameter $parameters of route(). ( Ignorable by Annotation )

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

137
        $submitRoute = route($this->reservationTableService->getRouteName().'.post_search_free_rooms', /** @scrutinizer ignore-type */ $dataset->guest->id);
Loading history...
138
139 3
        $fiels = $this->getFields();
140 3
        array_unshift($fiels, $this->getGuestField());
141
142
        $viewData = [
143 3
            'dataset'     => $dataset,
144 3
            'fields'      => $fiels,
145 3
            'title'       => $title,
146 3
            'submitRoute' => $submitRoute,
147
        ];
148
149 3
        return view('addedit', $viewData);
150
    }
151
152 2
    public function postSearchFreeRooms(ReservationSearchRequest $request, $guestId = null)
153
    {
154
        try {
155 2
            $guest = Guest::select('id')->findOrFail($guestId);
156
        } catch (ModelNotFoundException $e) {
157
            return $this->returnBack([
158
                'message'     => trans('general.object_not_found'),
159
                'alert-class' => 'alert-danger',
160
            ]);
161
        }
162
163 2
        $data = $request->only(['date_start', 'date_end', 'people']);
164
165 2
        return redirect()->route($this->reservationTableService->getRouteName().'.choose_free_room', $guest->id)
0 ignored issues
show
Bug introduced by
$guest->id of type integer is incompatible with the type array expected by parameter $parameters of Illuminate\Routing\Redirector::route(). ( Ignorable by Annotation )

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

165
        return redirect()->route($this->reservationTableService->getRouteName().'.choose_free_room', /** @scrutinizer ignore-type */ $guest->id)
Loading history...
166 2
            ->with($data);
167
    }
168
169
    /**
170
     * @param RoomTableService $roomTableService
171
     * @param int              $guestId
172
     *
173
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
174
     */
175 2
    public function chooseFreeRoom(RoomTableService $roomTableService, $guestId)
176
    {
177 2
        if (!$this->isReservationDataInSessionCorrect()) {
178
            return $this->returnBack([
179
                'message'     => trans('general.object_not_found'),
180
                'alert-class' => 'alert-danger',
181
            ]);
182
        }
183
184
        try {
185 2
            $guest = Guest::select('id', 'first_name', 'last_name')->findOrFail($guestId);
186
        } catch (ModelNotFoundException $e) {
187
            // TODO: logger helper
188
            Log::warning(__CLASS__.'::'.__FUNCTION__.' at '.__LINE__.': '.$e->getMessage());
189
190
            return $this->returnBack([
191
                'message'     => trans('general.object_not_found'),
192
                'alert-class' => 'alert-danger',
193
            ]);
194
        }
195
196 2
        $dateStart = Session::get('date_start');
197 2
        $dateEnd = Session::get('date_end');
198 2
        $people = Session::get('people');
199
200 2
        $dateStart = Carbon::parse($dateStart);
201 2
        $dateEnd = Carbon::parse($dateEnd);
202
203 2
        $title = trans('navigation.choose_room_for').' '.$guest->fullName;
0 ignored issues
show
Bug introduced by
Are you sure trans('navigation.choose_room_for') of type null|string|array can be used in concatenation? ( Ignorable by Annotation )

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

203
        $title = /** @scrutinizer ignore-type */ trans('navigation.choose_room_for').' '.$guest->fullName;
Loading history...
204
205 2
        $dataset = Room::select('id', 'number', 'floor', 'capacity', 'price', 'comment')
206 2
            ->freeRoomsForReservation($dateStart, $dateEnd, $people)
207 2
            ->paginate($this->getItemsPerPage());
208
209 2
        if ($dataset->isEmpty()) {
210 1
            $this->addFlashMessage(trans('general.no_rooms_in_database'), 'alert-danger');
211
        }
212
213
        $viewData = [
214 2
            'columns'               => $roomTableService->getColumns(),
215 2
            'dataset'               => $dataset,
216 2
            'routeName'             => $roomTableService->getRouteName(),
217 2
            'title'                 => $title,
218 2
            'routeChooseName'       => $this->reservationTableService->getRouteName().'.add',
219 2
            'additionalRouteParams' => $guest->id,
220
        ];
221
222 2
        return view('list', $viewData);
223
    }
224
225 1
    public function add($guestId, $roomId)
226
    {
227 1
        if (!$this->isReservationDataInSessionCorrect()) {
228
            return $this->returnBack([
229
                'message'     => trans('general.object_not_found'),
230
                'alert-class' => 'alert-danger',
231
            ]);
232
        }
233
234 1
        $dateStart = Session::get('date_start');
235 1
        $dateEnd = Session::get('date_end');
236 1
        $people = Session::get('people');
237
238
        try {
239 1
            $guest = Guest::select('id')->findOrFail($guestId);
240 1
            $room = Room::select('id')->findOrFail($roomId);
241
        } catch (ModelNotFoundException $e) {
242
            Log::warning(__CLASS__.'::'.__FUNCTION__.' at '.__LINE__.': '.$e->getMessage());
243
244
            return $this->returnBack([
245
                'message'     => trans('general.object_not_found'),
246
                'alert-class' => 'alert-danger',
247
            ]);
248
        }
249
250 1
        $reservation = new Reservation();
251 1
        $reservation->guest_id = $guest->id;
252 1
        $reservation->room_id = $room->id;
253 1
        $reservation->date_start = $dateStart;
254 1
        $reservation->date_end = $dateEnd;
255 1
        $reservation->people = $people;
256
257 1
        $reservation->save();
258
259 1
        $this->addFlashMessage(trans('general.saved'), 'alert-success');
260
261 1
        return redirect()->route($this->reservationTableService->getRouteName().'.index');
262
    }
263
264
    // TODO
265
    public function store(ReservationSearchRequest $request, $objectId = null)
266
    {
267
        if ($objectId === null) {
268
            $object = new Reservation();
269
        } else {
270
            try {
271
                $object = Reservation::findOrFail($objectId);
272
            } catch (ModelNotFoundException $e) {
273
                return $this->returnBack([
274
                    'message'     => trans('general.object_not_found'),
275
                    'alert-class' => 'alert-danger',
276
                ]);
277
            }
278
        }
279
280
        $object->fill($request->all());
281
        $object->save();
282
283
        return redirect()->route($this->reservationTableService->getRouteName().'.index')
284
            ->with([
285
                'message'     => trans('general.saved'),
286
                'alert-class' => 'alert-success',
287
            ]);
288
    }
289
290 1
    public function delete($objectId)
291
    {
292
        try {
293 1
            $object = Reservation::findOrFail($objectId);
294
        } catch (ModelNotFoundException $e) {
295
            $data = ['class' => 'alert-danger', 'message' => trans('general.object_not_found')];
296
297
            return response()->json($data);
298
        }
299
300 1
        $object->delete();
301
302 1
        $data = ['class' => 'alert-success', 'message' => trans('general.deleted')];
303
304 1
        return response()->json($data);
305
    }
306
307 2
    public function showEditForm($objectId)
308
    {
309
        try {
310 2
            $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
311 2
            ->with('guest:id,first_name,last_name')
312 2
            ->with('room:id,number')
313 2
            ->findOrFail($objectId);
314 1
        } catch (ModelNotFoundException $e) {
315 1
            return $this->returnBack([
316 1
                'message'     => trans('general.object_not_found'),
317 1
                'alert-class' => 'alert-danger',
318
            ]);
319
        }
320
321 1
        $title = trans('navigation.edit_reservation');
322 1
        $submitRoute = route($this->reservationTableService->getRouteName().'.postedit', $objectId);
323
324 1
        $fiels = $this->getFields();
325 1
        array_unshift($fiels, $this->getGuestField(), $this->getRoomField(), $this->getActionButtons());
326
327
        $viewData = [
328 1
            'dataset'     => $dataset,
329 1
            'fields'      => $fiels,
330 1
            'title'       => $title,
331 1
            'submitRoute' => $submitRoute,
332 1
            'routeName'   => $this->reservationTableService->getRouteName(),
333
        ];
334
335 1
        return view('addedit', $viewData);
336
    }
337
338
    public function editChooseGuest(GuestTableService $guestTableService, $reservationId)
339
    {
340
        try {
341
            $reservation = Reservation::select('id', 'guest_id')
342
                ->findOrFail($reservationId);
343
        } catch (ModelNotFoundException $e) {
344
            return $this->returnBack([
345
                'message'     => trans('general.object_not_found'),
346
                'alert-class' => 'alert-danger',
347
            ]);
348
        }
349
350
        $title = trans('navigation.change_guest_for_reservation');
351
352
        $dataset = Guest::select('id', 'first_name', 'last_name', 'address', 'zip_code', 'place', 'PESEL', 'contact')
353
            ->whereNotIn('id', [$reservation->guest_id])
354
            ->paginate($this->getItemsPerPage());
355
356
        if ($dataset->isEmpty()) {
357
            $this->addFlashMessage(trans('general.no_guests_in_database'), 'alert-danger');
358
        }
359
360
        $viewData = [
361
            'columns'               => $guestTableService->getColumns(),
362
            'dataset'               => $dataset,
363
            'routeName'             => $guestTableService->getRouteName(),
364
            'title'                 => $title,
365
            'routeChooseName'       => $this->reservationTableService->getRouteName().'.edit_change_guest',
366
            'additionalRouteParams' => $reservation->id,
367
        ];
368
369
        return view('list', $viewData);
370
    }
371
372
    public function editChooseRoom(RoomTableService $roomTableService, $reservationId)
373
    {
374
        try {
375
            $reservation = Reservation::select('id', 'guest_id', 'date_start', 'date_end', 'people')
376
                ->findOrFail($reservationId);
377
        } catch (ModelNotFoundException $e) {
378
            return $this->returnBack([
379
                'message'     => trans('general.object_not_found'),
380
                'alert-class' => 'alert-danger',
381
            ]);
382
        }
383
384
        $dateStart = Carbon::parse($reservation->date_start);
385
        $dateEnd = Carbon::parse($reservation->date_end);
386
387
        $title = trans('navigation.change_room_for_reservation');
388
389
        $dataset = Room::select('id', 'number', 'floor', 'capacity', 'price', 'comment')
390
            ->freeRoomsForReservation($dateStart, $dateEnd, $reservation->people)
391
            ->paginate($this->getItemsPerPage());
392
393
        if ($dataset->isEmpty()) {
394
            $this->addFlashMessage(trans('general.no_rooms_in_database'), 'alert-danger');
395
        }
396
397
        $viewData = [
398
            'columns'               => $roomTableService->getColumns(),
399
            'dataset'               => $dataset,
400
            'routeName'             => $roomTableService->getRouteName(),
401
            'title'                 => $title,
402
            'routeChooseName'       => $this->reservationTableService->getRouteName().'.edit_change_room',
403
            'additionalRouteParams' => $reservation->id,
404
        ];
405
406
        return view('list', $viewData);
407
    }
408
409 4
    public function getGuestField()
410
    {
411
        return [
412 4
            'id'    => 'guest',
413 4
            'title' => trans('general.guest'),
414 4
            'value' => function (Reservation $data) {
415 4
                return $data->guest->full_name;
416 4
            },
417
            'optional' => [
418
                'readonly' => 'readonly',
419
            ],
420
        ];
421
    }
422
423 1
    public function getRoomField()
424
    {
425
        return [
426 1
            'id'    => 'room',
427 1
            'title' => trans('general.room'),
428 1
            'value' => function (Reservation $data) {
429 1
                return $data->room->number;
430 1
            },
431
            'optional' => [
432
                'readonly' => 'readonly',
433
            ],
434
        ];
435
    }
436
437 1
    public function getActionButtons()
438
    {
439
        return [
440 1
            'id'         => 'action_buttons',
441 1
            'type'       => 'buttons',
442
            'buttons'    => [
443
                [
444 1
                    'value' => function () {
445 1
                        return 'Zmień gościa';
446 1
                    },
447 1
                    'route_name'  => 'reservation.edit_choose_guest',
448 1
                    'route_param' => function (Reservation $data) {
449 1
                        return $data->id;
450 1
                    },
451
                    'optional' => [
452
                        'class' => 'btn btn-primary',
453
                    ],
454
                ],
455
                [
456 1
                    'value' => function () {
457 1
                        return 'Zmień pokój';
458 1
                    },
459 1
                    'route_name'  => 'reservation.edit_choose_room',
460 1
                    'route_param' => function (Reservation $data) {
461 1
                        return $data->id;
462 1
                    },
463
                    'optional' => [
464
                        'class' => 'btn btn-primary',
465
                    ],
466
                ],
467
            ],
468
        ];
469
    }
470
471 4
    public function getFields()
472
    {
473
        return [
474
            [
475 4
                'id'    => 'date_start',
476 4
                'title' => trans('general.date_start'),
477 4
                'value' => function (Reservation $data) {
478 4
                    return $data->date_start;
479 4
                },
480 4
                'type'     => 'text',
481
                'optional' => [
482
                    'required'    => 'required',
483
                    'class'       => 'datepicker start-date',
484
                    'placeholder' => 'dd.mm.rrrr',
485
                ],
486
            ],
487
            [
488 4
                'id'    => 'date_end',
489 4
                'title' => trans('general.date_end'),
490 4
                'value' => function (Reservation $data) {
491 4
                    return $data->date_end;
492 4
                },
493 4
                'type'     => 'text',
494
                'optional' => [
495
                    'required'    => 'required',
496
                    'class'       => 'datepicker end-date',
497
                    'placeholder' => 'dd.mm.rrrr',
498
                ],
499
            ],
500
            [
501 4
                'id'    => 'people',
502 4
                'title' => trans('general.number_of_people'),
503 4
                'value' => function (Reservation $data) {
504 4
                    return $data->people ?: 1;
505 4
                },
506 4
                'type'     => 'number',
507
                'optional' => [
508
                    'required' => 'required',
509
                    'min'      => '1',
510
                ],
511
            ],
512
        ];
513
    }
514
515 2
    private function isReservationDataInSessionCorrect()
516
    {
517 2
        if (!Session::has(['date_start', 'date_end', 'people'])) {
518
            Log::error('Missing one of Session keys: date_start, date_end, people');
519
520
            return false;
521
        }
522
523 2
        Session::reflash();
524
525 2
        return true;
526
    }
527
}
528