ReservationController::getFields()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 39
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 4

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 4
eloc 27
nc 4
nop 1
dl 0
loc 39
ccs 22
cts 22
cp 1
crap 4
rs 9.488
c 1
b 1
f 0
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Http\Interfaces\ManageTableInterface;
6
use App\Http\Requests\ReservationAddRequest;
7
use App\Http\Requests\ReservationEditRequest;
8
use App\Models\Guest;
9
use App\Models\Reservation;
10
use App\Models\Room;
11
use App\Services\GuestTableService;
12
use App\Services\ReservationTableService;
13
use App\Services\RoomTableService;
14
use Carbon\Carbon;
15
use Illuminate\Database\Eloquent\ModelNotFoundException;
16
use Illuminate\Database\Query\Builder;
17
use Illuminate\Support\Facades\DB;
18
use Illuminate\Support\Facades\Log;
19
use Illuminate\Support\Facades\Session;
20
21
class ReservationController extends Controller implements ManageTableInterface
22
{
23
    protected $reservationTableService;
24
25 39
    public function __construct(ReservationTableService $reservationTableService)
26
    {
27 39
        $this->reservationTableService = $reservationTableService;
28 39
    }
29
30 17
    public function index()
31
    {
32 17
        $title = trans('navigation.all_reservations');
33
34 17
        $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
35 17
            ->with('guest:id,first_name,last_name')
36 17
            ->with('room:id,number')
37 17
            ->orderBy('date_end', 'DESC')
38 17
            ->paginate($this->getItemsPerPage());
39
40 17
        if ($dataset->isEmpty()) {
41 9
            $this->addFlashMessage(trans('general.no_reservations_in_database'), 'alert-danger');
42
        }
43
44
        $viewData = [
45 17
            'columns'       => $this->reservationTableService->getColumns(),
46 17
            'dataset'       => $dataset,
47 17
            'routeName'     => $this->reservationTableService->getRouteName(),
48 17
            'title'         => $title,
49
        ];
50
51 17
        return view('list', $viewData);
52
    }
53
54 2
    public function current()
55
    {
56 2
        $title = trans('navigation.current_reservations');
57
58 2
        $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
59 2
            ->with('guest:id,first_name,last_name')
60 2
            ->with('room:id,number')
61 2
            ->getCurrentReservations()
62 2
            ->orderBy('date_end')
63 2
            ->paginate($this->getItemsPerPage());
64
65 2
        if ($dataset->isEmpty()) {
66 1
            $this->addFlashMessage(trans('general.no_reservations_in_database'), 'alert-danger');
67
        }
68
69
        $viewData = [
70 2
            'columns'       => $this->reservationTableService->getColumns(),
71 2
            'dataset'       => $dataset,
72 2
            'routeName'     => $this->reservationTableService->getRouteName(),
73 2
            'title'         => $title,
74
        ];
75
76 2
        return view('list', $viewData);
77
    }
78
79 2
    public function future()
80
    {
81 2
        $title = trans('navigation.future_reservations');
82
83 2
        $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
84 2
            ->with('guest:id,first_name,last_name')
85 2
            ->with('room:id,number')
86 2
            ->getFutureReservations()
87 2
            ->orderBy('date_end')
88 2
            ->paginate($this->getItemsPerPage());
89
90 2
        if ($dataset->isEmpty()) {
91 1
            $this->addFlashMessage(trans('general.no_reservations_in_database'), 'alert-danger');
92
        }
93
94
        $viewData = [
95 2
            'columns'       => $this->reservationTableService->getColumns(),
96 2
            'dataset'       => $dataset,
97 2
            'routeName'     => $this->reservationTableService->getRouteName(),
98 2
            'title'         => $title,
99
        ];
100
101 2
        return view('list', $viewData);
102
    }
103
104 3
    public function chooseGuest(GuestTableService $guestTableService)
105
    {
106 3
        $title = trans('navigation.choose_guest');
107
108 3
        $dataset = Guest::select('id', 'first_name', 'last_name', 'address', 'zip_code', 'place', 'PESEL', 'contact')
109 3
            ->paginate($this->getItemsPerPage());
110
111 3
        if ($dataset->isEmpty()) {
112 1
            $this->addFlashMessage(trans('general.no_guests_in_database'), 'alert-danger');
113
        }
114
115
        $viewData = [
116 3
            'columns'         => $guestTableService->getColumns(),
117 3
            'dataset'         => $dataset,
118 3
            'routeName'       => $guestTableService->getRouteName(),
119 3
            'title'           => $title,
120 3
            'routeChooseName' => $this->reservationTableService->getRouteName().'.search_free_rooms',
121
        ];
122
123 3
        return view('list', $viewData);
124
    }
125
126 4
    public function searchFreeRooms($guestId)
127
    {
128
        try {
129 4
            $guest = Guest::select('id', 'first_name', 'last_name')->findOrFail($guestId);
130 1
        } catch (ModelNotFoundException $e) {
131 1
            return $this->returnBack([
132 1
                'message'     => trans('general.object_not_found'),
133 1
                'alert-class' => 'alert-danger',
134
            ]);
135
        }
136
137 3
        $dataset = new Reservation();
138 3
        $dataset->guest()->associate($guest);
139 3
        $title = trans('navigation.search_free_rooms');
140 3
        $submitRoute = route($this->reservationTableService->getRouteName().'.post_search_free_rooms', [$dataset->guest->id]);
141
142 3
        $fiels = $this->getFields(true);
143 3
        array_unshift($fiels, $this->getGuestField());
144
145
        $viewData = [
146 3
            'dataset'     => $dataset,
147 3
            'fields'      => $fiels,
148 3
            'title'       => $title,
149 3
            'submitRoute' => $submitRoute,
150
        ];
151
152 3
        return view('addedit', $viewData);
153
    }
154
155 3
    public function postSearchFreeRooms(ReservationAddRequest $request, $guestId = null)
156
    {
157
        try {
158 3
            $guest = Guest::select('id')->findOrFail($guestId);
159 1
        } catch (ModelNotFoundException $e) {
160 1
            return $this->returnBack([
161 1
                'message'     => trans('general.object_not_found'),
162 1
                'alert-class' => 'alert-danger',
163
            ]);
164
        }
165
166 2
        $data = $request->only(['date_start', 'date_end', 'people']);
167
168 2
        return redirect()->route($this->reservationTableService->getRouteName().'.choose_free_room', [$guest->id])
169 2
            ->with($data);
170
    }
171
172
    /**
173
     * @param RoomTableService $roomTableService
174
     * @param int              $guestId
175
     *
176
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
177
     */
178 5
    public function chooseFreeRoom(RoomTableService $roomTableService, $guestId)
179
    {
180 5
        if (!$this->isReservationDataInSessionCorrect()) {
181 1
            return $this->returnBack([
182 1
                'message'     => trans('general.session_error'),
183 1
                'alert-class' => 'alert-danger',
184
            ]);
185
        }
186
187
        try {
188 4
            $guest = Guest::select('id', 'first_name', 'last_name')->findOrFail($guestId);
189 1
        } catch (ModelNotFoundException $e) {
190 1
            Log::warning(__CLASS__.'::'.__FUNCTION__.' at '.__LINE__.': '.$e->getMessage());
191
192 1
            return $this->returnBack([
193 1
                'message'     => trans('general.object_not_found'),
194 1
                'alert-class' => 'alert-danger',
195
            ]);
196
        }
197
198 3
        $dateStart = Session::get('date_start');
199 3
        $dateEnd = Session::get('date_end');
200 3
        $people = Session::get('people');
201
202 3
        $dateStart = Carbon::parse($dateStart);
203 3
        $dateEnd = Carbon::parse($dateEnd);
204
205 3
        $title = trans('navigation.choose_room_for').' '.$guest->fullName;
206
207 3
        $dataset = Room::select('id', 'number', 'floor', 'capacity', 'price', 'comment')
208 3
            ->freeRoomsForReservation($dateStart, $dateEnd, $people)
209 3
            ->paginate($this->getItemsPerPage());
210
211 3
        if ($dataset->isEmpty()) {
212 1
            $this->addFlashMessage(trans('general.no_rooms_in_database'), 'alert-danger');
213
        }
214
215
        $viewData = [
216 3
            'columns'               => $roomTableService->getColumns(),
217 3
            'dataset'               => $dataset,
218 3
            'routeName'             => $roomTableService->getRouteName(),
219 3
            'title'                 => $title,
220 3
            'routeChooseName'       => $this->reservationTableService->getRouteName().'.add',
221 3
            'additionalRouteParams' => $guest->id,
222
        ];
223
224 3
        return view('list', $viewData);
225
    }
226
227 6
    public function add($guestId, $roomId)
228
    {
229 6
        if (!$this->isReservationDataInSessionCorrect()) {
230 1
            return $this->returnBack([
231 1
                'message'     => trans('general.session_error'),
232 1
                'alert-class' => 'alert-danger',
233
            ]);
234
        }
235
236 5
        $dateStart = Session::get('date_start');
237 5
        $dateEnd = Session::get('date_end');
238 5
        $people = Session::get('people');
239
240 5
        $dateStart = Carbon::parse($dateStart);
241 5
        $dateEnd = Carbon::parse($dateEnd);
242
243
        try {
244 5
            $guest = Guest::select('id')->findOrFail($guestId);
245 5
            $room = Room::select('id', 'capacity')->findOrFail($roomId);
246 1
        } catch (ModelNotFoundException $e) {
247 1
            Log::warning(__CLASS__.'::'.__FUNCTION__.' at '.__LINE__.': '.$e->getMessage());
248
249 1
            return $this->returnBack([
250 1
                'message'     => trans('general.object_not_found'),
251 1
                'alert-class' => 'alert-danger',
252
            ]);
253
        }
254
255 4
        if ($room->capacity < $people) {
256 1
            return $this->returnBack([
257 1
                'message'     => trans('general.people_exceeds_room_capacity'),
258 1
                'alert-class' => 'alert-danger',
259
            ]);
260
        }
261
262 3
        if (!$room->isFree($dateStart, $dateEnd)) {
263 1
            return $this->returnBack([
264 1
                'message'     => trans('general.dates_coincide_different_booking'),
265 1
                'alert-class' => 'alert-danger',
266
            ]);
267
        }
268
269 2
        $reservation = new Reservation();
270 2
        $reservation->guest_id = $guest->id;
271 2
        $reservation->room_id = $room->id;
272 2
        $reservation->date_start = $dateStart;
273 2
        $reservation->date_end = $dateEnd;
274 2
        $reservation->people = $people;
275
276 2
        $reservation->save();
277
278 2
        $this->addFlashMessage(trans('general.saved'), 'alert-success');
279
280 2
        return redirect()->route($this->reservationTableService->getRouteName().'.index');
281
    }
282
283 4
    public function postEdit(ReservationEditRequest $request, $objectId)
284
    {
285
        try {
286 4
            $object = Reservation::with('room:id,capacity')
287 4
                ->findOrFail($objectId);
288 1
        } catch (ModelNotFoundException $e) {
289 1
            return $this->returnBack([
290 1
                'message'     => trans('general.object_not_found'),
291 1
                'alert-class' => 'alert-danger',
292
            ]);
293
        }
294
295
        // Check room capacity for people in reservation
296 3
        if ($object->room->capacity < $request->input('people')) {
297 1
            return redirect()->back()->with([
298 1
                'message'     => trans('general.people_exceeds_room_capacity'),
299 1
                'alert-class' => 'alert-danger',
300
            ]);
301
        }
302
303 2
        $dateStart = Carbon::parse($request->input('date_start'));
304 2
        $dateEnd = Carbon::parse($request->input('date_end'));
305
306
        // Check if dates can be changed
307 2
        $reservationsIdsForDates = DB::table('reservations')
308 2
            ->where('room_id', $object->room_id)
309 2
            ->where('id', '!=', $object->id)
310
            ->where(function (Builder $query) use ($dateStart, $dateEnd) {
311
                $query->where(function (Builder $query) use ($dateStart, $dateEnd) {
312 2
                    $query->where('date_start', '<', $dateEnd)
313 2
                        ->where('date_end', '>', $dateStart);
314 2
                });
315 2
            })
316 2
            ->count();
317
318 2
        if ($reservationsIdsForDates > 0) {
319 1
            return redirect()->back()->with([
320 1
                'message'     => trans('general.dates_coincide_different_booking'),
321 1
                'alert-class' => 'alert-danger',
322
            ]);
323
        }
324
325 1
        $object->fill($request->all());
326 1
        $object->save();
327
328 1
        return redirect()->route($this->reservationTableService->getRouteName().'.index')
329 1
            ->with([
330 1
                'message'     => trans('general.saved'),
331 1
                'alert-class' => 'alert-success',
332
            ]);
333
    }
334
335 2
    public function delete($objectId)
336
    {
337
        try {
338 2
            $object = Reservation::findOrFail($objectId);
339 1
        } catch (ModelNotFoundException $e) {
340 1
            $data = ['class' => 'alert-danger', 'message' => trans('general.object_not_found')];
341
342 1
            return response()->json($data);
343
        }
344
345 1
        $object->delete();
346
347 1
        $data = ['class' => 'alert-success', 'message' => trans('general.deleted')];
348
349 1
        return response()->json($data);
350
    }
351
352 8
    public function showEditForm($objectId)
353
    {
354
        try {
355 8
            $dataset = Reservation::select('id', 'room_id', 'guest_id', 'date_start', 'date_end', 'people')
356 8
            ->with('guest:id,first_name,last_name')
357 8
            ->with('room:id,number')
358 8
            ->findOrFail($objectId);
359 1
        } catch (ModelNotFoundException $e) {
360 1
            return $this->returnBack([
361 1
                'message'     => trans('general.object_not_found'),
362 1
                'alert-class' => 'alert-danger',
363
            ]);
364
        }
365
366 7
        $title = trans('navigation.edit_reservation');
367 7
        $submitRoute = route($this->reservationTableService->getRouteName().'.postedit', $objectId);
368
369 7
        $fiels = $this->getFields();
370 7
        array_unshift($fiels, $this->getGuestField(), $this->getRoomField(), $this->getActionButtons());
371
372
        $viewData = [
373 7
            'dataset'     => $dataset,
374 7
            'fields'      => $fiels,
375 7
            'title'       => $title,
376 7
            'submitRoute' => $submitRoute,
377 7
            'routeName'   => $this->reservationTableService->getRouteName(),
378
        ];
379
380 7
        return view('addedit', $viewData);
381
    }
382
383 3
    public function editChooseGuest(GuestTableService $guestTableService, $reservationId)
384
    {
385
        try {
386 3
            $reservation = Reservation::select('id', 'guest_id')->findOrFail($reservationId);
387 1
        } catch (ModelNotFoundException $e) {
388 1
            return $this->returnBack([
389 1
                'message'     => trans('general.object_not_found'),
390 1
                'alert-class' => 'alert-danger',
391
            ]);
392
        }
393
394 2
        $title = trans('navigation.change_guest_for_reservation');
395
396 2
        $dataset = Guest::select('id', 'first_name', 'last_name', 'address', 'zip_code', 'place', 'PESEL', 'contact')
397 2
            ->whereNotIn('id', [$reservation->guest_id])
398 2
            ->paginate($this->getItemsPerPage());
399
400 2
        if ($dataset->isEmpty()) {
401 1
            $this->addFlashMessage(trans('general.no_guests_in_database'), 'alert-danger');
402
        }
403
404
        $viewData = [
405 2
            'columns'               => $guestTableService->getColumns(),
406 2
            'dataset'               => $dataset,
407 2
            'routeName'             => $guestTableService->getRouteName(),
408 2
            'title'                 => $title,
409 2
            'routeChooseName'       => $this->reservationTableService->getRouteName().'.edit_change_guest',
410 2
            'additionalRouteParams' => $reservation->id,
411
        ];
412
413 2
        return view('list', $viewData);
414
    }
415
416 2
    public function editChangeGuest($reservationId, $guestId)
417
    {
418
        try {
419 2
            $reservation = Reservation::select('id')->findOrFail($reservationId);
420 2
            $guest = Guest::select('id')->findOrFail($guestId);
421 1
        } catch (ModelNotFoundException $e) {
422 1
            return $this->returnBack([
423 1
                'message'     => trans('general.object_not_found'),
424 1
                'alert-class' => 'alert-danger',
425
            ]);
426
        }
427
428 1
        $reservation->guest_id = $guest->id;
429 1
        $reservation->save();
430
431 1
        return redirect()->route($this->reservationTableService->getRouteName().'.editform', [$reservation->id])
432 1
            ->with([
433 1
                'message'     => trans('general.saved'),
434 1
                'alert-class' => 'alert-success',
435
            ]);
436
    }
437
438 3
    public function editChooseRoom(RoomTableService $roomTableService, $reservationId)
439
    {
440
        try {
441 3
            $reservation = Reservation::select('id', 'guest_id', 'date_start', 'date_end', 'people')
442 3
                ->findOrFail($reservationId);
443 1
        } catch (ModelNotFoundException $e) {
444 1
            return $this->returnBack([
445 1
                'message'     => trans('general.object_not_found'),
446 1
                'alert-class' => 'alert-danger',
447
            ]);
448
        }
449
450 2
        $dateStart = Carbon::parse($reservation->date_start);
451 2
        $dateEnd = Carbon::parse($reservation->date_end);
452
453 2
        $title = trans('navigation.change_room_for_reservation');
454
455 2
        $dataset = Room::select('id', 'number', 'floor', 'capacity', 'price', 'comment')
456 2
            ->freeRoomsForReservation($dateStart, $dateEnd, $reservation->people)
457 2
            ->paginate($this->getItemsPerPage());
458
459 2
        if ($dataset->isEmpty()) {
460 1
            $this->addFlashMessage(trans('general.no_rooms_in_database'), 'alert-danger');
461
        }
462
463
        $viewData = [
464 2
            'columns'               => $roomTableService->getColumns(),
465 2
            'dataset'               => $dataset,
466 2
            'routeName'             => $roomTableService->getRouteName(),
467 2
            'title'                 => $title,
468 2
            'routeChooseName'       => $this->reservationTableService->getRouteName().'.edit_change_room',
469 2
            'additionalRouteParams' => $reservation->id,
470
        ];
471
472 2
        return view('list', $viewData);
473
    }
474
475 4
    public function editChangeRoom($reservationId, $roomId)
476
    {
477
        try {
478 4
            $reservation = Reservation::select('id', 'people', 'date_start', 'date_end')
479 4
                ->findOrFail($reservationId);
480 4
            $room = Room::select('id', 'capacity')->findOrFail($roomId);
481 1
        } catch (ModelNotFoundException $e) {
482 1
            return $this->returnBack([
483 1
                'message'     => trans('general.object_not_found'),
484 1
                'alert-class' => 'alert-danger',
485
            ]);
486
        }
487
488 3
        $dateStart = Carbon::parse($reservation->date_start);
489 3
        $dateEnd = Carbon::parse($reservation->date_end);
490
491 3
        if ($room->capacity < $reservation->people) {
492 1
            return $this->returnBack([
493 1
                'message'     => trans('general.people_exceeds_room_capacity'),
494 1
                'alert-class' => 'alert-danger',
495
            ]);
496
        }
497
498 2
        if (!$room->isFree($dateStart, $dateEnd)) {
499 1
            return $this->returnBack([
500 1
                'message'     => trans('general.dates_coincide_different_booking'),
501 1
                'alert-class' => 'alert-danger',
502
            ]);
503
        }
504
505 1
        $reservation->room_id = $room->id;
506 1
        $reservation->save();
507
508 1
        return redirect()->route($this->reservationTableService->getRouteName().'.editform', [$reservation->id])
509 1
            ->with([
510 1
                'message'     => trans('general.saved'),
511 1
                'alert-class' => 'alert-success',
512
            ]);
513
    }
514
515 10
    public function getGuestField()
516
    {
517
        return [
518 10
            'id'    => 'guest',
519 10
            'title' => trans('general.guest'),
520
            'value' => function (Reservation $data) {
521 10
                return $data->guest->full_name;
522 10
            },
523
            'optional' => [
524
                'readonly' => 'readonly',
525
            ],
526
        ];
527
    }
528
529 7
    public function getRoomField()
530
    {
531
        return [
532 7
            'id'    => 'room',
533 7
            'title' => trans('general.room'),
534
            'value' => function (Reservation $data) {
535 7
                return $data->room->number;
536 7
            },
537
            'optional' => [
538
                'readonly' => 'readonly',
539
            ],
540
        ];
541
    }
542
543 7
    public function getActionButtons()
544
    {
545
        return [
546 7
            'id'         => 'action_buttons',
547 7
            'type'       => 'buttons',
548
            'buttons'    => [
549
                [
550
                    'value' => function () {
551 7
                        return trans('general.change_guest');
552 7
                    },
553 7
                    'route_name'  => 'reservation.edit_choose_guest',
554
                    'route_param' => function (Reservation $data) {
555 7
                        return $data->id;
556 7
                    },
557
                    'optional' => [
558
                        'class' => 'btn btn-primary',
559
                    ],
560
                ],
561
                [
562
                    'value' => function () {
563 7
                        return trans('general.change_room');
564 7
                    },
565 7
                    'route_name'  => 'reservation.edit_choose_room',
566
                    'route_param' => function (Reservation $data) {
567 7
                        return $data->id;
568 7
                    },
569
                    'optional' => [
570
                        'class' => 'btn btn-primary',
571
                    ],
572
                ],
573
            ],
574
        ];
575
    }
576
577 10
    public function getFields($forAdd = false)
578
    {
579
        return [
580
            [
581 10
                'id'    => 'date_start',
582 10
                'title' => trans('general.date_start'),
583
                'value' => function (Reservation $data) {
584 10
                    return $data->date_start;
585 10
                },
586 10
                'type'     => 'text',
587
                'optional' => [
588 10
                    'required'    => 'required',
589 10
                    'class'       => 'datepicker'.($forAdd ? ' start-date' : null),
590 10
                    'placeholder' => 'dd.mm.rrrr',
591
                ],
592
            ],
593
            [
594 10
                'id'    => 'date_end',
595 10
                'title' => trans('general.date_end'),
596
                'value' => function (Reservation $data) {
597 10
                    return $data->date_end;
598 10
                },
599 10
                'type'     => 'text',
600
                'optional' => [
601 10
                    'required'    => 'required',
602 10
                    'class'       => 'datepicker'.($forAdd ? ' end-date' : null),
603 10
                    'placeholder' => 'dd.mm.rrrr',
604
                ],
605
            ],
606
            [
607 10
                'id'    => 'people',
608 10
                'title' => trans('general.number_of_people'),
609
                'value' => function (Reservation $data) {
610 10
                    return $data->people ?: 1;
611 10
                },
612 10
                'type'     => 'number',
613
                'optional' => [
614
                    'required' => 'required',
615
                    'min'      => '1',
616
                ],
617
            ],
618
        ];
619
    }
620
621 10
    private function isReservationDataInSessionCorrect()
622
    {
623 10
        if (!Session::has(['date_start', 'date_end', 'people'])) {
624 2
            Log::error('Missing one of Session keys: date_start, date_end, people');
625
626 2
            return false;
627
        }
628
629 8
        Session::reflash();
630
631 8
        return true;
632
    }
633
}
634