diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 556a339..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/booking.helper.inc b/booking.helper.inc index 321cfb5..b77c811 100644 --- a/booking.helper.inc +++ b/booking.helper.inc @@ -853,28 +853,18 @@ function _booking_deposit_amount($person, $include_fees = TRUE) array(':eventid' => $event->eid)) ->fetchObject(); - if ($deposit) - { + if ($deposit) { //if we're using paypal, add the transaction fee - if (variable_get('booking_use_paypal', 0) == 1 && $include_fees == TRUE) - { + if (variable_get('booking_use_paypal', 0) == 1 && $include_fees == TRUE) { $amount_owing = _booking_add_paypal_fees($deposit->booking_price, $person->booking_country); - /* - //add the 30 cent fixed cost - $amount_owing = $deposit->booking_price + 0.3; - //and the 2.4 percent transaction fee - $amount_owing = $amount_owing / (1 - 0.026); - */ } - else - { + else { $amount_owing = $deposit->booking_price; } //return the calculated amount rounded to two decimal places return number_format($amount_owing, 2, '.', ''); } - else - { + else { //there is no deposit amount return 0; } diff --git a/booking.module b/booking.module index 32620e3..df0255b 100644 --- a/booking.module +++ b/booking.module @@ -61,8 +61,8 @@ module_load_include('inc', 'booking', 'booking.studygroup_leaders'); module_load_include('inc', 'booking', 'booking.travel'); // Load the include for managing room bookings and definitions module_load_include('inc', 'booking', 'booking.rooms'); -//still some functions in this file -module_load_include('inc', 'booking', 'booking.rooms_old'); +// load the include for mass-allocating people to rooms +module_load_include('inc', 'booking', 'booking.rooms_allocate'); // Load the include for room layout definitions module_load_include('inc', 'booking', 'booking.rooms_admin'); @@ -597,7 +597,7 @@ function booking_menu() { 'title' => 'Assign Attendees to Rooms', 'description' => 'Assign attendees to rooms via autocomplete fields', 'page callback' => 'drupal_get_form', - 'page arguments' => array('booking_rooms_allocate_test_form', 3), + 'page arguments' => array('booking_rooms_allocate_form', 3), 'access arguments' => array('edit room allocations'), //'type' => MENU_NORMAL_ITEM, ); diff --git a/booking.rooms.inc b/booking.rooms.inc index 45f9efe..63788d9 100644 --- a/booking.rooms.inc +++ b/booking.rooms.inc @@ -1,108 +1,455 @@ fields('p', array('nid', 'booking_firstname', 'booking_lastname')); - $db_or = db_or()->condition('p.booking_lastname', '%' . db_like($string) . '%', 'LIKE')->condition('p.booking_firstname', '%' . db_like($string) . '%', 'LIKE'); - $db_and = db_and()->condition($db_or)->condition('p.booking_eventid', $event->eid, '='); - $result = $query->condition($db_and) - ->execute(); +/** + * Function for viewing a summary of who belongs to which study group + */ +function booking_roomallocations_view_summary() { + global $event; + $rows = array(); + + $header = array( + 'booking_firstname' => array('data' => t('First Name'), 'field' => 'p.booking_firstname'), + 'booking_lastname' => array('data' => t('Last Name'), 'field' => 'p.booking_lastname', 'sort' => 'asc'), + 'booking_gender' => array('data' => t('Gender'), 'field' => 'p.booking_gender'), + 'booking_age' => array('data' => t('Age'), 'field' => 'p.booking_dob'), + 'booking_married' => array('data' => t('Married?'), 'field' => 'p.booking_married'), + 'booking_room_request' => array('data' => t('Requested Roommates'), 'field' => 'p.booking_room_mate1'), + 'booking_roomlocation' => array('data' => t('Room Location'), 'field' => 'r.booking_room_location_id'), + 'booking_room_num' => array('data' => t('Room Number'), 'field' => 'r.booking_room_number'), + 'booking_room_bedtype' => array('data' => t('Bed Type'), 'field' => 'm.booking_room_bedtype'), + 'booking_room_edit' => array('data' => t('Edit')), + ); - // save the query to matches - foreach ($result as $row) { - $name = $row->booking_lastname . ', ' . $row->booking_firstname . ' [' . $row->nid . ']'; - $matches[$name] = $name; - } + $query = db_select('booking_person', 'p'); + $query->leftJoin('booking_room_mapping', 'm', 'm.booking_nodeid = p.nid'); + $query->leftJoin('booking_room_definition', 'r', 'r.rid = m.booking_roomid'); + $query->leftJoin('booking_room_locations', 'l', 'l.lid = r.booking_room_location_id'); + $db_and = db_and(); + $db_and->condition('p.booking_eventid', $event->eid, '='); + $db_and->condition('p.booking_status', 1, '='); + $query->condition($db_and); + $query->fields('p')->fields('m')->fields('r')->fields('l'); + $table_sort = $query->extend('TableSort')->orderbyHeader($header); + $result = $table_sort->execute(); + + foreach($result as $data) { + $location_link = $data->booking_roomlocation_descrip . l( + t(' (Edit)'), + t('admin/booking/rooms/!id/assign', array('!id' => $data->booking_room_location_id)), + array('query' => drupal_get_destination()) + ); + + $rows[] = array( + 'data' => array( + $data->booking_firstname, + $data->booking_lastname, + $data->booking_gender == 'M' ? 'Male' : 'Female', + _booking_get_age_years($data->booking_dob), + $data->booking_married == 'Y' ? 'Yes' : 'No', + $data->booking_room_mate1, + $data->booking_room_location_id > 0 ? $location_link : '', + $data->booking_room_number, + _booking_room_bedtype_lookup($data->booking_room_bedtype), + l( t('Change Room'), t('admin/booking/!id/edit-room', array('!id' => $data->nid)), array('query' => drupal_get_destination()) ), + ), + ); + } - // Return the result to the form in json - drupal_json_output($matches); + $prefix = t("
Enter part of a person's name in the text field and wait for the blue spinning circle to autocomplete with the person's details. Make sure you click on the person from the dropdown list that appears.
"; - $form['first_para'] = array ( - '#type' => 'markup', - '#markup' => $prefix, - ); - - //verify that $location_id is a number - if (! preg_match('/^[0-9]+$/', $location_id)) { - drupal_set_message("Error: Invalid room location ID '" . $location_id . "' supplied. Unable to allocate rooms.", 'error', FALSE); + $form = array(); + $room_options = array(); + $location_options = array(); + $location_options[] = "--"; + + //verify that $nid is a number + if (! preg_match('/^[0-9]+$/', $nid)) { + drupal_set_message("Error: Invalid registration ID '" . $nid . "' supplied. Unable to edit room allocation.", 'error', FALSE); drupal_goto('admin/booking/rooms'); return ""; - } - - //query for existing room allocations - $query = db_select('booking_person', 'p'); - $query->leftJoin('booking_room_mapping', 'm', 'm.booking_nodeid = p.nid'); - $query->condition('p.booking_eventid', $event->eid, '='); - $query->fields('p', array('booking_lastname', 'booking_firstname'))->fields('m'); - $room_mapping = $query->execute()->fetchAllAssoc('booking_nodeid'); - - //query for room definitions - $room_query = db_query("SELECT r.*, l.* FROM {booking_room_definition} r " . - "INNER JOIN {booking_room_locations} l on r.booking_room_location_id = l.lid " . - "WHERE booking_room_location_id = :lid " . - "ORDER BY CAST(booking_room_number as SIGNED INTEGER) ASC", - array(':lid' => $location_id)); + } + + //check that this person exists + $check_query = db_query("SELECT nid " . + "FROM {booking_person} " . + "WHERE nid = :nid", + array(':nid' => $nid)) + ->fetchObject(); + + //throw an error if they don't exist + if (! $check_query) + { + drupal_set_message("Error: Unable to find booking corresponding with registration ID '" . $nid . "'.", 'error', FALSE); + drupal_goto('admin/booking/rooms'); + return ""; + } + + //person must exist in database, load the user object + $person = node_load($nid); + + //load the room locations + $locations_query = db_query("SELECT * FROM {booking_room_locations} where booking_roomlocation_active='Y'"); + foreach($locations_query as $row) { + $location_options[$row->lid] = $row->booking_roomlocation_descrip; + } - //define the table header + $prefix = t("Manually assign/update room allocation for !first !last.
Room Edit selected room location:\n@info", array('@info' => print_r( $selected_room_location, true))); + + $selected_room_num = isset($form_state['values']['booking_room_number']) ? + $form_state['values']['booking_room_number'] : $person->booking_room_number; + //watchdog('booking', "
Room Edit selected room number:\n@info", array('@info' => print_r( $selected_room_num, true))); + + $form['booking_room_location_id'] = array( + '#type' => 'select', + '#title' => t('Room Location'), + '#options' => $location_options, + '#default_value' => $person->booking_room_location_id, + '#ajax' => array( + 'event' => 'change', + 'wrapper' => 'booking_roomnum_wrapper', + 'callback' => 'booking_roomnum_ajax_callback', + ), + ); + + $form['booking_room_number'] = array( + '#type' => 'select', + '#title' => t('Room Number'), + //'#description' => t(''), + '#prefix' => '
Room Edit ajax callback:\n@info", array('@info' => print_r( $form, true))); + return $form['form']['booking_room_number']; +} + +/** + * Function to return the updated form element booking_room_bedtype for booking_room_edit_form() + */ +function booking_bedtype_ajax_callback($form, $form_state) { + //watchdog('booking', "
Room Edit ajax callback:\n@info", array('@info' => print_r( $form, true))); + return $form['form']['booking_room_bedtype']; +} + +/** + * Function to calculate appropriate range of room numbers for ajax enabled form booking_room_edit_form() + * @param $location_id - the room location id to look at + * @return array containing the room numbers for this location + */ +function _booking_get_roomedit_roomnum_options($selected) { + $room_options = array(); + $room_options[] = "--"; + + $room_query = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid", + array(':lid' => $selected)); + + foreach($room_query as $room) + { + $room_options[$room->booking_room_number] = $room->booking_room_number; + } + //watchdog('booking', "
Room Number Options:\n@info", array('@info' => print_r( $room_options, true))); + + return $room_options; +} + +/** + * Function to calculate appropriate bed options for ajax enabled form booking_room_edit_form() + * @param $location_id - the room location id to look at + * @param $room_num - the room number to get the bed details from + * @return array containing the bed options for this specific room + */ +function _booking_get_roomedit_bedtype_options($location_id, $room_num) { + $bed_options = array(); + $bed_options[] = "--"; + + $details = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid AND booking_room_number = :num", + array(':lid' => $location_id, ':num' => $room_num))->fetchObject(); + + //check we got a response from the query + if ($details) + { + //go through the bed options + if ($details->booking_room_singlebeds > 0) + { + $bed_options[1] = "Single"; + } + if ($details->booking_room_doublebeds > 0) + { + $bed_options[2] = "Double"; + } + if ($details->booking_room_queenbeds > 0) + { + $bed_options[3] = "Queen"; + } + } + + //watchdog('booking', "
Room Number Options:\n@info", array('@info' => print_r( $bed_options, true))); + + return $bed_options; +} + +/** + * Validate the submission to update allocated room and bed for a person + */ +function booking_room_edit_form_validate($form, &$form_state) { + //TODO: turn this into a generalised helper function, and use it for validating booking_rooms_allocate_form() also + + global $event; + $values = $form_state['input']; + + //watchdog('booking', "
Room Number Form State:\n@info", array('@info' => print_r( $form_state['values'], true))); + + //no need to validate if we're just removing the mapping + //op won't be defined in the form if it's just receiving the ajax callback, so check that is defined first + if (isset($form_state['values']['op']) && $form_state['values']['op'] == 'Remove') + { + return; + } + else + { + if (!isset($values['booking_room_location_id']) || !isset($values['booking_room_number']) || !isset($values['booking_room_bedtype'])) + { + form_set_error('form', + t('Invalid configuration detected. Please ensure a room location, room number and bed type are all set.') + ); + return; + } + + //get the specific room definition from the database + $details = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid AND booking_room_number = :num", + array(':lid' => $values['booking_room_location_id'], ':num' => $values['booking_room_number']))->fetchObject(); + + //perform a check to see if this person is already allocated to this bed + $check = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid AND booking_nodeid = :nid", + array(':eid' => $event->eid, ':nid' => $values['personid']))->fetchObject(); + + if ($check && ($check->booking_roomid == $details->rid && $check->booking_room_bedtype == $values['booking_room_bedtype'])) + { + //drupal_set_message('Not validating room capacity because this person is already allocated this bed in this room.'); + } + //there was no existing mapping for this person, so check that there's capacity in this room + elseif (! _booking_room_capacity_check($details->rid, $values['booking_room_bedtype'], $details)) + { + form_set_error('booking_room_number', + t('Unfortunately there are no beds available of the type specified in the room.') + ); + } + } +} + +/** + * Process the submission to update allocated room and bed for a person + */ +function booking_room_edit_form_submit($form, &$form_state) { + global $event; + $values = $form_state['input']; + $redirect_path = "admin/config/booking/rooms"; + + //check if we should remove the room allocation + if ($form_state['values']['op'] == 'Remove') + { + $message = t("Removing id !nid from room number !number in location !location", + array('!nid' => $values['personid'], '!location' => $values['booking_room_location_id'], + '!number' => $values['booking_room_number']) + ); + watchdog('booking', $message); + drupal_set_message($message, 'status', FALSE); + + db_delete('booking_room_mapping') + ->condition('booking_eventid', $event->eid) + ->condition('booking_nodeid', $values['personid']) + ->execute(); + + + //return; + } + //otherwise, continue with adding/updating the room allocation + else + { + $details = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid AND booking_room_number = :num", + array(':lid' => $values['booking_room_location_id'], ':num' => $values['booking_room_number']))->fetchObject(); + + $check = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid AND booking_nodeid = :nid", + array(':eid' => $event->eid, ':nid' => $values['personid']))->fetchObject(); + + //this person already exists in mapping table + if ($check) + { + $message = t("Updating person id !nid to room id !id with bed type !type.", + array('!nid' => $values['personid'], '!id' => $details->rid, '!type' => _booking_room_bedtype_lookup($values['booking_room_bedtype']), + '!number' => $values['booking_room_number']) + ); + + //there is an existing mapping to update + $result = db_update('booking_room_mapping') + ->fields(array( + 'booking_roomid' => $details->rid, + 'booking_room_bedtype' => $values['booking_room_bedtype'], + )) + ->condition('mid', $check->mid) + //->condition('booking_eventid', $event->eid) + //->condition('booking_nodeid', $values['personid']) + ->execute(); + + } + //create a new record in the mapping table + else + { + $message = t("Allocating person id !nid to room id !id with bed type !type.", + array('!nid' => $values['personid'], '!id' => $details->rid, '!type' => _booking_room_bedtype_lookup($values['booking_room_bedtype']), + '!number' => $values['booking_room_number']) + ); + + //create a new room mapping for this person + $result = db_insert('booking_room_mapping') + ->fields(array( + 'booking_roomid' => $details->rid, + 'booking_eventid' => $event->eid, + 'booking_nodeid' => $values['personid'], + 'booking_room_bedtype' => $values['booking_room_bedtype'], + )) + ->execute(); + + } + watchdog('booking', $message); + drupal_set_message($message, 'status', FALSE); + + } //end operation check + + $form_state['redirect'] = $redirect_path; +} + +/** + * Function for generating report of room allocations in a specific location + */ +function booking_rooms_view_form($node, &$form_state, $location_id) { + global $event; + $rows = array(); + $form = array(); + + //verify that $location_id is a number + if (! preg_match('/^[0-9]+$/', $location_id)) { + drupal_set_message("Error: Invalid room location ID '" . $location_id . "' supplied. Unable to allocate rooms.", + 'error', FALSE); + drupal_goto('admin/booking/rooms'); + return ""; + } + + $location_description = db_query("SELECT booking_roomlocation_descrip FROM {booking_room_locations} where lid = :id", + array(':id' => $location_id)) + ->fetchObject(); + + //$prefix = t("
Room assignment report rows:\n@info", array('@info' => print_r( $rows, true))); + + $result = array ( + '#attached' => array ( + 'css' => array(drupal_get_path('module', 'booking') . '/booking.css') + ), + 'first_para' => array ( + '#type' => 'markup', + '#markup' => $prefix, + ), + 'table' => array ( + '#theme' => 'table', + '#header' => $header, + '#rows' => $rows, + '#attributes' => array('id' => 'sort-table'), + '#empty' => t('No room allocations found for this location.'), + ) ); - return array ( - 'form' => $form, - ); -} //end booking_rooms_allocate_test_form + return $result; -/** - * Process the submission for room assignment - */ -function booking_rooms_allocate_test_form_submit($form, &$form_state) { - global $event; - - $values = $form_state['input']; - //watchdog('booking_debug', "
Room assignment test submission form :\n@info", array('@info' => print_r( $form, true))); - - //query for existing room allocations - $query = db_select('booking_person', 'p'); - $query->leftJoin('booking_room_mapping', 'm', 'm.booking_nodeid = p.nid'); - $query->condition('p.booking_eventid', $event->eid, '='); - $query->fields('p', array('booking_lastname', 'booking_firstname'))->fields('m'); - $room_mapping = $query->execute()->fetchAllAssoc('booking_nodeid'); - - $bed_inputs = array( - 'booking_room_singlebed' => 1, - 'booking_room_doublebed_p1' => 2, - 'booking_room_doublebed_p2' => 2, - 'booking_room_queenbed_p1' => 3, - 'booking_room_queenbed_p2' => 3, - ); - - //go through the different bed types - foreach ($bed_inputs as $type => $type_id) - { - //if this bed type wasn't defined in the form, skip it - if (empty($values[$type])) - continue; - - //watchdog('booking_debug', "
Room assignment submission for !type:\n@info", array('!type' => $type, '@info' => print_r( $values[$type], true))); - - //go through each room - foreach($values[$type] as $room => $data) - { - //go through each bed - foreach ($data as $bed_index => $person) - { - //check for previous value - $previous_nid = 0; - $previous_nid = _booking_rooms_allocate_get_previous_value($form, $type, $room, $type . '[' . $room . '][' . $bed_index . ']'); - - if (! empty($person)) { - //extract nid from $person using regex - if (preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches)) { - //watchdog('booking_debug', "Processing room assignment for ID !id belonging to person !person ", array('!id' => $matches[1], '!person' => $person)); - $nid = $matches[1]; - - //handle the insert/update/deletes required - _booking_rooms_allocate_test_form_submit_helper($room_mapping, $room, $type_id, $bed_index, $nid, $previous_nid); - - } //parsed node id successfully - - - } //empty bed check - elseif (empty($person) && $previous_nid > 0) - { - $message = t('Removing person !person previously in room id !room with bed index !index and bed type !type.', - array('!room' => $room, '!index' => $bed_index, '!person' => $previous_nid, '!type' => $type_id)); - watchdog('booking', $message); - drupal_set_message($message); - - db_delete('booking_room_mapping') - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $previous_nid) - ->condition('booking_room_bedtype', $type_id) - ->condition('booking_roomid', $room) - ->execute(); - - } - else - { - //TODO: Check if this bed used to have someone allocated - //and if so, remove their mapping - } - } //next bed - } //next room - } //next bed type -} //end function - - -/** - * look through the previous form data and return the matching element - */ -function _booking_rooms_allocate_get_previous_value(&$form, $type, $room, $name) { - - foreach($form['form']['rooms']['#rows'] as $key => $value) - { - //watchdog('booking_debug', "
Room assignment checker for type !type in room !room:\n@info", array('!room' => $room, '!type' => $type, '@info' => print_r( $value, true))); - //return; - if ((!empty($value[$type]['data']['#value'])) && ($value[$type]['data']['#name'] == $name)) { - //watchdog('booking_debug', "Found correct room with room number !num and type !type", array('!num' => $room, '!type' => $type)); - - //found the correct element, extract the node id - $person = $value[$type]['data']['#value']; - if (preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches)) { - return $matches[1]; - } - } - } - - //in case there was no matching value, return an empty string - return 0; } /** - * function to update person with correct bed allocation and remove any previous allocation if necessary + * Function for generating a name relating to a node id + * @param $attendees - an associative array containing the possible attendees + * @param $nid - the node id of the person for which to return the formatted string + * @return string containing first name and last name relating to node id */ -function _booking_rooms_allocate_test_form_submit_helper(&$room_mapping, $room, $type_id, $bed_index, $nid, $previous_nid) -{ - global $event; - $message = ""; +function _booking_rooms_view_formatperson(&$attendees, $nid) { - //remove any person previously defined for this bed that doesn't match what is now defined - if ($previous_nid > 0 && $nid != $previous_nid) - { - $message = t('Bed allocation for room !room and bed index !index has changed. Removing previous !person from this location.', - array('!room' => $room, '!index' => $bed_index, '!person' => $previous_nid)); - watchdog('booking', $message); - drupal_set_message($message); - - //look for an exact match, - //in case this person has moved to a different bed type during this form submission - db_delete('booking_room_mapping') - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $previous_nid) - ->condition('booking_room_bedtype', $type_id) - ->condition('booking_roomid', $room) - ->execute(); - } + $output = "Empty"; - //if this person didn't previously have a room/bed mapping - if (empty($room_mapping[$nid])) + if ($nid > 0 && !empty($attendees[$nid])) { - //Validate that there is capacity for the person to be allocated to this room - if (_booking_room_capacity_check($room, $type_id)) - { - $message = t('Assigning person id !id to a type !type bed in room id !room.', - array('!id' => $nid, '!room' => $room, '!type' => $type_id)); - - //double check we haven't already allocated a bed during this submission - $check = db_query("SELECT * FROM {booking_room_mapping} " . - " WHERE booking_eventid = :eid AND booking_roomid = :rid " . - " AND booking_room_bedtype = :type AND booking_nodeid = :nid", - array(':eid' => $event->eid, ':rid' => $room, ':type' => $type_id, - ':nid' => $nid, - ))->fetchObject(); - - if (! $check) - { - $result = db_insert('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $room, - 'booking_eventid' => $event->eid, - 'booking_nodeid' => $nid, - 'booking_room_bedtype' => $type_id, - )) - ->execute(); - } - //this person has already been inserted during this form submission - //so don't add them in twice - else - { - $message .= t(' Except this person already exists.'); - } - - } - //no capacity available in this room - else - { - $message = t('No capacity to assign person id !id to a type !type bed in room id !room.', - array('!id' => $nid, '!room' => $room, '!type' => $type_id) - ); - } - } - //this person previously had a room mapping but to a different room - elseif ((!empty($room_mapping[$nid])) && $room_mapping[$nid]->booking_roomid != $room) - { - $message = t('Changing person id !id from old room !oldroom to new room !room with type !type bed.', - array('!id' => $nid, '!room' => $room, '!type' => $type_id, - '!oldroom' => $room_mapping[$nid]->booking_roomid)); - - db_update('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $room, - 'booking_room_bedtype' => $type_id, - )) - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $nid) - ->execute(); - } - //this person previously had a room mapping but to a different bed type in the same room - elseif ((!empty($room_mapping[$nid])) && $room_mapping[$nid]->booking_room_bedtype != $type_id) - { - $message = t('Changing person id !id in room !room to new bed type type !type .', - array('!id' => $nid, '!room' => $room, '!type' => $type_id, - '!oldroom' => $room_mapping[$nid]->booking_roomid)); - - db_update('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $room, - 'booking_room_bedtype' => $type_id, - )) - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $nid) - ->execute(); - + $output = $attendees[$nid]->booking_firstname . " " . $attendees[$nid]->booking_lastname; } - //log the result if there was one - if ($message !== "") - { - watchdog('booking', $message); - drupal_set_message($message); - } - -} - - -/** - * function to generate table rows for each single bed defined in this room - */ -function _booking_rooms_allocate_generate_singlebeds($data, $existing_beds, $default_row, &$counter, &$form) { - //create an additional row for each single bed - for ($i = 0; $i < $data->booking_room_singlebeds; $i++) - { - $single_bed = array ( - '#id' => 'booking-room-singlebed-' . $data->rid . '-' . $i, - '#type' => 'textfield', - '#title' => 'Name', - '#title_display' => 'invisible', - '#name' => 'booking_room_singlebed[' . $data->rid . '][' . $i . ']', - '#size' => 100, - '#autocomplete_path' => 'booking/rooms/autocomplete', - '#value' => (!empty($existing_beds[1][$i])) ? $existing_beds[1][$i] : '', - '#attributes' => array('style' => array('width:200px')), - ); - - $form['rooms'][$data->rid][$counter] = array( - 'booking-room-singlebed' => &$single_bed, - ); - - $new_row = _booking_clone_array($default_row); - $new_row['booking_room_singlebed'] = array('data' => &$single_bed); - - $form['rooms']['#rows'][$counter] = $new_row; - - unset($single_bed); - $counter++; - } -} - -/** - * function to generate table rows for each double bed defined in this room - */ -function _booking_rooms_allocate_generate_doublebeds($data, $existing_beds, $default_row, &$counter, &$form) { - //create an additional row for each double bed - //$j is our counter that increments twice as fast as $i to cater for both beds - $j = 0; - for ($i = 0; $i < $data->booking_room_doublebeds; $i++) - { - $double_bed_p1 = array ( - '#id' => 'booking-room-doublebed-p1-' . $data->rid . '-' . $i, - '#type' => 'textfield', - '#title' => 'Name', - '#title_display' => 'invisible', - '#name' => 'booking_room_doublebed_p1[' . $data->rid . '][' . $i . ']', - '#size' => 100, - '#autocomplete_path' => 'booking/rooms/autocomplete', - '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : '', - '#attributes' => array('style' => array('width:200px')), - ); - $double_bed_p2 = array ( - '#id' => 'booking-room-doublebed-p2-' . $data->rid . '-' . $i, - '#type' => 'textfield', - '#title' => 'Name', - '#title_display' => 'invisible', - '#name' => 'booking_room_doublebed_p2[' . $data->rid . '][' . $i . ']', - '#size' => 100, - '#autocomplete_path' => 'booking/rooms/autocomplete', - '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : '', - '#attributes' => array('style' => array('width:200px')), - ); - - //include fields for rendering - $form['rooms'][$data->rid][$counter] = array( - 'booking-room-doublebed-p1' => &$double_bed_p1, - 'booking-room-doublebed-p2' => &$double_bed_p2, - ); - - //add references to the fields for the row so that theme_table can theme appropriately - $new_row = _booking_clone_array($default_row); - $new_row['booking_room_doublebed_p1'] = array('data' => &$double_bed_p1); - $new_row['booking_room_doublebed_p2'] = array('data' => &$double_bed_p2); - $form['rooms']['#rows'][$counter] = $new_row; - - unset($double_bed_p1); - unset($double_bed_p2); - $counter++; - } -} - -/** - * function to generate table rows for each queen bed defined in this room - */ -function _booking_rooms_allocate_generate_queenbeds($data, $existing_beds, $default_row, &$counter, &$form) { - //create an additional row for each double bed - //$j is our counter that increments twice as fast as $i to cater for both beds - $j = 0; - for ($i = 0; $i < $data->booking_room_queenbeds; $i++) - { - //calculate the two form elements for queen beds - $queen_bed_p1 = array ( - '#id' => 'booking-room-queenbed-p1-' . $data->rid . '-' . $i, - '#type' => 'textfield', - '#title' => 'Name', - '#title_display' => 'invisible', - '#name' => 'booking_room_queenbed_p1[' . $data->rid . '][' . $i . ']', - '#size' => 100, - '#autocomplete_path' => 'booking/rooms/autocomplete', - '#value' => (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : '', - '#attributes' => array('style' => array('width:200px')), - ); - $queen_bed_p2 = array ( - '#id' => 'booking-room-queenbed-p2-' . $data->rid . '-' . $i, - '#type' => 'textfield', - '#title' => 'Name', - '#title_display' => 'invisible', - '#name' => 'booking_room_queenbed_p2[' . $data->rid . '][' . $i . ']', - '#size' => 100, - '#autocomplete_path' => 'booking/rooms/autocomplete', - '#value' => (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : '', - '#attributes' => array('style' => array('width:200px')), - ); - - // Include the fields so they'll be rendered and named - // correctly, but they'll be ignored here when rendering as - // we're using #theme => table. - $form['rooms'][$data->rid][$counter] = array( - 'booking-room-queenbed-p1' => &$queen_bed_p1, - 'booking-room-queenbed-p2' => &$queen_bed_p2, - ); - - // Now add references to the fields to the rows that - // `theme_table()` will use. - - $new_row = _booking_clone_array($default_row); - $new_row['booking_room_queenbed_p1'] = array('data' => &$queen_bed_p1); - $new_row['booking_room_queenbed_p2'] = array('data' => &$queen_bed_p2); - $form['rooms']['#rows'][$counter] = $new_row; - - unset($queen_bed_p1); - unset($queen_bed_p2); - $counter++; - } -} + return $output; +} \ No newline at end of file diff --git a/booking.rooms_allocate.inc b/booking.rooms_allocate.inc new file mode 100644 index 0000000..abb8476 --- /dev/null +++ b/booking.rooms_allocate.inc @@ -0,0 +1,507 @@ +fields('p', array('nid', 'booking_firstname', 'booking_lastname')); + $db_or = db_or()->condition('p.booking_lastname', '%' . db_like($string) . '%', 'LIKE')->condition('p.booking_firstname', '%' . db_like($string) . '%', 'LIKE'); + $db_and = db_and()->condition($db_or)->condition('p.booking_eventid', $event->eid, '='); + $result = $query->condition($db_and) + ->execute(); + + // save the query to matches + foreach ($result as $row) { + $name = $row->booking_lastname . ', ' . $row->booking_firstname . ' [' . $row->nid . ']'; + $matches[$name] = $name; + } + + // Return the result to the form in json + drupal_json_output($matches); +} + +/** + * Test function for allocating people to rooms with an autocomplete field + * Using a regular table of elements as per https://passingcuriosity.com/2011/drupal-7-forms-tables/ + */ +function booking_rooms_allocate_form($node, &$form_state, $location_id) { + global $event; + $form = array(); + $attendee_select = array(); + $options = array(); + $counter = 0; + + $prefix = "
Enter part of a person's name in the text field and wait for the blue spinning circle to autocomplete with the person's details. Make sure you click on the person from the dropdown list that appears.
"; + $form['first_para'] = array ( + '#type' => 'markup', + '#markup' => $prefix, + ); + + //verify that $location_id is a number + if (! preg_match('/^[0-9]+$/', $location_id)) { + drupal_set_message("Error: Invalid room location ID '" . $location_id . "' supplied. Unable to allocate rooms.", 'error', FALSE); + drupal_goto('admin/booking/rooms'); + return ""; + } + + //query for existing room allocations + $query = db_select('booking_person', 'p'); + $query->leftJoin('booking_room_mapping', 'm', 'm.booking_nodeid = p.nid'); + $query->condition('p.booking_eventid', $event->eid, '='); + $query->fields('p', array('booking_lastname', 'booking_firstname'))->fields('m'); + $room_mapping = $query->execute()->fetchAllAssoc('booking_nodeid'); + + //query for room definitions + $room_query = db_query("SELECT r.*, l.* FROM {booking_room_definition} r " . + "INNER JOIN {booking_room_locations} l on r.booking_room_location_id = l.lid " . + "WHERE booking_room_location_id = :lid " . + "ORDER BY CAST(booking_room_number as SIGNED INTEGER) ASC", + array(':lid' => $location_id)); + + //define the table header + $header = array ( + 'booking_room_location' => array('data' => t('Room Location'), 'field' => 'booking_room_location_id'), + 'booking_room_number' => array('data' => t('Room Number')), + 'booking_room_singlebed' => array('data' => t('Single Bed')), + 'booking_room_doublebed_p1' => array('data' => t('Double Bed Person 1')), + 'booking_room_doublebed_p2' => array('data' => t('Double Bed Person 2')), + 'booking_room_queenbed_p1' => array('data' => t('Queen Bed Person 1')), + 'booking_room_queenbed_p2' => array('data' => t('Queen Bed Person 2')), + ); + + //attach the custom css + $form['#attached']['css'] = array( + drupal_get_path('module', 'booking') . '/booking.css', + ); + + //create the container element for the whole table + $form['rooms'] = array( + '#prefix' => 'Room assignment test submission form :\n@info", array('@info' => print_r( $form, true))); + + //query for existing room allocations + $query = db_select('booking_person', 'p'); + $query->leftJoin('booking_room_mapping', 'm', 'm.booking_nodeid = p.nid'); + $query->condition('p.booking_eventid', $event->eid, '='); + $query->fields('p', array('booking_lastname', 'booking_firstname'))->fields('m'); + $room_mapping = $query->execute()->fetchAllAssoc('booking_nodeid'); + + $bed_inputs = array( + 'booking_room_singlebed' => 1, + 'booking_room_doublebed_p1' => 2, + 'booking_room_doublebed_p2' => 2, + 'booking_room_queenbed_p1' => 3, + 'booking_room_queenbed_p2' => 3, + ); + + //go through the different bed types + foreach ($bed_inputs as $type => $type_id) + { + //if this bed type wasn't defined in the form, skip it + if (empty($values[$type])) + continue; + + //watchdog('booking_debug', "
Room assignment submission for !type:\n@info", array('!type' => $type, '@info' => print_r( $values[$type], true))); + + //go through each room + foreach($values[$type] as $room => $data) + { + //go through each bed + foreach ($data as $bed_index => $person) + { + //check for previous value + $previous_nid = 0; + $previous_nid = _booking_rooms_allocate_get_previous_value($form, $type, $room, $type . '[' . $room . '][' . $bed_index . ']'); + + if (! empty($person)) { + //extract nid from $person using regex + if (preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches)) { + //watchdog('booking_debug', "Processing room assignment for ID !id belonging to person !person ", array('!id' => $matches[1], '!person' => $person)); + $nid = $matches[1]; + + //handle the insert/update/deletes required + _booking_rooms_allocate_form_submit_helper($room_mapping, $room, $type_id, $bed_index, $nid, $previous_nid); + + } //parsed node id successfully + + + } //empty bed check + elseif (empty($person) && $previous_nid > 0) + { + $message = t('Removing person !person previously in room id !room with bed index !index and bed type !type.', + array('!room' => $room, '!index' => $bed_index, '!person' => $previous_nid, '!type' => $type_id)); + watchdog('booking', $message); + drupal_set_message($message); + + db_delete('booking_room_mapping') + ->condition('booking_eventid', $event->eid) + ->condition('booking_nodeid', $previous_nid) + ->condition('booking_room_bedtype', $type_id) + ->condition('booking_roomid', $room) + ->execute(); + + } + else + { + //TODO: Check if this bed used to have someone allocated + //and if so, remove their mapping + } + } //next bed + } //next room + } //next bed type +} //end function + + +/** + * look through the previous form data and return the matching element + */ +function _booking_rooms_allocate_get_previous_value(&$form, $type, $room, $name) { + + foreach($form['form']['rooms']['#rows'] as $key => $value) + { + //watchdog('booking_debug', "
Room assignment checker for type !type in room !room:\n@info", array('!room' => $room, '!type' => $type, '@info' => print_r( $value, true))); + //return; + if ((!empty($value[$type]['data']['#value'])) && ($value[$type]['data']['#name'] == $name)) { + //watchdog('booking_debug', "Found correct room with room number !num and type !type", array('!num' => $room, '!type' => $type)); + + //found the correct element, extract the node id + $person = $value[$type]['data']['#value']; + if (preg_match('/[\s\w,]+\s\[(\d+)\]/i', $person, $matches)) { + return $matches[1]; + } + } + } + + //in case there was no matching value, return an empty string + return 0; +} + +/** + * function to update person with correct bed allocation and remove any previous allocation if necessary + */ +function _booking_rooms_allocate_form_submit_helper(&$room_mapping, $room, $type_id, $bed_index, $nid, $previous_nid) +{ + global $event; + $message = ""; + + //remove any person previously defined for this bed that doesn't match what is now defined + if ($previous_nid > 0 && $nid != $previous_nid) + { + $message = t('Bed allocation for room !room and bed index !index has changed. Removing previous !person from this location.', + array('!room' => $room, '!index' => $bed_index, '!person' => $previous_nid)); + watchdog('booking', $message); + drupal_set_message($message); + + //look for an exact match, + //in case this person has moved to a different bed type during this form submission + db_delete('booking_room_mapping') + ->condition('booking_eventid', $event->eid) + ->condition('booking_nodeid', $previous_nid) + ->condition('booking_room_bedtype', $type_id) + ->condition('booking_roomid', $room) + ->execute(); + } + + //if this person didn't previously have a room/bed mapping + if (empty($room_mapping[$nid])) + { + //Validate that there is capacity for the person to be allocated to this room + if (_booking_room_capacity_check($room, $type_id)) + { + $message = t('Assigning person id !id to a type !type bed in room id !room.', + array('!id' => $nid, '!room' => $room, '!type' => $type_id)); + + //double check we haven't already allocated a bed during this submission + $check = db_query("SELECT * FROM {booking_room_mapping} " . + " WHERE booking_eventid = :eid AND booking_roomid = :rid " . + " AND booking_room_bedtype = :type AND booking_nodeid = :nid", + array(':eid' => $event->eid, ':rid' => $room, ':type' => $type_id, + ':nid' => $nid, + ))->fetchObject(); + + if (! $check) + { + $result = db_insert('booking_room_mapping') + ->fields(array( + 'booking_roomid' => $room, + 'booking_eventid' => $event->eid, + 'booking_nodeid' => $nid, + 'booking_room_bedtype' => $type_id, + )) + ->execute(); + } + //this person has already been inserted during this form submission + //so don't add them in twice + else + { + $message .= t(' Except this person already exists.'); + } + + } + //no capacity available in this room + else + { + $message = t('No capacity to assign person id !id to a type !type bed in room id !room.', + array('!id' => $nid, '!room' => $room, '!type' => $type_id) + ); + } + } + //this person previously had a room mapping but to a different room + elseif ((!empty($room_mapping[$nid])) && $room_mapping[$nid]->booking_roomid != $room) + { + $message = t('Changing person id !id from old room !oldroom to new room !room with type !type bed.', + array('!id' => $nid, '!room' => $room, '!type' => $type_id, + '!oldroom' => $room_mapping[$nid]->booking_roomid)); + + db_update('booking_room_mapping') + ->fields(array( + 'booking_roomid' => $room, + 'booking_room_bedtype' => $type_id, + )) + ->condition('booking_eventid', $event->eid) + ->condition('booking_nodeid', $nid) + ->execute(); + } + //this person previously had a room mapping but to a different bed type in the same room + elseif ((!empty($room_mapping[$nid])) && $room_mapping[$nid]->booking_room_bedtype != $type_id) + { + $message = t('Changing person id !id in room !room to new bed type type !type .', + array('!id' => $nid, '!room' => $room, '!type' => $type_id, + '!oldroom' => $room_mapping[$nid]->booking_roomid)); + + db_update('booking_room_mapping') + ->fields(array( + 'booking_roomid' => $room, + 'booking_room_bedtype' => $type_id, + )) + ->condition('booking_eventid', $event->eid) + ->condition('booking_nodeid', $nid) + ->execute(); + + } + + //log the result if there was one + if ($message !== "") + { + watchdog('booking', $message); + drupal_set_message($message); + } + +} + + +/** + * function to generate table rows for each single bed defined in this room + */ +function _booking_rooms_allocate_generate_singlebeds($data, $existing_beds, $default_row, &$counter, &$form) { + //create an additional row for each single bed + for ($i = 0; $i < $data->booking_room_singlebeds; $i++) + { + $single_bed = array ( + '#id' => 'booking-room-singlebed-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_singlebed[' . $data->rid . '][' . $i . ']', + '#size' => 100, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[1][$i])) ? $existing_beds[1][$i] : '', + '#attributes' => array('style' => array('width:200px')), + ); + + $form['rooms'][$data->rid][$counter] = array( + 'booking-room-singlebed' => &$single_bed, + ); + + $new_row = _booking_clone_array($default_row); + $new_row['booking_room_singlebed'] = array('data' => &$single_bed); + + $form['rooms']['#rows'][$counter] = $new_row; + + unset($single_bed); + $counter++; + } +} + +/** + * function to generate table rows for each double bed defined in this room + */ +function _booking_rooms_allocate_generate_doublebeds($data, $existing_beds, $default_row, &$counter, &$form) { + //create an additional row for each double bed + //$j is our counter that increments twice as fast as $i to cater for both beds + $j = 0; + for ($i = 0; $i < $data->booking_room_doublebeds; $i++) + { + $double_bed_p1 = array ( + '#id' => 'booking-room-doublebed-p1-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_doublebed_p1[' . $data->rid . '][' . $i . ']', + '#size' => 100, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : '', + '#attributes' => array('style' => array('width:200px')), + ); + $double_bed_p2 = array ( + '#id' => 'booking-room-doublebed-p2-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_doublebed_p2[' . $data->rid . '][' . $i . ']', + '#size' => 100, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : '', + '#attributes' => array('style' => array('width:200px')), + ); + + //include fields for rendering + $form['rooms'][$data->rid][$counter] = array( + 'booking-room-doublebed-p1' => &$double_bed_p1, + 'booking-room-doublebed-p2' => &$double_bed_p2, + ); + + //add references to the fields for the row so that theme_table can theme appropriately + $new_row = _booking_clone_array($default_row); + $new_row['booking_room_doublebed_p1'] = array('data' => &$double_bed_p1); + $new_row['booking_room_doublebed_p2'] = array('data' => &$double_bed_p2); + $form['rooms']['#rows'][$counter] = $new_row; + + unset($double_bed_p1); + unset($double_bed_p2); + $counter++; + } +} + +/** + * function to generate table rows for each queen bed defined in this room + */ +function _booking_rooms_allocate_generate_queenbeds($data, $existing_beds, $default_row, &$counter, &$form) { + //create an additional row for each double bed + //$j is our counter that increments twice as fast as $i to cater for both beds + $j = 0; + for ($i = 0; $i < $data->booking_room_queenbeds; $i++) + { + //calculate the two form elements for queen beds + $queen_bed_p1 = array ( + '#id' => 'booking-room-queenbed-p1-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_queenbed_p1[' . $data->rid . '][' . $i . ']', + '#size' => 100, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : '', + '#attributes' => array('style' => array('width:200px')), + ); + $queen_bed_p2 = array ( + '#id' => 'booking-room-queenbed-p2-' . $data->rid . '-' . $i, + '#type' => 'textfield', + '#title' => 'Name', + '#title_display' => 'invisible', + '#name' => 'booking_room_queenbed_p2[' . $data->rid . '][' . $i . ']', + '#size' => 100, + '#autocomplete_path' => 'booking/rooms/autocomplete', + '#value' => (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : '', + '#attributes' => array('style' => array('width:200px')), + ); + + // Include the fields so they'll be rendered and named + // correctly, but they'll be ignored here when rendering as + // we're using #theme => table. + $form['rooms'][$data->rid][$counter] = array( + 'booking-room-queenbed-p1' => &$queen_bed_p1, + 'booking-room-queenbed-p2' => &$queen_bed_p2, + ); + + // Now add references to the fields to the rows that + // `theme_table()` will use. + + $new_row = _booking_clone_array($default_row); + $new_row['booking_room_queenbed_p1'] = array('data' => &$queen_bed_p1); + $new_row['booking_room_queenbed_p2'] = array('data' => &$queen_bed_p2); + $form['rooms']['#rows'][$counter] = $new_row; + + unset($queen_bed_p1); + unset($queen_bed_p2); + $counter++; + } +} diff --git a/booking.rooms_old.inc b/booking.rooms_old.inc deleted file mode 100644 index c9edbbc..0000000 --- a/booking.rooms_old.inc +++ /dev/null @@ -1,983 +0,0 @@ - 'max-width:60%'); - $rows = array(); - - //get room definitions - $room_definitions = _booking_room_location_lookup(); - //ditch the first element which is empty - array_shift($room_definitions); - $i = 1; - - foreach ($room_definitions as $room) { - $rows[] = array( - $room, - l(t('Allocate Rooms'), t('admin/booking/rooms/!id/assign', array('!id' => $i))), - l(t('View Rooms'), t('admin/booking/rooms/!id/view', array('!id' => $i))), - ); - - $i++; - } - - //output everything - $output .= t("
Manually assign/update room allocation for !first !last.
Room Edit selected room location:\n@info", array('@info' => print_r( $selected_room_location, true))); - - $selected_room_num = isset($form_state['values']['booking_room_number']) ? - $form_state['values']['booking_room_number'] : $person->booking_room_number; - //watchdog('booking', "
Room Edit selected room number:\n@info", array('@info' => print_r( $selected_room_num, true))); - - $form['booking_room_location_id'] = array( - '#type' => 'select', - '#title' => t('Room Location'), - '#options' => $location_options, - '#default_value' => $person->booking_room_location_id, - '#ajax' => array( - 'event' => 'change', - 'wrapper' => 'booking_roomnum_wrapper', - 'callback' => 'booking_roomnum_ajax_callback', - ), - ); - - $form['booking_room_number'] = array( - '#type' => 'select', - '#title' => t('Room Number'), - //'#description' => t(''), - '#prefix' => '
Room Edit ajax callback:\n@info", array('@info' => print_r( $form, true))); - return $form['form']['booking_room_number']; -} - -/** - * Function to return the updated form element booking_room_bedtype for booking_room_edit_form() - */ -function booking_bedtype_ajax_callback($form, $form_state) { - //watchdog('booking', "
Room Edit ajax callback:\n@info", array('@info' => print_r( $form, true))); - return $form['form']['booking_room_bedtype']; -} - -/** - * Function to calculate appropriate range of room numbers for ajax enabled form booking_room_edit_form() - * @param $location_id - the room location id to look at - * @return array containing the room numbers for this location - */ -function _booking_get_roomedit_roomnum_options($selected) { - $room_options = array(); - $room_options[] = "--"; - - $room_query = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid", - array(':lid' => $selected)); - - foreach($room_query as $room) - { - $room_options[$room->booking_room_number] = $room->booking_room_number; - } - //watchdog('booking', "
Room Number Options:\n@info", array('@info' => print_r( $room_options, true))); - - return $room_options; -} - -/** - * Function to calculate appropriate bed options for ajax enabled form booking_room_edit_form() - * @param $location_id - the room location id to look at - * @param $room_num - the room number to get the bed details from - * @return array containing the bed options for this specific room - */ -function _booking_get_roomedit_bedtype_options($location_id, $room_num) { - $bed_options = array(); - $bed_options[] = "--"; - - $details = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid AND booking_room_number = :num", - array(':lid' => $location_id, ':num' => $room_num))->fetchObject(); - - //check we got a response from the query - if ($details) - { - //go through the bed options - if ($details->booking_room_singlebeds > 0) - { - $bed_options[1] = "Single"; - } - if ($details->booking_room_doublebeds > 0) - { - $bed_options[2] = "Double"; - } - if ($details->booking_room_queenbeds > 0) - { - $bed_options[3] = "Queen"; - } - } - - //watchdog('booking', "
Room Number Options:\n@info", array('@info' => print_r( $bed_options, true))); - - return $bed_options; -} - -/** - * Validate the submission to update allocated room and bed for a person - */ -function booking_room_edit_form_validate($form, &$form_state) { - //TODO: turn this into a generalised helper function, and use it for validating booking_rooms_allocate_form() also - - global $event; - $values = $form_state['input']; - - //watchdog('booking', "
Room Number Form State:\n@info", array('@info' => print_r( $form_state['values'], true))); - - //no need to validate if we're just removing the mapping - //op won't be defined in the form if it's just receiving the ajax callback, so check that is defined first - if (isset($form_state['values']['op']) && $form_state['values']['op'] == 'Remove') - { - return; - } - else - { - if (!isset($values['booking_room_location_id']) || !isset($values['booking_room_number']) || !isset($values['booking_room_bedtype'])) - { - form_set_error('form', - t('Invalid configuration detected. Please ensure a room location, room number and bed type are all set.') - ); - return; - } - - //get the specific room definition from the database - $details = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid AND booking_room_number = :num", - array(':lid' => $values['booking_room_location_id'], ':num' => $values['booking_room_number']))->fetchObject(); - - //perform a check to see if this person is already allocated to this bed - $check = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid AND booking_nodeid = :nid", - array(':eid' => $event->eid, ':nid' => $values['personid']))->fetchObject(); - - if ($check && ($check->booking_roomid == $details->rid && $check->booking_room_bedtype == $values['booking_room_bedtype'])) - { - //drupal_set_message('Not validating room capacity because this person is already allocated this bed in this room.'); - } - //there was no existing mapping for this person, so check that there's capacity in this room - elseif (! _booking_room_capacity_check($details->rid, $values['booking_room_bedtype'], $details)) - { - form_set_error('booking_room_number', - t('Unfortunately there are no beds available of the type specified in the room.') - ); - } - } -} - -/** - * Process the submission to update allocated room and bed for a person - */ -function booking_room_edit_form_submit($form, &$form_state) { - global $event; - $values = $form_state['input']; - $redirect_path = "admin/config/booking/rooms"; - - //check if we should remove the room allocation - if ($form_state['values']['op'] == 'Remove') - { - $message = t("Removing id !nid from room number !number in location !location", - array('!nid' => $values['personid'], '!location' => $values['booking_room_location_id'], - '!number' => $values['booking_room_number']) - ); - watchdog('booking', $message); - drupal_set_message($message, 'status', FALSE); - - db_delete('booking_room_mapping') - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $values['personid']) - ->execute(); - - - //return; - } - //otherwise, continue with adding/updating the room allocation - else - { - $details = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid AND booking_room_number = :num", - array(':lid' => $values['booking_room_location_id'], ':num' => $values['booking_room_number']))->fetchObject(); - - $check = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid AND booking_nodeid = :nid", - array(':eid' => $event->eid, ':nid' => $values['personid']))->fetchObject(); - - //this person already exists in mapping table - if ($check) - { - $message = t("Updating person id !nid to room id !id with bed type !type.", - array('!nid' => $values['personid'], '!id' => $details->rid, '!type' => _booking_room_bedtype_lookup($values['booking_room_bedtype']), - '!number' => $values['booking_room_number']) - ); - - //there is an existing mapping to update - $result = db_update('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $details->rid, - 'booking_room_bedtype' => $values['booking_room_bedtype'], - )) - ->condition('mid', $check->mid) - //->condition('booking_eventid', $event->eid) - //->condition('booking_nodeid', $values['personid']) - ->execute(); - - } - //create a new record in the mapping table - else - { - $message = t("Allocating person id !nid to room id !id with bed type !type.", - array('!nid' => $values['personid'], '!id' => $details->rid, '!type' => _booking_room_bedtype_lookup($values['booking_room_bedtype']), - '!number' => $values['booking_room_number']) - ); - - //create a new room mapping for this person - $result = db_insert('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $details->rid, - 'booking_eventid' => $event->eid, - 'booking_nodeid' => $values['personid'], - 'booking_room_bedtype' => $values['booking_room_bedtype'], - )) - ->execute(); - - } - watchdog('booking', $message); - drupal_set_message($message, 'status', FALSE); - - } //end operation check - - $form_state['redirect'] = $redirect_path; -} - - -/** - * Function for allocating rooms - */ -function booking_rooms_allocate_form($node, &$form_state, $location_id) { - global $event; - $form = array(); - $attendee_select = array(); - $options = array(); - $counter = 0; - - //verify that $location_id is a number - if (! preg_match('/^[0-9]+$/', $location_id)) { - drupal_set_message("Error: Invalid room location ID '" . $location_id . "' supplied. Unable to allocate rooms.", 'error', FALSE); - drupal_goto('admin/booking/rooms'); - return ""; - } - - //query for existing room allocations - $room_mapping_query = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid", - array(':eid' => $event->eid)); - //$room_mapping = $room_mapping_query->fetchAll(); - $room_mapping = $room_mapping_query->fetchAllAssoc('booking_nodeid'); - - //query for room definitions - $room_query = db_query("SELECT * FROM {booking_room_definition} WHERE booking_room_location_id = :lid ORDER BY CAST(booking_room_number as SIGNED INTEGER) ASC", - array(':lid' => $location_id)); - - //query for attendees - $query = db_query("SELECT nid, booking_firstname, booking_lastname, booking_gender, booking_dob, booking_partner_id " . - " FROM {booking_person} " . - " WHERE booking_eventid = :eid and (booking_status=1 or booking_status=5) order by booking_lastname, booking_firstname", - array(':eid' => $event->eid)); - - //make a list of all attendees that are booked in - $attendee_select[] = ''; - - foreach($query as $row) - { - $married = $row->booking_partner_id > 0 ? ' *' : ''; - $age = _booking_get_age_years($row->booking_dob); - $assigned_flag = empty($room_mapping[$row->nid]) ? '' : ' - '; - $attendee_select[$row->nid] = $assigned_flag . $row->booking_lastname . ', ' . $row->booking_firstname . ' ' . ' ['. $age . ' ' . $row->booking_gender . ']' . $married; - - } - - //watchdog('booking', "
Loading existing room allocations:\n@info", array('@info' => print_r( $room_mapping, true))); - - //attach the custom css - $form['#attached']['css'] = array( - drupal_get_path('module', 'booking') . '/booking.css', - ); - - //define the header - $header = array ( - 'booking_room_location' => array('data' => t('Room Location'), 'field' => 'booking_room_location_id'), - 'booking_room_number' => array('data' => t('Room Number')), - 'booking_room_singlebed' => array('data' => t('Single Bed')), - 'booking_room_doublebed_p1' => array('data' => t('Double Bed Person 1')), - 'booking_room_doublebed_p2' => array('data' => t('Double Bed Person 2')), - 'booking_room_queenbed_p1' => array('data' => t('Queen Bed Person 1')), - 'booking_room_queenbed_p2' => array('data' => t('Queen Bed Person 2')), - ); - - $default_row = array(); - $default_row['booking_room_location'] = ""; - $default_row['booking_room_number'] = ""; - $default_row['booking_room_singlebed'] = ""; - $default_row['booking_room_doublebed_p1'] = ""; - $default_row['booking_room_doublebed_p2'] = ""; - $default_row['booking_room_queenbed_p1'] = ""; - $default_row['booking_room_queenbed_p2'] = ""; - - foreach ($room_query as $data) - { - //load the existing bed mappings for this room - $existing_beds = array(); - for ($i = 1; $i <= 3; $i++) - { - foreach ($room_mapping as $mapping) - { - //check that the room id in the mapping table matches the room that we're currently adding to the table - //and also the bed type matches the first dimension in the array - if ($mapping->booking_roomid == $data->rid && $mapping->booking_room_bedtype == $i) - { - $existing_beds[$i][] = $mapping->booking_nodeid; - } - } - } - - //watchdog('booking', "
Existing bed mappings:\n@info", array('@info' => print_r( $existing_beds, true))); - - //create a row that contains just the room location and number - $row = _booking_clone_array($default_row); - $row['booking_room_location'] = _booking_room_location_lookup($data->booking_room_location_id); - $row['booking_room_number'] = $data->booking_room_number; - $row['#attributes'] = array('id' => array("new-group-row")); - $options[$counter++] = $row; - - //create an additional row for each single bed - for ($i = 0; $i < $data->booking_room_singlebeds; $i++) - { - //retrieve the default value if one exists - $default = (!empty($existing_beds[1][$i])) ? $existing_beds[1][$i] : 0; - - $row = _booking_clone_array($default_row); - $row['booking_room_singlebed'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_singlebed[' . $data->rid . '][' . $i . ']', - '#value' => $default, - )); - $options[$counter++] = $row; - } - - //create an additional row for each double bed - //$j is our counter that increments twice as fast as $i to cater for both beds - $j = 0; - for ($i = 0; $i < $data->booking_room_doublebeds; $i++) - { - $row = _booking_clone_array($default_row); - $row['booking_room_doublebed_p1'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_doublebed_p1[' . $data->rid . '][' . $i . ']', - '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0, - )); - $row['booking_room_doublebed_p2'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_doublebed_p2[' . $data->rid . '][' . $i . ']', - '#value' => (!empty($existing_beds[2][$j])) ? $existing_beds[2][$j++] : 0, - )); - $options[$counter++] = $row; - } - - //create an additional row for each queen bed - //$j is our counter that increments twice as fast as $i to cater for both beds - $j = 0; - for ($i = 1; $i <= $data->booking_room_queenbeds; $i++) - { - $row = _booking_clone_array($default_row); - $default = (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0; - - $row['booking_room_queenbed_p1'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_queenbed_p1[' . $data->rid . '][' . $i . ']', - '#value' => $default, - )); - - //find the default for the second bed - $default = (!empty($existing_beds[3][$j])) ? $existing_beds[3][$j++] : 0; - - $row['booking_room_queenbed_p2'] = array('data' => array( - '#type' => 'select', - '#options' => $attendee_select, - '#name' => 'booking_room_queenbed_p2[' . $data->rid . '][' . $i . ']', - '#value' => $default, - )); - - //add this row to the table - $options[$counter++] = $row; - } - - } - - $form['table'] = array ( - '#type' => 'tableselect', - '#header' => $header, - '#options' => $options, - '#empty' => t('No rooms found for this room location id.'), - ); - - //so we can access the dropdown elements - $form['booking_room_singlebed'] = array( '#type' => 'value' ); - $form['booking_room_queenbed_p1'] = array( '#type' => 'value' ); - $form['booking_room_queenbed_p2'] = array( '#type' => 'value' ); - $form['booking_room_doublebed_p1'] = array( '#type' => 'value' ); - $form['booking_room_doublebed_p2'] = array( '#type' => 'value' ); - - $form['submit'] = array ( - '#type' => 'submit', - '#value' => t('Submit'), - ); - - return array ( - 'form' => $form, - ); - -} - -/** - * Process the submission for room assignment - */ -function booking_rooms_allocate_form_submit($form, &$form_state) { - global $event; - - //query for existing room allocations - $room_mapping_query = db_query("SELECT * FROM {booking_room_mapping} WHERE booking_eventid = :eid", array(':eid' => $event->eid)); - $room_mapping = $room_mapping_query->fetchAllAssoc('booking_nodeid'); - - $bed_inputs = array( - 'booking_room_singlebed' => 1, - 'booking_room_doublebed_p1' => 2, - 'booking_room_doublebed_p2' => 2, - 'booking_room_queenbed_p1' => 3, - 'booking_room_queenbed_p2' => 3, - ); - - //watchdog('booking', "
Room assignment submission form state:\n@info", array('@info' => print_r( $form_state, true))); - - //go through the different bed types - foreach ($bed_inputs as $type => $type_id) - { - //watchdog('booking', "Bed type !type with id !id", array('!type' => $type, '!id' => $type_id)); - //watchdog('booking', "
Room assignment submission:\n@info", array('@info' => print_r( $form_state['values'][$type], true))); - - //if this bed type wasn't defined in the form, skip it - if (empty($form_state['values'][$type])) - continue; - - //go through each room - foreach($form_state['values'][$type] as $room => $value) - { - //go through each bed - foreach ($value as $index => $nid) - { - //calculate the name of the field for the bed - $bed_lookup = $type . '[' . $room . '][' . $index . ']'; - $previous_nid = 0; - $message = ""; - - //firstly check if there was a different nid here before - - //iterate the option input-types in the form array that made up the original form - foreach ($form['form']['table']['#options'] as $option) - { - //if this one was defined and matches the bed we're looking at now - if (!empty($option[$type]) && $option[$type]['data']['#name'] == $bed_lookup) - { - $previous_nid = $option[$type]['data']['#value']; - break; - } - } - - //if there is a person now selected for this bed - if ($nid > 0) - { - //remove any person previously defined here that doesn't match what is now defined - if ($previous_nid > 0 && $nid != $previous_nid) - { - $message = t('Bed allocation for room !room and bed index !index has changed. Removing previous !person from this location.', - array('!room' => $room, '!index' => $index, '!person' => $previous_nid)); - watchdog('booking', $message); - drupal_set_message($message); - - //look for an exact match, - //in case this person has moved to a different bed type during this form submission - db_delete('booking_room_mapping') - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $previous_nid) - ->condition('booking_room_bedtype', $type_id) - ->condition('booking_roomid', $room) - ->execute(); - } - //if this person didn't previously have a room/bed mapping - if (empty($room_mapping[$nid])) - { - //Validate that there is capacity for the person to be allocated to this room - if (_booking_room_capacity_check($room, $type_id)) - { - $message = t('Assigning person id !id to a type !type bed in room id !room.', - array('!id' => $nid, '!room' => $room, '!type' => $type_id)); - - //double check we haven't already allocated a bed during this submission - $check = db_query("SELECT * FROM {booking_room_mapping} " . - " WHERE booking_eventid = :eid AND booking_roomid = :rid " . - " AND booking_room_bedtype = :type AND booking_nodeid = :nid", - array(':eid' => $event->eid, ':rid' => $room, ':type' => $type_id, - ':nid' => $nid, - ))->fetchObject(); - - if (! $check) - { - $result = db_insert('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $room, - 'booking_eventid' => $event->eid, - 'booking_nodeid' => $nid, - 'booking_room_bedtype' => $type_id, - )) - ->execute(); - } - //this person has already been inserted during this form submission - //so don't add them in twice - else - { - $message .= t(' Except this person already exists.'); - } - - } - //no capacity available in this room - else - { - $message = t('No capacity to assign person id !id to a type !type bed in room id !room.', - array('!id' => $nid, '!room' => $room, '!type' => $type_id) - ); - } - } - //this person previously had a room mapping but to a different room - elseif ((!empty($room_mapping[$nid])) && $room_mapping[$nid]->booking_roomid != $room) - { - $message = t('Changing person id !id from old room !oldroom to new room !room with type !type bed.', - array('!id' => $nid, '!room' => $room, '!type' => $type_id, - '!oldroom' => $room_mapping[$nid]->booking_roomid)); - - db_update('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $room, - 'booking_room_bedtype' => $type_id, - )) - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $nid) - ->execute(); - } - //this person previously had a room mapping but to a different bed type in the same room - elseif ((!empty($room_mapping[$nid])) && $room_mapping[$nid]->booking_room_bedtype != $type_id) - { - $message = t('Changing person id !id in room !room to new bed type type !type .', - array('!id' => $nid, '!room' => $room, '!type' => $type_id, - '!oldroom' => $room_mapping[$nid]->booking_roomid)); - - db_update('booking_room_mapping') - ->fields(array( - 'booking_roomid' => $room, - 'booking_room_bedtype' => $type_id, - )) - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $nid) - ->execute(); - - } - //log the result if there was one - if ($message !== "") - { - watchdog('booking', $message); - drupal_set_message($message); - } - } - //this bed has no ID assigned now, but did it have something before? - elseif ($nid == 0 && $previous_nid > 0) - { - $message = t('Removing person !person previously in room id !room with bed index !index and bed type !type.', - array('!room' => $room, '!index' => $index, '!person' => $previous_nid, '!type' => $type_id)); - watchdog('booking', $message); - drupal_set_message($message); - - db_delete('booking_room_mapping') - ->condition('booking_eventid', $event->eid) - ->condition('booking_nodeid', $previous_nid) - ->condition('booking_room_bedtype', $type_id) - ->condition('booking_roomid', $room) - ->execute(); - - } //end node checking - } //iterate each bed - } //iterate each room - } //iterate each bed type -} - -/** - * Function for generating report of room allocations in a specific location - */ -function booking_rooms_view_form($node, &$form_state, $location_id) { - global $event; - $rows = array(); - $form = array(); - - //verify that $location_id is a number - if (! preg_match('/^[0-9]+$/', $location_id)) { - drupal_set_message("Error: Invalid room location ID '" . $location_id . "' supplied. Unable to allocate rooms.", - 'error', FALSE); - drupal_goto('admin/booking/rooms'); - return ""; - } - - $location_description = db_query("SELECT booking_roomlocation_descrip FROM {booking_room_locations} where lid = :id", - array(':id' => $location_id)) - ->fetchObject(); - - //$prefix = t("
Room assignment report rows:\n@info", array('@info' => print_r( $rows, true))); - - $result = array ( - '#attached' => array ( - 'css' => array(drupal_get_path('module', 'booking') . '/booking.css') - ), - 'first_para' => array ( - '#type' => 'markup', - '#markup' => $prefix, - ), - 'table' => array ( - '#theme' => 'table', - '#header' => $header, - '#rows' => $rows, - '#attributes' => array('id' => 'sort-table'), - '#empty' => t('No room allocations found for this location.'), - ) - ); - - return $result; - -} - -/** - * Function for generating a name relating to a node id - * @param $attendees - an associative array containing the possible attendees - * @param $nid - the node id of the person for which to return the formatted string - * @return string containing first name and last name relating to node id - */ -function _booking_rooms_view_formatperson(&$attendees, $nid) { - - $output = "Empty"; - - if ($nid > 0 && !empty($attendees[$nid])) - { - $output = $attendees[$nid]->booking_firstname . " " . $attendees[$nid]->booking_lastname; - } - - return $output; -} \ No newline at end of file diff --git a/booking.tokens.inc b/booking.tokens.inc index 8153a7f..50e5947 100644 --- a/booking.tokens.inc +++ b/booking.tokens.inc @@ -673,6 +673,12 @@ function booking_tokens($type, $tokens, array $data = array(), array $options = return $replacements; } +/** + * Function to define generic site-wide tokens relating to the bookings module + * + * @param none + * @return associative array containing tokens + */ function booking_define_tokens() { global $event; @@ -687,7 +693,7 @@ function booking_define_tokens() $tokens = array(); $tokens['eventname'] = $event->booking_eventname; $tokens['eventdates'] = _date_range_to_string(date("Y-m-d", $booking_times->booking_event_start), - date("Y-m-d", $booking_times->booking_event_end)); + date("Y-m-d", $booking_times->booking_event_end)); $tokens['contact-us'] = l('contact us', 'contact-us'); $tokens['contact-email'] = variable_get('booking_contact_email'); $tokens['regn-count'] = $regncount_query->num_ppl; @@ -695,7 +701,12 @@ function booking_define_tokens() return $tokens; } - +/** + * Function to define tokens related to a specific registration from the bookings module + * + * @param $node - object representing the registration + * @return associative array containing tokens for the specified person + */ function booking_define_personspecific_tokens($node) { global $event; @@ -741,7 +752,6 @@ function booking_define_personspecific_tokens($node) $tokens['balance-payment-link'] = url('balance/' . $tempid, array('absolute' => TRUE)); $tokens['confirm-payment-link'] = url('confirm/' . $tempid, array('absolute' => TRUE)); $tokens['paypal-total-amount'] = _booking_amount_owing($node, $amount_paid); - //$tokens['paypal-total-amount'] = _booking_amount_owing($node->nid, $amount_paid); $tokens['paypal-deposit-amount'] = _booking_deposit_amount($node, TRUE); $tokens['regn-summary'] = _booking_details_email_summary($node);