Skip to content

Commit

Permalink
Add booking completed
Browse files Browse the repository at this point in the history
  • Loading branch information
DevSaad02 committed Mar 6, 2025
1 parent 1251ff8 commit be46f44
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 35 deletions.
5 changes: 5 additions & 0 deletions app/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Slim\Exception\HttpNotFoundException;
use App\Application\Actions\User\ViewUserAction;
use App\Application\Actions\User\ListUsersAction;
use App\Controllers\HomeController;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Interfaces\RouteCollectorProxyInterface as Group;
Expand Down Expand Up @@ -47,6 +48,9 @@

return $next($request, $response);
};
$app->group('/analytics', function (Group $group) {
$group->get('', [HomeController::class, 'analytics']);
})->add(JwtMiddleware::class);
$app->group('/auth', function (Group $group) {

$group->post('/register', [AuthController::class, 'register']);
Expand All @@ -63,6 +67,7 @@
$group->get('/{id}/slots', [ParkingController::class, 'getSlotsByParkingId']);
})->add(JwtMiddleware::class);
$app->group('/booking', function (Group $group) {
$group->get('', [BookingController::class, 'getBookings']);
$group->post('', [BookingController::class, 'addBooking']);
$group->post('/available-slots', [BookingController::class, 'getAvailableSlots']);
})->add(JwtMiddleware::class);
Expand Down
70 changes: 36 additions & 34 deletions src/Controllers/BookingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,25 @@ public function __construct(LoggerInterface $logger, ArrayConversionService $arr
$this->arrayConversionService = $arrayConversionService;
}

