rEEservation
rEEservation is the add-on for ExpressionEngine 2.x that enables you to accept reservations/bookings on your website and handle them easily. In can be used to book hotel rooms, tickets for event etc.
- Installation
- Add-on structure
- Settings
- Email templates
- Control Panel overview
- Booking form
- Check availability of object for a certain date
- Check availability of several objects
- Display available dates in calendar
- List and edit bookings
- PayPal integration
Installation
Unzip the files into your /expressionengine/system/third_party directory. Then go to Add-ons/Modules section in your Control Panel and perform installation.
If you want to be able to send notification to customers when status of their booking changes, you should also enable the rEEservation extension.
If you want to enable your customer instant PayPal payment for the booking made, enable rEEservation PalPal extension and make sure Simple Commerce module is installed and all settings are correct. Fill in the settings for rEEservation PalPal extension as well. If you are using PayPal Sandbox, set var $debug = TRUE
in both mod.simple_commerce.php and ext.reeservation_paypal.php
Add-on structure
The rEEservation add-on for ExpressionEngine consists of module and extension (and also optional extension to enable PayPal payments).
The module is responsible for creation of booking record, checking whether there are places available and displaying the booking details and for managing of reservations.
The extension is responsible for sending email notifications when status of the booking has been changed.
Please put attention that settings for rEEservation module, rEEservation extension and rEEservation PayPal extensions are edited separately.
To make use of module, you should create a channel in EE that will contain entries for objects that can be booked. Name it, for instance, 'Hotel'. Next, create entries in this channel that correspond to booking object. Name them, for instance, 'Room 1', 'Room 2', 'Room 3 Deluxe' etc. The entries can contain any data, you can use them to diplay information on your site's pages.
It is also possible to expand the add-on by creating your own extension. For example, you can integrate payment gateway. Or register member, if he's not registered yet. To do this, make use of following hooks:
- reeservation_booking_status_change (mcp.reeservation.php) - do additional processing when booking status is changed.
Accepted parameters:- booking_id - id of booking
- status - new status of booking (open/pending/closed/rejected)
- send - whether to send notification to user this time (true/false)
- includecomment - include moderator's comment with the notification (true/false)
- reeservation_booking_created_start (mod.reeservation.php) - do something before and booking recording begins. You can bind you CAPTCHA extension to this hook, or modify any POST data.
- reeservation_booking_created_end (mod.reeservation.php) - do additional processing when booking record is created, but no notification sent yet.
Accepted parameters:- booking_id - id of booking
- data - the array of data inserted into database
- reeservation_booking_created_absolute_end (mod.reeservation.php) - do additional processing when booking creation process is completely finished, just before the redirect.
Accepted parameters:- booking_id - id of booking
- data - the array of data inserted into database
Settings
On the settings page in the module's Control Panel you can set various settings. They include:
- Default booking status — status that will be assigned to booking when it is created. Possible values are 'Open/approved', 'Cancelled by user', 'Rejected (by admin)', 'Pending payment / approval'
- Allow multiple bookings — determines whether same object can be reserved by several people for the same date
- Limit of bookings per object — you can set the numbers of bookings you can have for the same entry and date (if multiple bookings allowed)
- Bookings limit field — you can limit the number of booking for same date on per-entry level. The smaller numbers takes precedence.
- Channels — EE channels that contain entries for objects that can be booked
- Booking-enabled entries — each object you want to be booked should be represented by a channel entry. Select all that apply here. OPTIONAL for front-ends bookings, but still required for control panel bookings and higly recommended to select in order to get proper dropdowns in search forms etc.
- Lock pending bookings — if your default booking status is 'pending' you can set a timeout here. This is period of time when no bookings are accepted for the object. It can be used to give user some time to make payment or to give admin time to review the booking. After this time, other people can try reserving this object again (even if you have Allow multiple bookings set to No)
- Use CAPTCHA — allows you to use CAPTCHA check in booking form.
If you are using any CAPTCHA extension, you should make appropriate record for reeservation_booking_created_start hook
- Redirect timeout — time to show success message after booking has been completed. 0 for immediare redirect to landing page
- Notification email — email address to send admin notifications about new bookings. Separate multiple addresses with comma.
- Send admin notification — the notification mentioned above will be sent only if you set this to 'yes'
- Send owner notification — send notification about new booking to object owner (entry author)
- Send customer notification — send notification to customer confirming his request has been accepted
Statuses explained:
- Open / approved - indicates valid booking. No more bookings are possible for the same object & date (unless you have Allow multiple bookings set to Yes)
- Pending - booking request recieved, but not approved yet by admin. No bookings are possible for the same object & date for the period in munites defined by Lock pending bookings settings after booking time (unless you have Allow multiple bookings set to Yes)
- Rejected - the booking has been rejected by administrator
- Cancelled - the booking has been cancelled by customer. The add-on intentionally does not provide a way for customers to cancel their booking due to possible misuse, that should be dome by administrator on request.
Email templates
The add-on is capable to send 4 types of notification: notification to user that his booking request has been received, notification to admin that there has been a new booking made, notification to object owner (entry author) that there has been a new booking made and (if the extension is installed) notification to user if the booking status has been changed.
All notifications are sent only if they are enabled in the settings. Owner notification is sent if the address is not listed as admin address.
Following variables are available in all templates:
- booking_id - booking order ID
- name - customer's name
- email - customer's email
- phone - customer's phone
- places - number of places reserved
- status - booking status
- site_name - site name
- site_url - site URL
- entry_id - entry (booking object) ID
- title - entry (booking object) title
- url_title - entry URL title
- channel_name - booking channel 'techical' name
- channel_title - channel title
- owner_name - name of object owner (entry author)
- owner_username - name of object owner
- owner_email - email of object owner
- permalink - permalink to entry (booking object) using entry_id
- title_permalink - permalink to entry (booking object) using url_title
- date_from format="%Y-%m-%d" - reserved period start. EE date formatting rules apply.
- date_to format="%Y-%m-%d" - reserved period end. EE date formatting rules apply.
Additionally, in admin notification template following variable is available:
- booking_cp_link - link to view booking details in Control Panel
In 'booking edited' template also available are:
- old_status - initial booking status
- status - status of booking after edit has been made
- comment - editor's comment (when included in message)
Control Panel overview
In the module's Control Panel under 'Bookings' tab you can see the full list of booking requests posted.
You can narrow the results by performing a search. The reservations can be filtered by:
- channel
- entry title (booking object name)
- customer name (registered users only)
- customer's email address
- booking status
- object owner
- dates
When you click the link on the object name, you are able to see booking details.
On that page you can change the booking status and also leave a comment.
If you have rEEservation extension installed, you can also choose to notify the user about the edit you made and optionally include the comment with the message.
Since version 2.4.2 you have the ability to create booking from Control Panel on behalf of your customers.
Usage
Available tags are:
- exp:reeservation:form - display booking form
- exp:reeservation:check - check whether the object is booked for the date provided and display booking details
exp:reeservation:form
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/base/jquery-ui.css" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#date_from").datepicker({ dateFormat: "yy-mm-dd" });
$("#date_to").datepicker({ dateFormat: "yy-mm-dd" });
});
</script>
{exp:channel:entries}
<h3>{title}</h3>
{exp:reeservation:form entry_id="{entry_id}"}
{if logged_out}
<p>Name: <input type="text" name="name" /></p>
<p>Email: <input type="text" name="email" /></p>
{/if}
{if logged_in}
<p>Name: {logged_in_screen_name}</p>
<p>Email: {logged_in_email}</p>
{/if}
<p>Phone: <input type="text" name="phone" /></p>
<p>Other contact details: <textarea name="contact"></textarea></p>
<p>Booking dates:<br />
from <input type="text" name="date_from" id="date_from" value="{current_time format="%Y-%m-%d"}" /> to <input type="text" name="date_to" id="date_to" /></p>
<p>Leave a comment to your order: <textarea name="comment"></textarea></p>
{if captcha}
<p>CAPTCHA: <input type="text" name="captcha" /></p>
{captcha}
{/if}
<p><input type="submit" value="Proceed" /></p>
{/exp:reeservation:form}
{/exp:channel:entries}
Parameters:
- entry_id - ID of entry to be booked. Optional, you can use form field instead.
- return - page to redirect after booking has been made. Optional
Variables:
- captcha - display CAPTCHA image
Conditional variables:
- if captcha
- if logged_in
- if logged_out
Form fields:
- entry_id - ID of entry to be booked. Can be set using form entry_id parameter
- places - optionally provide number of places you want to book (only if multiple booking enabled)
- name - customer's name. Required if logged out
- email - customer's email address. Required if logged out
- phone - customer's phone. Optional.
- contact - other contact details customer wants to provide
- comment - customer's comment to be sent together with booking request
- date_from - the start date of booked period. Required
- date_to - the end date of booked period. If omited, the booking will be made for 1 day
You can specify the dates in European or US format. 2011-12-31 and 12/31/11 are both valid. I recommend using jQuery datepicker calendar to set dates easily.
Alternative date fields.
Instead of letting user fill the date in required format, you can ask him to select year, month and day using dropdown selects.
So instead of date_from and date_to you can make use of following fields:
- date_from_day - day of month of booking start day. Required
- date_from_month - booking month (1 to 12). Required
- date_from_year - booking year. If omited, defaults to current year
- date_to_day - day of month of booking end day. If omited, booking will be made for 1 day
- date_to_month
- date_to_year
exp:reeservation:check
Use this tag to check object availability on a certain date.
{exp:reeservation:check entry_id="{segment_2}" day="{current_time format='%d'}" month="{current_time format='%m'}" year="{current_time format='%Y'}"}
{if no_results}
<a href="#booking_form">{day_number}</a>
{/if}
<div style="background: red"><a href="javascript:void(0)" title="{booking_details}Booked on {booking_date format="%Y-%m-%d"}{if booking_admin} by {name}{/if}{/booking_details}">{day_number}</a></div>
{/exp:reeservation:check}
Parameters:
- entry_id - entry ID for object to check booking. Mandatory.
- day - day to check. Mandatory.
- month - month to check. Mandatory.
- year - year to check. Mandatory.
- status - status of booking to display. Optional, default to 'open'. You can separate multuple statuses with a pipe |.
You can, alternatively, perform check for a date range. If at least one date within the range is booked, the contents of tag pair is displayed. Otherwise, the contents of {if no_results} is displayed. To check for a date range, use parameters day_from, month_from, year_from, day_to, month_to, year_to instead of day, month and year.
Conditional variables:
- if captcha
- if logged_in
- if booking_admin - check whether logged in member has access to module control panel
- if no_results - text to display if no boooking exist for the parameter provided
Single variables outside {booking_details} tag pair:
- bookings_limit - number of bookings allowed per object for the same date
- bookings_count - actual number of bookings for selected object and date
- available - number of places available for booking for given date
- entry_id - ID of booked object
- title - title of booked object
- url_title - URL title of booked object
You can display detailed booking info using booking_details tag pair.
Single variables inside {booking_details} tag pair:
- booking_id - ID of booking record
- member_id - member ID of customer (if registered, 0 otherwise)
- owner_id - member ID of object owner
- name - customer's name
- email - customer's email
- phone - customer's phone
- contact - additional contact info provided
- comment - comment left with the reservation
- status - booking status
- moderator_id - ID of member who did last edit of booking
- moderation_comment - comment admin/moderator has left on booking
- date_from format="%Y-%m-%d" - reserved period start. EE date formatting rules apply.
- date_to format="%Y-%m-%d" - reserved period end. EE date formatting rules apply.
- booking_date format="%Y-%m-%d" - date when booking has been submitted. EE date formatting rules apply.
- moderation_date format="%Y-%m-%d" - date when booking was last reviewed by admin. EE date formatting rules apply.
exp:reeservation:check_multiple
Use this tag to check availability of several objects on a certain date.
{exp:reeservation:check_multiple entry_id="{segment_2}" day="{current_time format='%d'}" month="{current_time format='%m'}" year="{current_time format='%Y'}"}
{if no_results}
<a href="#booking_form">{day_number}</a>
{/if}
{entries}
<p>{title} has {bookings_count} places booked ({available} available)</p>
{/entries}
{/exp:reeservation:check_multiple}
Parameters:
- entry_id - entry ID for object to check booking. You can specify multiple entry IDs by separating them with a pipe (ex. entry_id="2|12|82").
- day - day to check. Mandatory.
- month - month to check. Mandatory.
- year - year to check. Mandatory.
- status - status of booking to display. Optional, default to 'open'. You can separate multuple statuses with a pipe |.
You can, alternatively, perform check for a date range. If at least one date within the range is booked, the contents of tag pair is displayed. Otherwise, the contents of {if no_results} is displayed. To check for a date range, use parameters day_from, month_from, year_from, day_to, month_to, year_to instead of day, month and year.
Conditional variables:
- if captcha
- if logged_in
- if booking_admin - check whether logged in member has access to module control panel
- if no_results - text to display if no boooking exist for the parameter provided
You can display availability info on each object using entries tag pair.
Single variables inside {entries} tag pair:
- bookings_limit - number of bookings allowed per object for the same date
- bookings_count - actual number of bookings for selected object and date
- available - number of places available for booking for given date
- entry_id - ID of booked object
- title - title of booked object
- url_title - URL title of booked object
Outside of {entries} tag pair you have:
- total_booked - total number of bookings for all searched objects for given date(s)
- total_available - total number of places available for booking in all searched objects for given date
Simple calendar
Here's an example how to buld booking/availability using Simple Calendar plugin which is bundled with rEEservation.
{exp:simple_calendar entry_id="{segment_2}" start_day="sunday" month="{current_time format='%n'}" year="{current_time format='%Y'}"}
<h4>{current_time format="%F %Y"}</h4>
<table class="calendar" border="0" cellpadding="6" cellspacing="1" width="300px">
<tr>
{calendar_heading}
<th title="{lang:weekday_long}">{lang:weekday_abrev}</th>
{/calendar_heading}
</tr>
{calendar_rows}
{row_start}<tr>{/row_start}
<td{if today} class="today"{/if}>
{reeservation_check}
{if no_results}
{day_number}
{/if}
<a style="color: red" href="javascript:void(0)"
title="{booking_details}Booked on {booking_date format="%Y-%m-%d"}{if booking_admin} by {name}{/if}{/booking_details}">{day_number}</a>
{/reeservation_check}
</td>
{if empty}<td> </td>{/if}
{row_end}</tr>{/row_end}
{/calendar_rows}
</table>
{/exp:simple_calendar}
{reeservation_check} tag pair is basically calling exp:reeservation:check function, so all its variables and conditionals are available.
List and edit bookings
You can list all bookings that match certain parameter, such as entry author or customer using {exp:reeservation:listing} tag.
Accepted parameters are:
- entry_id - entry ID for object
- owner_id - ID of entry author/object owner
- member_id - customer ID
- booking_id - you can limit your display to just particular boking. You can also display form to edit it for object owner (see below)
- status - status of booking to display. Optional, default to 'open'. You can separate multuple statuses with a pipe |.
Ouput variables:
- booking_id - ID of booking record
- entry_id - ID of booked object
- title - title of booked object
- url_title - URL title of booked object
- member_id - member ID of customer (if registered, 0 otherwise)
- owner_id - member ID of object owner
- name - customer's name
- email - customer's email
- phone - customer's phone
- contact - additional contact info provided
- comment - comment left with the reservation
- status - booking status
- moderator_id - ID of member who did last edit of booking
- moderation_comment - comment admin/moderator has left on booking
- date_from format="%Y-%m-%d" - reserved period start. EE date formatting rules apply.
- date_to format="%Y-%m-%d" - reserved period end. EE date formatting rules apply.
- booking_date format="%Y-%m-%d" - date when booking has been submitted. EE date formatting rules apply.
- moderation_date format="%Y-%m-%d" - date when booking was last reviewed by admin. EE date formatting rules apply.
{exp:reeservation:listing owner_id="{segment_2}"}
<p><a href="{path=bookings/edit/{booking_id}}">{title}, booked from {date_from format="%Y-%m-%d"} to {date_to format="%Y-%m-%d"}</a></p>
{/exp:reeservation:listing}
To display booking edit form, place a call to exp:reeservation:listing with 2 parameters form="true" and booking_id.
The editing is available only for owner of booked object (and admins of course).
Following fields can be used in the form:
Parameters:
- status - desired booking status. Possible values: 'open', 'pending', 'rejected', 'cancelled' (all lowercase)
- moderator_comment - optional comment
- notify_user - set to 'y' to notify customer about status change
- include_comment - set to 'y' to include comment with notification email
- return - page to redirect after editing has been made
PayPal integration
Simple Commerce module is required for this feature to work, however nothing will be recorded in Simple Commerce module, so you don't need to define any items in there - just PayPal settings
You can enable your customers to pay for the bookings made instantly using PayPal. To do this, you'll need to have Simple Commerce module set up and rEEservation PayPal extension installed and set up.
Install the rEEservation PayPal extension, go to it's settings and make sure all fields are filled in. Price field should contain the cost of 1-day reservation. The total will be calculated based on the field value and number of days.
If you have several channels for booking, consider using Drifter extension for price field.
If you are using PayPal Sandbox, set var $debug = TRUE
in both mod.simple_commerce.php and ext.reeservation_paypal.php
Make sure your default booking status is 'Pending'.
Now after the booking request has been received, the users will be instantly redirected to PayPal page. After they complete the payment, status of their order is set to Open/approved and notification email is sent. The user will be redirected to page you specify in extension settings or in 'return' parameter of booking form.
If you want to send notifications to customer/property owner/admin address, you should enable that in settings of 'rEEservation' extension.