简体   繁体   中英

Loop through each object and return it's availability (Laravel)

I have an app where users can rent cars. The cars are already in the database put by me.

$table->string('name')->nullable();
$table->string('color')->nullable();
$table->string('model')->nullable();

Since it's a rental I have a reservation table

$table->increments('id');
$table->dateTime('from_date')->nullable();
$table->dateTime('to_date')->nullable();

I already created a function where users request a car and the function will loop and find same requted car.

And car_user to link the reserved car with the user.

$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');

$table->integer('car_id')->unsigned();
$table->foreign('car_id')->references('id')->on('cars');

Now when I try to save the date and time for the specifically requested car (A).I have to make sure that:

  1. Same car(A) can't be reserved again in the same time.
  2. All the cars are available in the same time car (A) is reserved.

So I first came up with this function

public function isSlotAvailable(Request $request) {
    $appointments = Reservation::all();
    $from =  Carbon::parse( $request->from);
    $to =  Carbon::parse( $request->to);

    foreach ($appointments as $appointment) {
        $eventStart = Carbon::instance(
            new DateTime($appointment['dt_start'])
        );

        $eventEnd = Carbon::instance(
            new DateTime($appointment['dt_end'])
        )->subSecond(1);

        if ($from->between($eventStart, $eventEnd) || 
            $to->between($eventStart, $eventEnd)   || 
            ($eventStart->between($from, $to) && $eventEnd->between($from, $to))) {
            return false;
        }
    }

    return true;
}

This function will check if there is availability in the Reservation table. But it's wrong because it treats the cars as a single car. For example, if I have 5 cars available in the database and a user reserves a car from 2017-01-05 05:00:00 to 2017-01-10 09:00:00 . All the cars will be reserved in the same time because the loop does not go through each car like $car->allreservation .

Question

how can I loop in each car and check if the new requested date overlaps? and if it overlaps it will go to the second car and check and if not then it will link it to the user.

Really appreciate your help

UPDATE

This is how I save the new requested car

 $id = $new_car->id;
 $Reservation_id = $time->id;
 $user->cars()->attach($id, ['type' => 'requested']);
 $user->reservations()->attach(Reservation_id);

make sure that you are using DATETIME datatype in database table not using TIMESTAMP CURRENT_TIME_STAMP.

If you are using current time stamp then change it to DATETIME and save the form date field value in loop. I hope it will work!

As it seems to me what you need is a better database design.

As it seems you have same car with different quantities (is that? If not please comment Or is this car id is something like real car id? => it is unique)

If so what you need is a proper way to handle the database. In this case you have to implement a one to many relationship(Same id car having multiple instances). If this is the case you might need to add another field to the car; something like car quantity. Then you can check the reserved cars against the total quantity. Then if the number of reserved cars are less than what you have it can be reserved.

If it is other way around( each car having unique id - no repeating number of cars with same id); then when you check whether slot is available for the car, get all the reservations for that car and check whether it is having the same (or between) reservation. If this is not what you are looking for please comment.

Edit

You may need to consider some about Database normalization. Go through the tutorial here at tutorials-point

  1. First add the car id to the reservation table.
  2. Add User Id to the reservation table.
  3. Then you can get the reservations for that car as described below.
  4. Check whether your reservation is in the retrieved reservations.

In laravel you can write select queries like

$reservations= DB::table('reservations')->where('car_id', '=', 100)->get()  // if car_id = 100

To read more about laravel database queries refer the Documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM