Validating reservations

Hi, this is my first time asking a question here. I’m still new on Yii and went straight to version 2 instead. The community is very helpful and I got all my questions answered just by searching around, but I got stuck on this particular case about validating a reservation to avoid double bookings.

Here’s my reservation model:


class Trreservation extends \yii\db\ActiveRecord

{

    public static function tableName()

    {

        return 'trreservation';

    }


    public function rules()

    {

        return [

            [['Date'], 'date', 'format' => 'php:Y-m-d H:i'],

            [['RoomID', 'PatientID', 'DoctorID'], 'integer'],

        ];

    }


    public function attributeLabels()

    {

        return [

            'ReservationID' => 'Reservation ID',

            'Date' => 'Date & Time',

            'RoomID' => 'Room Name',

            'PatientID' => 'Patient Name',

            'DoctorID' => 'Doctor Name',

        ];

    }


    public function getRoom()

    {

        return $this->hasOne(Msroom::className(), ['RoomID' => 'RoomID']);

    }


    public function getPatient()

    {

        return $this->hasOne(Mspatient::className(), ['PatientID' => 'PatientID']);

    }


    public function getDoctor()

    {

        return $this->hasOne(Msdoctor::className(), ['DoctorID' => 'DoctorID']);

    }


}

Basically I want to add a rule to avoid double bookings, by giving an error if the inputted form has a match with a record that has an exact date-time-RoomID (or date-time-DoctorID). I have no idea how to create the validation for this case.

Besides using the core validators included in the Yii releases, you may also create your own validators. Example:




public function rules()

{

    return [

        [['Date'], 'date', 'format' => 'php:Y-m-d H:i'],

        [['RoomID', 'PatientID', 'DoctorID'], 'integer'],

        [['Date', 'RoomID'], 'validateDoubleBooking'],

    ];

}


function validateDoubleBooking($attribute, $params)

{

    ...

}



Ref:inline-validators

It works! Thank you for mentioning that part of the documentation. I wrote this inside the function


    public function rules()

    {

        return [

            [['Date'], 'date', 'format' => 'php:Y-m-d H:i'],

            [['RoomID', 'PatientID', 'DoctorID'], 'integer'],

            [['Date', 'RoomID'], 'validateDoubleRoom'],

        ];

    }


    public function validateDoubleRoom($attribute, $params)

    {

        $validatequery = Trreservation::findOne(['Date' => $this->Date, 'RoomID' => $this->RoomID]);

        if($validatequery)

        {

            $this->addError($attribute, 'There is a double booking at this time in this particular room');

        }

    }

Thanks again :lol:

Dear Adam!

As you can see, if your action is "Create", function validateDoubleRoom() is work fine.

But, if your action is "Update" and Date, RoomID is not changed, this function is wrong because you will find itself.

Here is my solution:




public function validateDoubleRoom($attribute, $params)

    {

        $validatequery = Trreservation::findOne(['Date' => $this->Date, 'RoomID' => $this->RoomID]);

        if($validatequery && ($validatequery->ReservationID != $this->ReservationID))

        {

            $this->addError($attribute, 'There is a double booking at this time in this particular room');

        }

    }

Thank you for pointing it out, I overlooked the update part of the validation. However when I tried to failproof the update without changing the code, it worked fine. Even if I put your suggested line of code, it still worked fine(I wonder). I will note your suggestion though since it seems logical to do it that way. Thanks