This topic is locked

Hotel reservation management

11/12/2020 1:51:57 PM
PHPRunner Tips and Tricks
fhumanes author


I have received inquiries about how to resolve the management of room reservations in a hotel or awnings on a beach.
In general, this problem of managing reservations (daily and not by the hour) of an item (room, car, motorcycle, boat, home, etc.) is very common, so I have developed this example (and not an application) to that can help you develop a system that has this problem.
Functional requirements
I have envisioned the example to address the following functional requirements.

  • There is an inventory of products (in this case rooms) to reserve. This inventory integrates the characteristics of the rooms.
  • In the Database, the dates on which the rooms are reserved are stored.
  • Associated with the reservation, it relates, in addition to the room and the dates, the Client's data.
  • A calendar must be provided where all reservations are reflected.
  • To search for the availability of a room or to make a new reservation, there will be a form that describes the characteristics of the room you are looking for and the dates you want. The system will indicate the available rooms according to the criteria and a calendar of the occupancies of these rooms, in order that the reservations are adjusted and no gaps are left without the rooms being reserved (optimization of resources).
  • The system is designed to be used by Hotel personnel, although it has possibilities to extend the example and enable it for the general public.


Solution
DEMO: https://fhumanes.com/hotel
User and password: admin /admin
The data model is very simple


The example is developed in PHPRunner 10.2, so that more users can use it (not all have version 10.4). Use the Color and DateRange plugins that you can download from plugins.
It uses the Fullcalendar JavaScript library that we have already used on other occasions and which is very good, but in this case we have used the “Timeline” functionality.
Step to describe the functionality of the example


Appearance of the general menu with the management options of the most important aspects.


Information of the rooms, with your most relevant data. A color has been used, which globally describes the characteristics of the room.


Information panel on the occupancy and availability of the rooms. It can be seen that there is a grouping of rooms to be displayed on the calendar and that it can be navigated by months, being able to show the reservations by month or by year.
By clicking on the reservation, you will see all the data and be able to modify it.


At the development level, this is the screen with the most coding and news.
A screen is created without an exact mirror table behind it and the "SELECT" is dynamically constructed to fit the search criteria.


As a result of the search, it shows the rooms that meet the criteria so that the one you want is selected and it also shows their calendar, to optimize the spaces.
You have to “click” on the “pencil” icon to confirm the reservation.


Once you have clicked on the "pencil" you get the reservation data screen to complete with the Customer information and confirm the reservation.
I briefly explain some codes, so you can see the simplicity of the example.
timeline.php.- To show the calendar grid.





<?php

global $conn;

$language = $hours_a_day = $_SESSION['config'][array_search('CALENDAR_LANGUAGE', array_column($_SESSION['config'], 'name'))]['value'];

$firstDay = $hours_a_day = $_SESSION['config'][array_search('CALENDAR_FIRST_DAY', array_column($_SESSION['config'], 'name'))]['value']; // 1 = Lunes, 0=Domingo

$now = substr(now(),0,10);

if (isset($_SESSION['q_fromDate'])) { $now = substr($_SESSION['q_fromDate'],0,10); }

$str1 = <<<EOD

<style>

html, body {

margin: 0;

padding: 0;

font-family: Arial, Helvetica Neue, Helvetica, sans-serif;

font-size: 12px;

}

#calendar {

max-width: 900px;

max-height: 400px;

margin: 40px auto;

}

</style>

<link href='fullcalendar/packages/core/main.css' rel='stylesheet' />

<link href='fullcalendar/packages-premium/timeline/main.css' rel='stylesheet' />

<link href='fullcalendar/packages-premium/resource-timeline/main.css' rel='stylesheet' />

<script src='fullcalendar/packages/core/main.js'></script>

<script src='fullcalendar/packages/interaction/main.js'></script>

<script src='fullcalendar/packages-premium/timeline/main.js'></script>

<script src='fullcalendar/packages-premium/resource-common/main.js'></script>

<script src='fullcalendar/packages-premium/resource-timeline/main.js'></script>

<script src='fullcalendar/packages/core/locales-all.js'></script>

<script src='fullcalendar/tooltip/tooltip.min.js'></script>

<script>

var initialLocaleCode = '$language';

var firstDay = '$firstDay';



document.addEventListener('DOMContentLoaded', function() {

var calendarEl = document.getElementById('calendar');

var calendar = new FullCalendar.Calendar(calendarEl, {

plugins: [ 'interaction', 'resourceTimeline' ],

now: '$now',



// timeZone: 'UTC+1', // the default 'local' (unnecessary to specify)

locale: initialLocaleCode,



editable: false,

aspectRatio: 1.8,

scrollTime: '00:00',

header: {

left: 'today prev,next',

center: 'title',

right: 'resourceTimelineMonth,resourceTimelineYear'

},

defaultView: 'resourceTimelineMonth',

navLinks: true,

resourceAreaWidth: '25%',

resourceLabelText: 'Rooms',

//

eventClick: function(info) {

var booking = info.event.id;

var title = info.event.title;

var url = "bookings_view.php?editid1="+booking;

var header = '<h2 data-itemtype="view_header" data-itemid="view_header" data-pageid="10">'+'Booking: '+ title+'</h2>' ;

window.popup = Runner.displayPopup({

url: url,

width: 800,

height: 500,

header: header

});

},

//

resourceLabelText: 'Rooms',

resources: { // you can also specify a plain string like 'json/resources.json'

url: 'timeline_ajax_resource.php'},

events: { // you can also specify a plain string like 'json/events-for-resources.json'

url: 'timeline_ajax_event.php'},

});

calendar.render();

});