public function getParkings(Request $request, Response $response)
public function getBookings(Request $request, Response $response)
{
$this->logger->info('Fetching parkings');
$this->logger->info('Fetching bookings');
try {
$parkings = Model::factory('Parking')->find_many();
$this->logger->info('Parkings fetched successfully');
$bookings = Model::factory('Booking')->find_many();
$this->logger->info('Bookings fetched successfully');
return $this->response($response, [
'status' => 'success',
'message' => 'Parkings fetched successfully',
'data' => $this->arrayConversionService->convertCollectionToArray($parkings)
'message' => 'Bookings fetched successfully',
'data' => $this->arrayConversionService->convertCollectionToArray($bookings)
]);
} catch (PDOException $e) {
return $this->response($response, [
'status' => 'error',
'message' => 'Error fetching parkings',
'message' => 'Error fetching bookings',
'error' => $e->getMessage()
]);
} catch (\Exception $e) {
$this->logger->error("Failed to fetch parkings", ['exception' => $e]);
$this->logger->error("Failed to fetch bookings", ['exception' => $e]);
throw new HttpInternalServerErrorException($request, "An error occurred: " . $e->getMessage());
}
}
Expand All @@ -55,20 +55,20 @@ public function addBooking(Request $request, Response $response)
$this->logger->info('Adding parking');
try {
$data = $request->getParsedBody();
if (empty($data['vehicle_number']) || empty($data['contact_number']) || empty($data['date']) || empty($data['start_time']) || empty($data['end_time'])) {
$data['user_id'] = $request->getAttribute('user_id');
if (empty($data['vehicle_registration_number']) || empty($data['contact_number']) || empty($data['date']) || empty($data['start_time']) || empty($data['end_time'])) {
throw new HttpBadRequestException($request, "Fields are required");
}
// Check if booking already exists
$booking = Model::factory('Booking')->where('date', $data['date'])->where('start_time', $data['start_time'])->where('end_time', $data['end_time'])->find_one();
if($booking){
if ($booking) {
throw new HttpBadRequestException($request, "Booking already exists");
}
// Create Booking
$booking = Model::factory('Booking')->create();
$booking->user_id = $data['user_id'];
$booking->slot_id = $data['slot_id'];
$booking->vehicle_registration_number = $data['vehicle_registration_number'];
$booking->vehicle_number = $data['vehicle_number'];
$booking->vehicle_type = $data['vehicle_type'];
$booking->vehicle_name = $data['vehicle_name'];
$booking->vehicle_owner = $data['vehicle_owner'];
Expand All @@ -87,8 +87,9 @@ public function addBooking(Request $request, Response $response)
$booked_slot->save();
return $this->response($response, [
'status' => 'success',
'message' => 'Booking added successfully',
'data' => $booking], 201);
'message' => 'Booking added successfully',
'data' => $this->arrayConversionService->convertToArray($booking)
], 201);
} catch (PDOException $e) {
$this->logger->error("Database error occurred while adding booking", ['exception' => $e]);
throw new HttpInternalServerErrorException($request, "Database error occurred: " . $e->getMessage());
Expand All @@ -104,48 +105,50 @@ public function addBooking(Request $request, Response $response)
public function getAvailableSlots(Request $request, Response $response)
{
$this->logger->info('Fetching available slots');
try{
try {
$data = $request->getParsedBody();
if (empty($data['parking_id']) || empty($data['date']) || empty($data['start_time']) || empty($data['end_time'])) {
throw new HttpBadRequestException($request, "Fields are required");
}

$parkingId = is_array($data['parking_id']) ? (int) reset($data['parking_id']) : (int) $data['parking_id'];
$date = (string) $data['date'];
$startTime = (string) $data['start_time'];
$endTime = (string) $data['end_time'];

ORM::configure('logging', true);

// Validate that end_time is greater than start_time
if ($startTime >= $endTime) {
throw new HttpBadRequestException($request, "End time must be greater than start time");
}

ORM::configure('logging', true);


$slots = Model::factory('Slot')
->table_alias('s')
->left_outer_join('booked_slot', 's.id = booked_slot.slot_id AND booked_slot.date = '.$date)
->where('s.parking_id', $parkingId)
->where_raw('(booked_slot.id IS NULL OR NOT (booked_slot.start_time < '.$endTime.' AND booked_slot.end_time > '.$startTime.'))')
->select_expr('s.*, CASE
->table_alias('s')
->left_outer_join('booked_slot', 's.id = booked_slot.slot_id AND booked_slot.date = "' . $date . '"')
->where_raw('s.parking_id = "' . $parkingId . '"')
->where_raw('(booked_slot.id IS NULL OR NOT (booked_slot.start_time < "' . $endTime . '" AND booked_slot.end_time > "' . $startTime . '"))')
->select_expr('s.*, CASE
WHEN booked_slot.id IS NOT NULL
AND booked_slot.start_time < '.$endTime.'
AND booked_slot.end_time > '.$startTime.'
THEN "reserved" ELSE "available"
END AS status');
AND booked_slot.start_time < "' . $endTime . '"
AND booked_slot.end_time > "' . $startTime . '"
THEN "occupied" ELSE "available"
END AS slot_status');

// Log the query and parameters before executing
$lastQuery = $slots->_build_select();
$this->logger->info("Query to be executed: " . $lastQuery);
$slots = $slots->find_many();
// Log the query and parameters before executing
$lastQuery = $slots->_build_select();
$this->logger->info("Query to be executed: " . $lastQuery);
$slots = $slots->find_many();


return $this->response($response, [
'status' => 'success',
'message' => 'Available slots fetched successfully',
'data' => $this->arrayConversionService->convertCollectionToArray($slots)
]);
} catch (PDOException $e) {
$lastQuery = ORM::get_last_query();
$this->logger->info("Last executed query: " . $lastQuery);
// $this->logger->error("Database error occurred while fetching available slots", ['exception' => $e]);
$this->logger->info("Last executed query: " . $lastQuery);
$this->logger->error("Database error occurred while fetching available slots", ['exception' => $e]);
throw new HttpInternalServerErrorException($request, "Database error occurred: " . $e->getMessage());
} catch (HttpBadRequestException $e) {
$this->logger->warning("Bad request: " . $e->getMessage());
Expand All @@ -155,5 +158,4 @@ public function getAvailableSlots(Request $request, Response $response)
throw new HttpInternalServerErrorException($request, "An error occurred: " . $e->getMessage());
}
}

}
34 changes: 34 additions & 0 deletions src/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,45 @@

namespace App\Controllers;

use Model;
use PDOException;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Exception\HttpInternalServerErrorException;
use Psr\Http\Message\ServerRequestInterface as Request;

class HomeController
{
public function response($response, $data, $status = 200)
{
$response->getBody()->write(json_encode($data));
return $response->withHeader('Content-Type', 'application/json')->withStatus($status);
}

public function analytics(Request $request, Response $response)
{
try {
// Fetch total parkings
$totalParkings = Model::factory('Parking')->count();

// Fetch total slots
$totalSlots = Model::factory('Slot')->count();

// Fetch total users with role_id 2
$totalUsers = Model::factory('User')->where('role_id', 2)->count();

// Prepare the data
$data = [
'total_parkings' => $totalParkings,
'total_slots' => $totalSlots,
'total_users' => $totalUsers
];

// Return the response
return $this->response($response, $data);
} catch (PDOException $e) {
throw new HttpInternalServerErrorException($request, "Database error occurred: " . $e->getMessage());
} catch (\Exception $e) {
throw new HttpInternalServerErrorException($request, "An error occurred: " . $e->getMessage());
}
}
}
2 changes: 1 addition & 1 deletion src/Models/BookedSlot.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* @property time $end_time
*/

class Booking extends Model
class BookedSlot extends Model
{
// Table name as a string
public static $_table = 'booked_slot';
Expand Down

0 comments on commit be46f44

Please sign in to comment.