diff --git a/app/Http/Controllers/BookingAPIController.php b/app/Http/Controllers/BookingAPIController.php index 5bd04e1..657bc45 100644 --- a/app/Http/Controllers/BookingAPIController.php +++ b/app/Http/Controllers/BookingAPIController.php @@ -4,6 +4,7 @@ use App\Models\Booking; use App\Models\Room; +use Carbon\Carbon; use App\Services\BookingService; use Illuminate\Http\Request; @@ -61,22 +62,59 @@ public function create(Request $request) } if (BookingService::dateConflict($room, $request->start, $request->end )) { - return response()->json([ - 'message' => "The {$room->name} room is unavailable for the chosen dates." - ], 400); + return response()->json([ + 'message' => "The {$room->name} room is unavailable for the chosen dates." + ], 400); } $booking = new Booking(); - $booking->room_id = $request->room_id; $booking->customer = $request->customer; $booking->start = $request->start; $booking->end = $request->end; - $booking->save(); return response()->json([ 'message' => "Booking successfully created" ], 201); } + + public function report() + { + $reportData = []; + // We add this at the top of the method in order to create an empty array (which + // we will fill with the required variables + + $roomsWithBookings = Room::with('booking') + ->get()?->makeHidden(['rate', 'image', 'min_capacity', 'max_capacity', 'description', 'type_id', 'created_at', + 'updated_at', 'booking']); + + foreach ($roomsWithBookings as $roomWithBooking) { + $roomBookingCount = $roomWithBooking->booking->count(); + $roomName = $roomWithBooking->name; + $roomId = $roomWithBooking->id; + $total = 0; + + foreach ($roomWithBooking->booking as $booking) { + $checkIn = Carbon::parse($booking['start']); + $checkOut = Carbon::parse($booking['end']); + + $total += $checkIn->diffInDays($checkOut); + } + + $averageStay = $roomBookingCount > 0 ? $total / $roomBookingCount : 0; + // We are accessing the variables and adding them into the empty array + $reportData[] = [ + 'id' => $roomId, + 'name' => $roomName, + 'booking_count' => $roomBookingCount, + 'average_booking_duration' => round($averageStay, 1), + ]; + } + + return response()->json([ + 'message' => 'Report generated', + 'data' => $reportData + ]); + } } diff --git a/routes/api.php b/routes/api.php index 52cdcdb..5dfc8c6 100644 --- a/routes/api.php +++ b/routes/api.php @@ -14,5 +14,4 @@ Route::get('/bookings',[BookingAPIController::class,'index']); Route::post('/bookings', [BookingAPIController::class, 'create']); - - +Route::get('/bookings/report',[BookingAPIController::class,'report']); diff --git a/tests/Feature/BookingTest.php b/tests/Feature/BookingTest.php index 6b95170..749b25f 100644 --- a/tests/Feature/BookingTest.php +++ b/tests/Feature/BookingTest.php @@ -158,6 +158,28 @@ public function test_getBookingsById_success(): void }); } + public function test_reportDataSuccess(): void + { + Room::factory()->create(); + Booking::factory()->create(); + Booking::factory()->create(); + + $response = $this->getJson('/api/bookings/report'); + $response->assertStatus(200) + ->assertJson(function (AssertableJson $json) { + $json->hasAll(['message', 'data']) + ->has('data', 3 , function (AssertableJson $data) { + $data->hasAll(['id', 'name', 'booking_count', 'average_booking_duration']) + ->whereAllType([ + 'id' => 'integer', + 'name' => 'string', + 'booking_count' => 'integer', + 'average_booking_duration' => 'integer' + ]); + }); + }); + } + public function test_getBookingsById_failure_idNotFound(): void { $response = $this->getJson('/api/bookings?room_id=1');