</script>

<div id='calendar'></div>

EOD;

echo $str1;

?>


timeline_ajax_resource.php .- To facilitate the inventory of rooms. When it is in the search phase, only the relation of the rooms resulting from the query is delivered.





<?php

require_once("include/dbcommon.php"); // DataBase PHPRunner

// Require our Event class and datetime utilities

require 'fullcalendar/php/utils.php';

$language = $_SESSION['language'];

$search = '';

If ( isset($_SESSION['q_IN']) && $_SESSION['q_IN'] <> '' ) { // Are you coming from Room Search?

$search = ' and rooms.idrooms IN ('.$_SESSION['q_IN'].') ';

}

$sql = "

SELECT idrooms, code, color, catalog_code

FROM rooms

join (

SELECT catalog_num, catalog_code

FROM catalog

join super_catalog on ( super_catalog_idsuper_catalog = idsuper_catalog

AND super_code = 'TYPE_ROOM')

where language = '$language'

) T2

where catalog_num = type $search

order by catalog_code, code

";

$resql = db_query($sql,$conn);

// Accumulate an output array of event data arrays.

// $output_arrays = array();

$str = '[';

$group = '';

while ($data = db_fetch_array($resql)){



If ($group <> $data['catalog_code']) {

if ($group <> '' ) {

$str = substr($str,0,strlen($str)-1); // erase last ","

$str .= ' ] },';

}

$str .= '{ "id": "'.$data['catalog_code'].'", "title": "'.$data['catalog_code'].'", "children": [';

$group = $data['catalog_code'];



}

$str .= '{ "id": "'.$data['code'].'", "title": "'.$data['code'].'", "eventColor": "'.$data['color'].'" },';



}

$str = substr($str,0,strlen($str)-1); // erase last ","

$str .= ' ] } ]';

echo $str;

// Send JSON to the client.

// $str = json_encode($output_arrays);

// echo json_encode($output_arrays);

?>


timeline_ajax_event.php. Provide the calendar grid with reservations for the period and, if it is the search period, of the rooms that have left according to the criteria provided.





<?php

require_once("include/dbcommon.php"); // DataBase PHPRunner

// Require our Event class and datetime utilities

require 'fullcalendar/php/utils.php';

// Short-circuit if the client did not give us a date range.

if (!isset($_GET['start']) || !isset($_GET['end'])) {

die("Please provide a date range.");

}

// Parse the start/end parameters.

// These are assumed to be ISO8601 strings with no time nor timeZone, like "2013-12-29".

// Since no timeZone will be present, they will parsed as UTC.

$range_start = parseDateTime($_GET['start']);

$range_end = parseDateTime($_GET['end']);

// Parse the timeZone parameter if it is present.

$time_zone ='UTC';

if (isset($_GET['timeZone'])) {

// $time_zone = new DateTimeZone($_GET['timeZone']);

}

$start = substr($_GET['start'],0,10).' 00:00:00';

$end = substr($_GET['end'] ,0,10).' 00:00:00';

$now = date('Y-m-d H:i:s', strtotime(now(). ' +2 hour')); // now() + 1

if ( $start < $now ) { // Minimum date of the moment

// $start = $now;

}

$language = $_SESSION['language'];

$search = '';

If ( isset($_SESSION['q_IN']) && $_SESSION['q_IN'] <> '' ) { // Are you coming from Room Search?

$search = ' and bookings.rooms_idrooms IN ('.$_SESSION['q_IN'].') ';

}

$sql = "

SELECT idbookings, rooms_idrooms, fromDate, toDate, name, phone, code

FROM bookings

join client on (client_idclient = idclient )

join rooms on (rooms_idrooms = idrooms )

where toDate >= '$start' and fromDate <= '$end' $search;

";

$resql = db_query($sql,$conn);

// Accumulate an output array of event data arrays.

$output_arrays = array();

while ($data = db_fetch_array($resql)){

$output_arrays[] = array(

'id'=>$data['idbookings'],

'title'=>$data['name'],

'resourceId'=>$data['code'],

'start'=>$data['fromDate'],

'end'=>date('Y-m-d', strtotime($data['toDate']. ' +1 day')),

'description'=>$data['phone']);

}

// Send JSON to the client.

// $str = json_encode($output_arrays);

echo json_encode($output_arrays);

?>


As always, you can contact me for any need at [email="fernandohumanes@gmail.com"]fernandohumanes@gmail.com[/email]
Also, as usual, I leave you in my portal all the files you need so that you can install the example on your computers.