Index: hotel_booking/hotel_booking.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_hotel/hotel_booking/hotel_booking.module,v
retrieving revision 1.19
diff -u -p -r1.19 hotel_booking.module
--- hotel_booking/hotel_booking.module	15 May 2010 03:15:09 -0000	1.19
+++ hotel_booking/hotel_booking.module	18 May 2010 16:33:49 -0000
@@ -1,1750 +1,1750 @@
-<?php
-// $Id: hotel_booking.module,v 1.19 2010/05/15 03:15:09 larowlan Exp $
-
-/**
- * Ubercart Hotel Booking module.
- *
- * @file
- * Provides a hotel room type node type that pricing and availability information can be tied to.
- * Originally based on Availability Calendars module by Dan Karran (geodaniel).
- * @author Will Vincent (tcindie) <tcindie at gmail dot com>
- */
-
-
-
-/**
- * Implementation of hook_perm().
- */
-function hotel_booking_perm() {
-  return array('edit hotel room availability', 'administer hotel booking settings', 'view hotel search results');
-}
-
-function hotel_booking_can_edit() {
-      return user_access('edit hotel room availability');
-}
-
-function hotel_search_can_view() {
-      return user_access('view hotel search results');
-}
-
-
-
-/**
- * Implementation of hook_menu().
- */
-function hotel_booking_menu() {
-  $items = array();
-
-  $items['admin/store/hotel_booking'] = array(
-    'title'            => 'Hotel Booking',
-    'description'      => t('Administer Hotel Booking settings, configure base rate(s), rate and occupancy modifiers, and add-on/upgrade products.'),
-    'page callback'    => 'hotel_booking_show_rates',
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_NORMAL_ITEM,
-    'file'             => 'hotel_booking_admin.inc',
-  );
-  $items['admin/store/hotel_booking/rates'] = array(
-    'title'            => 'Base Rates',
-    'page callback'    => 'hotel_booking_show_rates',
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_DEFAULT_LOCAL_TASK,
-    'weight'           => 0,
-    'file'             => 'hotel_booking_admin.inc',
-  );
-  $items['admin/store/hotel_booking/rates/add'] = array(
-    'title'            => 'Add Rate',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_rates_form'),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/rates/%'] = array(
-    'title'            => 'View Rate',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_rates_form', 4),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/rates/%/delete'] = array(
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_rates_delete_form', 4),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/rate_modifiers'] = array(
-    'title'            => 'Rate Modifiers',
-    'page callback'    => 'hotel_booking_show_rate_modifiers',
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_LOCAL_TASK,
-    'weight'           => 1,
-    'file'             => 'hotel_booking_admin.inc',
-  );
-  $items['admin/store/hotel_booking/rate_modifiers/add'] = array(
-    'title'            => 'Add Rate',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_rate_modifiers_form'),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/rate_modifiers/%'] = array(
-    'title'            => 'View Rate',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_rate_modifiers_form', 4),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/rate_modifiers/%/delete'] = array(
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_rate_modifiers_delete_form', 4),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/occupancy_modifiers'] = array(
-    'title'            => 'Occupancy Modifiers',
-    'page callback'    => 'hotel_booking_show_occupancy_modifiers',
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_LOCAL_TASK,
-    'weight'           => 2,
-    'file'             => 'hotel_booking_admin.inc',
-  );
-  $items['admin/store/hotel_booking/occupancy_modifiers/add'] = array(
-    'title'            => 'Add Occupancy Modifier',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_occupancy_modifiers_form'),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/occupancy_modifiers/%'] = array(
-    'title'            => 'View Occupancy Modifier',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_occupancy_modifiers_form', 4),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/occupancy_modifiers/%/delete'] = array(
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_occupancy_modifiers_delete_form', 4),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_CALLBACK,
-    'file'             => 'hotel_booking_admin.inc'
-  );
-  $items['admin/store/hotel_booking/hotel_settings'] = array(
-    'title'            => 'Settings',
-    'description'      => 'Configure global settings for Hotel Booking module.',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('hotel_booking_admin_settings'),
-    'access arguments' => array('administer hotel booking settings'),
-    'type'             => MENU_LOCAL_TASK,
-    'weight'           => 4,
-    'file'             => 'hotel_booking_admin.inc',
-  );
-  $items['room_search/%'] = array(
-    'title'           => 'Hotel Room Search Results',
-    'page callback'   => 'hotel_search_view',
-    'page arguments'  => array(1),
-    'access callback' => 'hotel_search_can_view',
-    'type'            => MENU_CALLBACK,
-  );
-  $items['room_search/book_room'] = array(
-    'title'           => '',
-    'page callback'   => 'hotel_book_room',
-    'access callback' => 'hotel_search_can_view',
-    'type'            => MENU_CALLBACK,
-  );
-
-  return $items;
-}
-
-
-
-function hotel_booking_get_rates() {
-  $result = db_query("SELECT * FROM {hotel_rate_types}");
-  $rate_list = array();
-  while ($row = db_fetch_object($result)) {
-    $rate_list[$row->hrid] = $row;
-  }
-  return $rate_list;
-}
-
-
-function hotel_booking_get_rate_modifiers() {
-  $result = db_query("SELECT * FROM {hotel_rate_modifiers} ORDER BY method DESC, value ASC");
-  $modifiers = array();
-  while ($row = db_fetch_object($result)) {
-    $modifiers[$row->hrmid] = $row;
-  }
-  return $modifiers;
-}
-
-
-function hotel_booking_get_occupancy_modifiers() {
-  $result = db_query("SELECT * FROM {hotel_occupancy_modifiers} ORDER BY adult_child ASC, threshold ASC, value ASC");
-  $modifiers = array();
-  while ($row = db_fetch_object($result)) {
-    $modifiers[$row->hoid] = $row;
-  }
-  return $modifiers;
-}
-
-
-/**
- * Implementation of hook_block().
- */
-function hotel_booking_block($op = 'list', $delta = 0, $edit = array()) {
-  switch ($op) {
-    case 'list':
-
-      $blocks[0] = array(
-        'info'       => t('Hotel Booking: Search Widget'),
-      );
-      return $blocks;
-
-
-    case 'configure':
-
-      $form = array();
-
-      // Build list of room types
-      $room_types[0] = t('None');
-      $results = db_query('SELECT hrt.nid, n.title FROM {hotel_room_types} AS hrt, {node} AS n WHERE n.nid = hrt.nid');
-      while ($result = db_fetch_array($results)) {
-        $room_types['node/'. $result['nid']] = check_plain($result['title']);
-      }
-
-      $form['best_rate_link'] = array(
-        '#type'          => 'select',
-        '#title'         => t('Room with best rate'),
-        '#default_value' => variable_get('hotel_booking_best_rate', '0'),
-        '#options'       => $room_types,
-        '#description'   => t("Select the room type with the best rate to display a link to it in the search block, if no room type is selected, the link will not be displayed."),
-      );
-      $form['search_children'] = array(
-        '#type'          => 'select',
-        '#title'         => t('Children Selection'),
-        '#default_value' => variable_get('hotel_booking_block_children', '1'),
-        '#options'       => array(0 => 'No', 1 => 'Yes'),
-        '#description'   => t('Select whether or not to display the children selection option in search block. Value will be 0 for searches if No is selected here.'),
-      );
-      $form['search_smoking'] = array(
-        '#type'          => 'select',
-        '#title'         => t('Smoking Preference Selection'),
-        '#default_value' => variable_get('hotel_booking_block_smoking', '1'),
-        '#options'       => array(0 => 'No', 1 => 'Yes'),
-        '#description'   => t('Select whether or not to display the smoking preference selection option in search block. Value will be No Preference if No is selected here.'),
-      );
-
-      return $form;
-
-
-    case 'save':
-      variable_set('hotel_booking_best_rate', $edit['best_rate_link']);
-      variable_set('hotel_booking_block_children', $edit['search_children']);
-      variable_set('hotel_booking_block_smoking', $edit['search_smoking']);
-
-      return;
-
-
-    case 'view': default:
-      drupal_add_css(drupal_get_path('module', 'hotel_booking') .'/css/hotel_block.css');
-      $block['subject'] = t('Room Search');
-      $block['content'] = drupal_get_form('hotel_booking_widget_form');
-      return $block;
-  }
-}
-
-
-
-
-/**
- * hotel booking widget block content.
- */
-function hotel_booking_widget_form() {
-  if (variable_get('hotel_booking_best_rate', '')) {
-    $form['roomsearch']['link'] = array(
-      '#prefix' => '<div class="bking-best-rate">',
-      '#value'  => l(t('View Availability of Best Room Rate'), variable_get('hotel_booking_best_rate', '')),
-      '#suffix' => '</div>',
-    );
-  }
-
-  $form['roomsearch']['checkin'] = array(
-    '#prefix' => '<div class="bking-date">',
-    '#type' => 'date_popup',
-    '#title' => t('Check-In Date'),
-    '#required' => TRUE,
-    '#size' => 14,
-    '#date_type' => DATE_ISO,
-    '#date_timezone' => date_default_timezone_name(),
-    '#date_format' => 'm/d/Y',
-    '#date_year_range' => '-0:+1',
-    '#suffix' => '</div>',
-  );
-  $form['roomsearch']['staylength'] = array(
-    '#prefix' => '<div class="bking-stay-length">',
-    '#type' => 'select',
-    '#title' => t('Nights'),
-    '#options' => array(
-        '1' => '1',
-        '2' => '2',
-        '3' => '3',
-        '4' => '4',
-        '5' => '5',
-        '6' => '6',
-        '7' => '7',
-        '8' => '8',
-        '9' => '9',
-        '10' => '10',
-        '11' => '11',
-        '12' => '12',
-        '13' => '13',
-        '14' => '14',
-      ),
-    '#default_value' => 1,
-    '#suffix' => '</div>',
-  );
-  $form['roomsearch']['adults'] = array(
-    '#prefix' => '<div class="bking-adults">',
-    '#type' => 'select',
-    '#title' => t('Adults'),
-    '#options' => array(
-        '1' => '1',
-        '2' => '2',
-        '3' => '3',
-        '4' => '4',
-        '5' => '5',
-        '6' => '6',
-        '7' => '7',
-        '8' => '8',
-      ),
-    '#default_value' => 1,
-    '#suffix' => '</div>',
-  );
-  if (variable_get('hotel_booking_block_children', 1)) {
-    $form['roomsearch']['children'] = array(
-      '#prefix' => '<div class="bking-children">',
-      '#type' => 'select',
-      '#title' => t('Children'),
-      '#options' => range(0, 8),
-      '#suffix' => '</div>',
-    );
-  }
-  else {
-    $form['roomsearch']['children'] = array(
-      '#type' => 'hidden',
-      '#value' => 0,
-    );
-  }
-  if (variable_get('hotel_booking_block_smoking', 1)) {
-    $form['roomsearch']['smoking'] = array(
-      '#prefix' => '<div class="bking-smoking">',
-      '#type' => 'select',
-      '#title' => t('Preference'),
-      '#options' => array(
-        '1' => t('Non-Smoking'),
-        '2' => t('Smoking'),
-        '3' => t('No Preference'),
-      ),
-      '#default_value' => 1,
-      '#suffix' => '</div>',
-    );
-  }
-  else {
-    $form['roomsearch']['smoking'] = array(
-      '#type' => 'hidden',
-      '#value' => 3,
-    );
-  }
-
-  $form['roomsearch']['submit'] = array(
-    '#prefix' => '<div class="bking-submit">',
-    '#type'   => 'submit',
-    '#title'  => t('Search'),
-    '#value'  => t('Search Rooms'),
-    '#suffix' => '</div>',
-  );
-  return $form;
-}
-
-
-
-function hotel_booking_widget_form_submit($form, $form_state) {
-  // $adults = number of adults
-  $adults = $form_state['values']['adults'];
-
-  // $children = number of children
-  $children = $form_state['values']['children'];
-
-  // Smoking Preference:
-  // 0 = Non Smoking
-  // 1 = Smoking
-  // 2 = No Preference
-  $smoking = $form_state['values']['smoking']-1;
-
-  // $checkin = Check In Date in the format YYYY-MM-DD
-  $foo = explode(" ", $form_state['values']['checkin']);
-  $checkin = $foo[0];
-
-  // $nights = number of nights
-  $nights = $form_state['values']['staylength'];
-
-  // Combine all of the above into arguments separated by underscores
-  $args = $checkin .'_'. $nights .'_'. $adults .'_'. $children .'_'. $smoking;
-
-  drupal_goto("room_search/". $args);
-}
-
-
-
-function hotel_search_view($args) {
-
-  $values = explode("_", $args);
-
-  $checkin = $values[0];
-  $nights = $values[1];
-  $adults = $values[2];
-  $children = $values[3];
-  $smoking = $values[4];
-
-  $visitors = $adults + $children;
-
-  if ($smoking < 2) {
-    $result = db_query('SELECT nid,rate_type,rate_modifier FROM {hotel_room_types} WHERE smoking = %d AND %d <= capacity', $smoking, $visitors);
-  }
-  else {
-    $result = db_query('SELECT nid,rate_type,rate_modifier FROM {hotel_room_types} WHERE %d <= capacity', $visitors);
-  }
-
-  $foo = $checkin ."+ ". ($nights-1) ." days";
-  $lastnight = date("Y-m-d", strtotime($foo));
-  $checkout = date("Y-m-d", strtotime("$lastnight + 1 day"));
-
-  $roomtypes = array();
-
-  while ($results = db_fetch_array($result)) {
-    $roomtypes[$results['nid']]['rate_type'] = $results['rate_type'];
-    $roomtypes[$results['nid']]['rate_modifier'] = $results['rate_modifier'];
-  }
-
-  $roomtype = array();
-
-  foreach ($roomtypes as $rtid => $data) {
-    $chkin = db_fetch_array(db_query('SELECT nocheckin FROM {hotel_availability_calendars} WHERE rtid = %d and caldate = "%s 00:00:00"', $rtid, $checkin));
-    $chkout = db_fetch_array(db_query('SELECT nocheckout FROM {hotel_availability_calendars} WHERE rtid = %d and caldate = "%s 00:00:00"', $rtid, $checkout));
-    if (!$chkin['nocheckin'] && !$chkout['nocheckout']) {
-      // First get the rate modifier information for room type.
-      if ($data['rate_modifier'] > 0) {
-        $query = db_query('SELECT method, value FROM {hotel_rate_modifiers} WHERE hrmid = %d', $data['rate_modifier']);
-        $thisresult = db_fetch_array($query);
-        $roomtype[$rtid]['modifier']['amount'] = $thisresult['value'];
-        $roomtype[$rtid]['modifier']['method'] = $thisresult['method'];
-      }
-      else {
-        $roomtype[$rtid]['modifier']['amount'] = 0;
-        $roomtype[$rtid]['modifier']['method'] = "value";
-      }
-
-      // Loop through each night of the stay and gather info for room type.
-      for ($night = 0; $night < $nights; $night++) {
-        $thisdate = date("Y-m-d", strtotime("$checkin + $night day"));
-        $result = db_query('SELECT a.caldate, a.minoccupancy, a.minstay, r.rate FROM {hotel_availability_calendars} AS a, {hotel_rate_calendars} AS r WHERE a.rtid = %d AND a.caldate = "%s" AND r.caldate = a.caldate AND a.avail_quantity > 0 AND r.hrid = %d AND %d >= a.minoccupancy AND %d >= a.minstay', $rtid, $thisdate, $data['rate_type'], $visitors, $nights);
-
-        while ($results = db_fetch_array($result)) {
-          $foo = explode(" ", $results['caldate']);
-          $roomtype[$rtid]['nights'][$foo[0]]['price'] = $results['rate'];
-          $roomtype[$rtid]['nights'][$foo[0]]['minstay'] = $results['minstay'];
-          $roomtype[$rtid]['nights'][$foo[0]]['minoccupancy'] = $results['minoccupancy'];
-        }
-      }
-    }
-  }
-
- /***
- /* The result of our room search queries, thus far, is an array of available
- /* room types
- /*
- /* The key of each element of the array is the room type ID (this is also the Node ID)
- /* Rate modifier information for each room type is contained within the array
- /* as well as unmodified rates for each night.
- /* The result looks something like this:
- /*
- /* Array (
- /*
- /*   [1] => Array (                      // Room type ID.
- /*     [nights] => Array(                // Array of nights
- /*       [2009-06-01] => Array (         // Date of night.
- /*         [price] => 125.500            // Floating Point value of base price.
- /*         [minstay] => 0                // Min. Night stay requirement for
- /*                                           this date.
- /*         [minoccupancy] => 0           // Min. occupancy requirement for
- /*                                           this date.
- /*       )
- /*     )
- /*
- /*     [modifier] => Array (             // Rate modifier for this room type.
- /*       [amount] => 15.000              // Floating point value of modifier
- /*                                           amount, or 0 if none.
- /*       [method] => value               // Whether modifier is a monetary
- /*                                           value or percentage.
- /*     )
- /*   )
- /* )
- /***/
-
- // Build a new array containing only rooms with the correct number of nights
-  $rooms = array();
-  foreach ($roomtype as $rtid => $data) {
-    if (sizeof($roomtype[$rtid]['nights']) == $nights) {
-      $rooms[$rtid] = $data;
-    }
-  }
-
- // Now we'll adjust price per night for each room type with base price
- // modifiers, and occupancy modifiers.
-  $sorted_rates = array();
-  foreach ($rooms as $rtid => $data) {
-    $adult_query = db_query('SELECT o.threshold, o.value FROM {hotel_occupancy_modifiers} AS o, {hotel_room_occupancy_modifiers} AS ro WHERE ro.nid = %d AND ro.hoid = o.hoid AND adult_child = "adult" AND %d > threshold', $rtid, $adults);
-    $child_query = db_query('SELECT o.threshold, o.value FROM {hotel_occupancy_modifiers} AS o, {hotel_room_occupancy_modifiers} AS ro WHERE ro.nid = %d AND ro.hoid = o.hoid AND adult_child = "child" AND %d > threshold', $rtid, $children);
-    $both_query = db_query('SELECT o.threshold, o.value FROM {hotel_occupancy_modifiers} AS o, {hotel_room_occupancy_modifiers} AS ro WHERE ro.nid = %d AND ro.hoid = o.hoid AND adult_child = "occup" AND %d > threshold', $rtid, ($adults + $children));
-    $adult_om = array();
-    $child_om = array();
-    $both_om = array();
-    while ($adult_result = db_fetch_array($adult_query)) {
-      $adult_om[] = $adult_result;
-    }
-    while ($child_result = db_fetch_array($child_query)) {
-      $child_om[] = $child_result;
-    }
-    while ($both_result = db_fetch_array($both_query)) {
-      $both_om[] = $both_result;
-    }
-    $total = 0;
-    foreach ($data['nights'] as $night => $nightdata) {
-      $a = $adults;
-      $c = $children;
-      $b = $a + $c;
-      if ($data['modifier']['method'] == 'value') {
-        $rooms[$rtid]['nights'][$night]['price'] += $data['modifier']['amount'];
-      }
-      else {
-        $rooms[$rtid]['nights'][$night]['price'] += ($data['nights'][$night]['price'] * ($data['modifier']['amount']/100));
-      }
-      // Apply Adult Occupancy Modifier(s)
-      for ($z = sizeof($adult_om)-1; $z >= 0; $z--) {
-        if ($a > $adult_om[$z]['threshold']) {
-          $new_a = $a - $adult_om[$z]['threshold'];
-          $rooms[$rtid]['nights'][$night]['price'] += ($new_a * $adult_om[$z]['value']);
-          $a -= $new_a;
-        }
-      }
-
-      // Apply Child Occupancy Modifier(s)
-      for ($z = sizeof($child_om)-1; $z >= 0; $z--) {
-        if ($c > $child_om[$z]['threshold']) {
-          $new_c = $c - $child_om[$z]['threshold'];
-          $rooms[$rtid]['nights'][$night]['price'] += ($new_c * $child_om[$z]['value']);
-          $c -= $new_c;
-        }
-      }
-
-      // Apply Overall Occupant (Adults & Children) Occupancy Modifier(s)
-      for ($z = sizeof($both_om)-1; $z >= 0; $z--) {
-        if ($b > $both_om[$z]['threshold']) {
-          $new_b = $b - $both_om[$z]['threshold'];
-          $rooms[$rtid]['nights'][$night]['price'] += ($new_b * $both_om[$z]['value']);
-          $b -= $new_b;
-        }
-      }
-      $total += $rooms[$rtid]['nights'][$night]['price'];
-    }
-    $sorted_rates[$rtid] = $total;
-  }
-
-  // Sort results by rate. Default to Ascending if no preference is set.
-  if (variable_get('hotel_booking_sort_order', 'ASC') == 'ASC') {
-    asort($sorted_rates);
-  }
-  else {
-    arsort($sorted_rates);
-  }
-
-  $content = '<div class="hotelsearch-prefix';
-  if (count($sorted_rates) < 1) {
-    $content .= ' hotelsearch-noresults';
-  }
-  $content .= '">';
-  $content .= '<p>'. format_plural(count($sorted_rates), 'Your search returned 1 result', 'Your search returned @count results') .'</p>';
-  if (count($sorted_rates) < 1) {
-    $content .= variable_get('hotel_booking_no_search_results', t('<p>Please select different dates and try your search again.</p>'));
-  }
-  $content .= '</div>';
-  $resultcount = 0;
-  foreach ($sorted_rates as $rtid => $total) {
-      $node = node_load($rtid);
-      $avg = $total / $nights;
-      $pp = $total / $visitors;
-      $content .= '<div class="hotelsearchresult ';
-      $content .= ($resultcount%2) ? 'hotel-search-odd">' : 'hotel-search-even">';
-      $content .= '<form action="book_room" method="post"><div>';
-      $content .= '<input type="hidden" name="nodeid[]" value="'. $node->nid .'" /></div>';
-      $content .= '<h3 class="booking-title">'. l($node->title, drupal_get_path_alias('node/'. $node->nid)) .'</h3>';
-      $content .= '<h3 class="booking-price">$ ' . number_format($total, 2, '.', ',') .'</h3>';
-       if (variable_get('hotel_booking_search_teaser_body', 'teaser') == 'teaser') {
-        $content .= '<div class="hotel-roomdesc">'. check_markup($node->teaser, $node->format, FALSE)
-         .' '. l(t('more'), drupal_get_path_alias('node/'. $node->nid)) 
-          ."</div>";
-      }
-      elseif (variable_get('hotel_booking_search_teaser_body', 'teaser') == 'body') {
-        $content .= '<div class="hotel-roomdesc">'. check_markup($node->body, $node->format, FALSE) ."</div>";
-      }
-
-      $content .= '<div class="hotel-button"><input class="form-submit" type="submit" value="';
-      $content .= t('Book This Room') .'" /></div>';
-
-      $content .= '<fieldset class="clear collapsible collapsed"><legend><a href="#">'. t('Pricing Details') .'</a></legend>';
-      $content .= '<div class="hotel-total">Room Total:<br />$ '. number_format($total, 2, '.', ',') .'</div>';
-      $content .= '<div class="hotel-perperson-total">'. t('Total / Person:') .'<br />$ '. $pp .'</div>';
-      $content .= '<div class="hotel-avgpernight">'. t('Avg / Night:') .'<br />$ '. $avg .'</div>';
-      $content .= '<h5 class="clear">'. t('Nightly Breakdown:') .'</h5>';
-      $content .= '<div class="hotel-result-days">';
-      $content .= '<input type="hidden" name="roomtype" value="'. $node->nid .'" />';
-      $content .= '<input type="hidden" name="adults" value="'. $adults .'" />';
-      $content .= '<input type="hidden" name="children" value="'. $children .'" />';
-      $content .= '<input type="hidden" name="total" value="'. $total .'" />';
-
-      for ($z = 0; $z < sizeof($rooms[$rtid]['nights']); $z++) {
-        $content .= '<div class="hotel-result-day">'. date('M j', strtotime("$checkin + $z day")) ."<br />$ " . number_format($rooms[$rtid]['nights'][date("Y-m-d", strtotime("$checkin + $z day"))]['price'], 2, '.', ',');
-        $content .= '<input type="hidden" name="date[]" value="'. date('Y-m-d', strtotime("$checkin + $z day")) .'" />';
-        $content .= '<input type="hidden" name="price[]" value="'. number_format($rooms[$rtid]['nights'][date("Y-m-d", strtotime("$checkin + $z day"))]['price'], 2, '.', ',') .'" />';
-        $content .= '</div>';
-      }
-      $content .= '</div></fieldset>';
-
-      if (module_exists('imagecache') && ($field = variable_get('uc_image_'. $node->type, '')) && isset($node->$field) && file_exists($node->{$field}[0]['filepath'])) {
-        $content .= theme('uc_product_image', $node->$field, $teaser, $page);
-      }
-      $content .= hotel_calendars_node($node, date('Y', strtotime($checkin)), date('n', strtotime($checkin)), 2, TRUE) . '</div>';
-
-      $content .= '</form><div class="clear"></div></div>';
-      $resultcount++;
-  }
-  drupal_add_js("misc/collapse.js");
-  drupal_add_js(drupal_get_path('module', 'hotel_calendars') .'/js/calTip.js');
-  drupal_add_css(drupal_get_path('module', 'hotel_calendars') .'/js/calTip.css');
-  drupal_add_css(drupal_get_path('module', 'hotel_booking') .'/css/hotel_search_results.css');
-  print theme('page', $content);
-}
-
-
-
-function hotel_book_room() {
-  global $user;
-  $node = node_load($_POST['nodeid'][0]);
-  foreach ($_POST['date'] as $dates) {
-    $nights[] = $dates;
-  }
-  foreach ($_POST['price'] as $price) {
-    $prices[] = $price;
-  }
-  $total = $_POST['total'];
-  $adults = $_POST['adults'];
-  $children = $_POST['children'];
-  $data = array(
-    'module' => 'hotel_booking',
-    'prices' => $prices,
-    'nights' => $nights,
-    'total' => $total,
-    'adults' => $adults,
-    'children' => $children,
-  );
-
-  $redirect_destination = variable_get('hotel_booking_redirect', 'cart');
-  uc_cart_add_item($node->nid, 1, $data);
-  $cart_item_id = db_last_insert_id('{uc_cart_products}', 'cart_item_id');
-
-  if ($redirect_destination == 'cart') {
-    drupal_goto($redirect_destination);
-  }
-  elseif ($redirect_destination == 'addon') {
-    drupal_goto('booking_upgrades/'. $cart_item_id);
-  }
-  else {
-    drupal_goto(variable_get('hotel_booking_redirect_otherurl', ''));
-  }
-
-}
-
-/**
- * Implementation of hook_cart_item().
- */
-function hotel_booking_cart_item($op, &$item) {
-  switch ($op) {
-    case 'load':
-      if ($item->module == 'hotel_booking') {
-        $data = $item->data;
-        $item->price = $data['total'];
-        $item->qty = 1;
-      }
-      break;
-    case 'remove':
-      $data = unserialize($item->data);
-      if ($data['module'] == 'hotel_booking') {
-        $item->price = $data['total'];
-        $item->qty = 1;
-
-        // Fire item_removed trigger:
-        $remove['rtid'] = $item->nid;
-        $remove['nights'] = $data['nights'];
-        $remove['module'] = $data['module'];
-        ca_pull_trigger('item_removed_from_cart', $remove);
-      }
-      break;
-  }
-}
-
-/**
- * Implementation of hook_cart_item_description().
- */
-function hotel_booking_cart_item_description($item) {
-    $node = node_load($item->nid);
-    return theme('hotel_booking_room_cart_description', $node->teaser, $item->data);
-}
-
-/**
- * Default implementation of theme_hotel_booking_room_description().
- */
-function theme_hotel_booking_room_cart_description($teaser = '', $data) {
-  $content = '<div class="item-list">';
-  if ($teaser && variable_get('hotel_booking_teaser_in_cart', FALSE)) {
-    $content .= $teaser .'<br />';
-  }
-  $content .= theme('hotel_booking_night_list', $data['nights'], $data['prices'], $data['adults'], $data['children']);
-  return $content;
-}
-
-/**
- * Default implementation of theme_hotel_booking_quantity().
- */
-function theme_hotel_booking_quantity($data = array()) {
-  $output = 1;
-
-  // The commented code that follows will set the quantity to the number of adults & children.
-  // This will lead to confusion between the cart block & checkout pages. Quantities should default to one.
-  // Otherwise people will get to the checkout page and see a different quantity and think it means they are booking
-  // Multiple rooms, rather than multiple nights for multiple people in a single room.
-
-  /*
-  $adults = $data['adults'];
-  $children = $data['children'];
-  $output = '';
-  if ($adults) {
-    $output .= t('Adults').':&nbsp;'.$adults;
-  }
-  if ($children) {
-    if ($output) $output .= '<br />';
-    $output .= t('Children').':&nbsp;'.$children;
-  } */
-
-  return $output;
-}
-
-/**
- * Implementation of hook_theme().
- */
-function hotel_booking_theme() {
-  return array('hotel_booking_night_list' => array(
-      'arguments'  => array(
-        'nights'   => array(),
-        'prices'   => array(),
-        'adults'   => int,
-        'children' => int,
-        'html'     => FALSE,
-      ),
-    ),
-    'hotel_booking_room_cart_description' => array(
-      'arguments' => array(
-        'teaser'  => '',
-        'data'    => array()
-      ),
-    ),
-  );
-
-  /* 'hotel_booking_quantity' => array(
-      'arguments' => array(
-        'data'    => array()
-      ),
-    ),
-  );*/
-}
-
-/**
- * Default implementation of theme_hotel_booking_night_list().
- *
- * html argument is for order pane product list which does a check plain
- */
-function theme_hotel_booking_night_list($nights = array(), $prices = array(), $adults = 0, $children = 0, $html = TRUE, $review = FALSE) {
-    if ($adults) {
-      $occupants = $adults .' Adult';
-      if ($adults > 1) {
-        $occupants .= 's';
-      }
-    }
-    if ($children) {
-      $occupants .= ', '. $children .' Child';
-      if ($children > 1) {
-        $occupants .= 'ren';
-      }
-    }
-    if ($adults || $children) {
-      $occupants .= '<br />';
-    }
-    if (count($nights)) {
-      $i = 0;
-      foreach ($nights as $night) {
-        $date = strtotime($night);
-        $nights_formatted[] = uc_date_format(date('m', $date), date('d', $date), date('Y', $date)) .': '. uc_currency_format($prices[$i]);
-        $i++;
-      }
-      if ($review) {
-        return count($nights) .' '. t('Night Stay:') .'<ul><li>'. implode('</li><li>', $nights_formatted) . '</li><ul>';
-      }
-      if ($html) {
-        return $occupants . count($nights) .' '. t('Night Stay:') .'<ul class="product-description"><li>'. implode('</li><li>', $nights_formatted) .'</li></ul></div>';
-      }
-      else {
-        return ' ('. implode(', ', $nights_formatted) .')';
-      }
-    }
-    return;
-}
-
-/**
- * Implementation of hook_cart_display().
- */
-function hotel_booking_cart_display($item) {
-    $node = node_load($item->nid);
-    $element = array();
-    $element['nid'] = array('#type' => 'value', '#value' => $node->nid);
-    $element['module'] = array('#type' => 'value', '#value' => 'hotel_booking');
-    $element['remove'] = array('#type' => 'checkbox');
-
-    $title = check_plain($item->title);
-    $title .= ' ('. count($item->data['nights']) .t(' Nights, ');
-    $title .= format_plural($item->data['adults'], '1 Adult', '@count Adults');
-    $title .= format_plural($item->data['children'], ', 1 Child', ', @count Children');
-    $title .= ')';
-    $element['title'] = array(
-      '#value' => node_access('view', $node) ? l($title, 'node/'. $node->nid) : check_plain($item->title),
-    );
-
-    $context = array(
-      'revision' => 'altered',
-      'location' => 'cart-item',
-      'subject' => array(
-        'cart_item' => $item,
-      ),
-      'extras' => array(
-        'node' => $node,
-      ),
-    );
-    $price_info = array(
-      'price' => $item->price,
-      'qty' => $item->qty,
-    );
-
-    $element['#total'] = uc_price($price_info, $context);
-    $element['data'] = array('#type' => 'hidden', '#value' => serialize($item->data));
-    $element['qty'] = array(
-      '#type'          => 'markup',
-      '#value'         => 1,
-      '#default_value' => 1,
-    );
-
-    if (variable_get('hotel_booking_teaser_in_cart', FALSE)) {
-      $description = theme_hotel_booking_room_cart_description($node->teaser, NULL); //$item->data);
-    }
-    else {
-      $description = theme_hotel_booking_room_cart_description('', NULL); //$item->data);
-    }
-    if ($description) {
-      $element['description'] = array('#value' => $description);
-    }
-
-    return $element;
-}
-
-/**
- * Helper function to remove addon items from the cart.
- */
-function hotel_booking_remove_upgrades($data = array()) {
-  if ($data) {
-    foreach ($data as $nid => $cart_item_id) {
-      db_query('DELETE FROM {uc_cart_products} WHERE cart_item_id = %d', $cart_item_id);
-    }
-  }
-  return;
-}
-
-/**
- * Implementation of hook_update_cart_item().
- */
-function hotel_booking_update_cart_item($nid, $data = array(), $qty, $cid = NULL) {
-    if (!$nid) return NULL;
-
-  $cid = !(is_null($cid) || empty($cid)) ? $cid : uc_cart_get_id();
-  if ($qty === 0) {
-    // If the Addon module is enabled, remove all the upgrade & addon items from
-    // the cart when their parent item is deleted.
-    if (module_exists('hotel_addons_upgrades')) {
-      hotel_booking_remove_upgrades($data['booking_upgrades']);
-    }
-    uc_cart_remove_item($nid, $cid, $data);
-  }
-  else {
-    db_query("UPDATE {uc_cart_products} SET qty = %d, changed = %d WHERE nid = %d AND cart_id = '%s' AND data = '%s'", $qty, time(), $nid, $cid, serialize($data));
-  }
-
-  // Rebuild the items hash
-  uc_cart_get_contents(NULL, 'rebuild');
-}
-
-/**
- * Implementation of hook_order().
- */
-function hotel_booking_order($op, &$order) {
-  $proceed = FALSE;
-  for ($i = 0; $i < count($order->products); $i++) {
-    if ($order->products[$i]->data['module'] == 'hotel_booking') {
-      //this is a hotel booking product
-      $proceed = TRUE;
-    }
-  }
-  switch ($op) {
-    case 'load':
-      if ($proceed && variable_get('hotel_booking_reward_prompt', '')) {
-        $result = db_query('SELECT * FROM {hotel_booking_reward_memberships} WHERE order_id = %d', $order->order_id);
-        if ($data = db_fetch_object($result)) {
-          $order->reward_membership = $data->member_number;
-        }
-      }
-      break;
-    case 'save':
-      if ($proceed && variable_get('hotel_booking_reward_prompt', '')) {
-        if(!empty($order->reward_membership)) {
-          db_query('UPDATE {hotel_booking_reward_memberships} SET member_number = "%s" WHERE order_id = %d', $order->reward_membership, $order->order_id);
-          if (db_affected_rows() == 0) {
-            db_query('INSERT INTO {hotel_booking_reward_memberships} (order_id, member_number) VALUES (%d, "%s")', $order->order_id, $order->reward_membership);
-          }
-        }
-      }
-      break;
-    case 'delete':
-      db_query('DELETE FROM {hotel_booking_reward_memberships} WHERE order_id = %d', $order->order_id);
-      break;
-  }
-}
-
-
-
-function hotel_booking_alter_availability($order) {
- 
-  switch($order->order_status) {
-    case 'canceled':
-      $message = t("Processing canceled booking(s)");
-      $sign = "+";
-      break;
-    default:
-      $message = t("Processing booking(s)");
-      $sign = "-";
-  }
-  watchdog('hotel booking', $message);
-  if (is_array($order->products)) {
-    foreach ($order->products as $key => $product){
-      if ($product->data['module'] = 'hotel_booking') {
-        $nid = $product->nid;
-        $nights = $product->data['nights'];
-        if (is_array($nights)) {
-          foreach ($nights as $night) {
-            if (hotel_booking_non_zeroed_date($night)) {
-              watchdog('hotel booking',t('Room type: @model availability updated for !night', array('@model' => $product->model, '!night' => $night)));
-              db_query("UPDATE {hotel_availability_calendars} SET avail_quantity = avail_quantity %s 1 WHERE rtid = %d AND caldate = '%s'", $sign, $nid, $night);
-            }
-          }
-        }
-      }
-    }
-  }
-} // end of hotel_booking_alter_availability()
-
-
-/**
- * Check given date againt the current expiration date (according to settings). Returns true in case the given date is 
- * yet to be expired, false otherwise
- */
-function hotel_booking_non_zeroed_date($date) {
-  if (strtotime($date) > strtotime(hotel_booking_expiration_date())) {
-    return true;
-  } else {
-    return false;
-  }
-}
-
-/**
- * Helper function to get the proper expiration date. Using using cron exripation process and cancellation process
- */
-function hotel_booking_expiration_date() {
-  $expiration = variable_get('hotel_booking_expiration', 'yesterday');
-  switch ($expiration) {
-    case 'yesterday':
-      $day   = date('j', mktime(0, 0, 0, date('n'), date('j') - 1, date('y')));
-      $month = date('n', mktime(0, 0, 0, date('n'), date('j') - 1, date('y')));
-      $year  = date('Y', mktime(0, 0, 0, date('n'), date('j') - 1, date('y')));
-      break;
-    case 'today':
-      $day   = date('j', mktime(0, 0, 0, date('n'), date('j'), date('y')));
-      $month = date('n', mktime(0, 0, 0, date('n'), date('j'), date('y')));
-      $year  = date('Y', mktime(0, 0, 0, date('n'), date('j'), date('y')));
-      break;
-    case 'tomorrow':
-      $day   = date('j', mktime(0, 0, 0, date('n'), date('j') + 1, date('y')));
-      $month = date('n', mktime(0, 0, 0, date('n'), date('j') + 1, date('y')));
-      $year  = date('Y', mktime(0, 0, 0, date('n'), date('j') + 1, date('y')));
-      break;
-  }
-  return sprintf("%s-%s-%s", $year, $month, $day);
-} // end of hotel_booking_expiration_date()
-
-/**
-* Implementation of hook_ca_predicate().
-*/
-function hotel_booking_ca_predicate() {
-  // Set the order status to "Payment Received" when a payment is received
-  // and the balance is less than or equal to 0.
-  //uc_checkout_complete
-  $configurations['hotel_booking_payment_received'] = array(
-    '#title' => t('Reduce room availability status on full payment'),
-    '#description' => t('Only happens when a payment is entered and the balance is <= $0.00.'),
-    '#class' => 'payment',
-    '#trigger' => 'uc_payment_entered',
-    '#status' => 1,
-    '#conditions' => array(
-      '#operator' => 'AND',
-      '#conditions' => array(
-        array(
-          '#name' => 'uc_payment_condition_order_balance',
-          '#title' => t('If the balance is less than or equal to $0.00.'),
-          '#argument_map' => array(
-            'order' => 'order',
-          ),
-          '#settings' => array(
-            'negate' => FALSE,
-            'balance_comparison' => 'less_equal',
-          ),
-        ),
-        array(
-          '#name' => 'uc_order_status_condition',
-          '#title' => t('If the order status is not already Payment Received.'),
-          '#argument_map' => array(
-            'order' => 'order',
-          ),
-          '#settings' => array(
-            'negate' => TRUE,
-            'order_status' => 'payment_received',
-          ),
-        ),
-      ),
-    ),
-    '#actions' => array(
-      array(
-        '#name' => 'hotel_booking_reduce_availability',
-        '#title' => t('Reduce the room availability.'),
-        '#argument_map' => array(
-          'order' => 'order',
-        ),
-        '#settings' => array(
-          'order_status' => 'payment_received',
-        ),
-      ),
-    ),
-  );
-
-  $configurations['hotel_booking_checkout_complete'] = array(
-    '#title' => t('Reduce room availability status on checkout with full payment'),
-    '#description' => t('Only happens when checkout occurs and a payment is entered and the balance is <= $0.00.'),
-    '#class' => 'payment',
-    '#trigger' => 'uc_checkout_complete',
-    '#status' => 0,
-    '#conditions' => array(
-      '#operator' => 'AND',
-      '#conditions' => array(
-        array(
-          '#name' => 'uc_payment_condition_order_balance',
-          '#title' => t('If the balance is less than or equal to $0.00.'),
-          '#argument_map' => array(
-            'order' => 'order',
-          ),
-          '#settings' => array(
-            'negate' => FALSE,
-            'balance_comparison' => 'less_equal',
-          ),
-        ),
-      ),
-    ),
-    '#actions' => array(
-      array(
-        '#name' => 'hotel_booking_reduce_availability',
-        '#title' => t('Reduce the room availability.'),
-        '#argument_map' => array(
-          'order' => 'order',
-        ),
-        '#settings' => array(
-          'order_status' => 'completed',
-        ),
-      ),
-    ),
-  );
-
-  // Set increase availability in case of cancellation
-  $configurations['hotel_booking_order_cancelled'] = array(
-    '#title' => t('Increase room availability on order cancellation.'),
-    '#description' => t('When order is cancelled, room availability should be increased.'),
-    '#class' => 'payment',
-    '#trigger' => 'uc_order_status_update',
-    '#status' => 1,
-    '#conditions' => array(
-      '#operator' => 'AND',
-      '#conditions' => array(
-        array(
-          '#name' => 'uc_order_status_condition',
-          '#title' => t('If the order status is cancelled'),
-          '#argument_map' => array(
-            'order' => 'updated_order',
-          ),
-          '#settings' => array(
-            'order_status' => 'canceled',
-          ),
-        ),
-      ),
-    ),
-    '#actions' => array(
-      array(
-        '#name' => 'hotel_booking_increase_availability',
-        '#title' => t('Increase the room availability.'),
-        '#argument_map' => array(
-          'order' => 'updated_order',
-        ),
-      ),
-    ),
-  );
-
-  return $configurations;
-}
-
-/**
- * Implementation of hook_ca_action().
- */
-function hotel_booking_ca_action() {
-  $order_arg = array(
-    '#entity' => 'uc_order',
-    '#title' => t('Order'),
-  );
-
-  $actions['hotel_booking_reduce_availability'] = array(
-    '#title' => t('Reduce the availability of rooms'),
-    '#category' => t('Order'),
-    '#callback' => 'hotel_booking_alter_availability',
-    '#arguments' => array(
-      'order' => $order_arg,
-    ),
-  );
-  $actions['hotel_booking_increase_availability'] = array(
-    '#title' => t('Increase the availability of rooms'),
-    '#category' => t('Order'),
-    '#callback' => 'hotel_booking_alter_availability',
-    '#arguments' => array(
-      'order' => $order_arg,
-    ),
-  );
-
-  return $actions;
-}
-
-
-/**
- * Helper function to determine if there is a booking item in the cart.
- */
-function _booking_item_in_cart() {
-  $items = uc_cart_get_contents();
-  foreach ($items as $item) {
-    if ($item->data['module'] == 'hotel_booking') {
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-
-
-
-/**
- * ----------------------------------------
- * Cart, Checkout, and Order Pane functions
- * ----------------------------------------
- */
-
-
-/**
- * Implementation of hook_cart_pane().
- */
-function hotel_booking_cart_pane() {
-  if (_booking_item_in_cart()) {
-    $panes[] = array(
-      'id' => 'booking_details',
-      'title' => t('Booking Details'),
-      'weight' => -15,
-      'body' => drupal_get_form('hotel_booking_details_pane_cart'),
-      'collapsible' => TRUE,
-      'collapsed'   => FALSE,
-    );
-    return $panes;
-  }
-  else {
-    return;
-  }
-}
-
-
-/**
- * Implementation of hook_checkout_pane().
- */
-function hotel_booking_checkout_pane() {
-  if (_booking_item_in_cart()) {
-    if (variable_get('hotel_booking_reward_prompt', '')) {
-      $panes[] = array(
-        'id'          => 'reward_membership',
-        'callback'    => 'hotel_booking_rewards',
-        'title'       => t('Reward Membership'),
-        'weight'      => 6,
-        'enabled'     => TRUE,
-        'process'     => TRUE,
-        'collapsible' => FALSE,
-      );
-    }
-    $panes[] = array(
-      'id'            => 'booking_details',
-      'callback'      => 'hotel_booking_details_pane_checkout',
-      'title'         => t('Booking Details'),
-      'weight'        => -8,
-      'enabled'       => TRUE,
-      'collapsible'   => TRUE,
-      'process'       => TRUE,
-    );
-    return $panes;
-  }
-  else {
-    return;
-  }
-}
-
-
-
-
-/**
- * Implementation of hook_order_pane().
- */
-function hotel_booking_order_pane() {
-  $panes[] = array(
-      'id' => 'hotel_booking',
-      'callback' => 'hotel_booking_booking_pane',
-      'title' => t('Booking Details'),
-      'desc' => t('Display details of room bookings.'),
-      'class' => 'abs-left',
-      'weight' => 5,
-      'show' => array('view', 'customer'),
-    );
-    if (variable_get('hotel_booking_reward_prompt', '')) {
-      $panes[] = array(
-        'id' => 'reward_membership',
-        'callback' => 'hotel_booking_pane_rewards',
-        'title' => t('Reward Membership'),
-        'weight' => 5,
-        'show' => array('view', 'customer'),
-      );
-    }
-  return $panes;
-}
-
-
-/**
- * Callbacks for order pane
- */
-function hotel_booking_booking_pane($op, $order) {
-  $proceed = FALSE;
-  for ($i = 0; $i < count($order->products); $i++) {
-    if ($order->products[$i]->data['module'] == 'hotel_booking') {
-      //this is a hotel booking product
-      $proceed = TRUE;
-    }
-  }
-  switch ($op) {
-    case 'view':
-    case 'customer':
-      if ($proceed) {
-        return drupal_get_form('hotel_booking_details_pane_order', $order->products, $order->as_template);
-      }
-      else {
-        break;
-      }
-  }
-}
-
-function hotel_booking_pane_rewards($op, $order) {
-  switch ($op) {
-    case 'view':
-    case 'customer':
-      if (!empty($order->reward_membership)) {
-        $reward_number = $order->reward_membership;
-        return t('Reward Membership Number: @reward', array('@reward' => $reward_number));
-      }
-      else {
-        break;
-      }
-  }
-}
-
-
-
-/**
- * Functions to build fieldsets & tables for order pane
- * @param $form_state array std drupal FAPI form state var
- * @param $products array array of products as per $order->products
- * @param $as_template bool whether pane is being displayed in a template (ie printed invoice, emailed)
- */
-function hotel_booking_details_pane_order($form_state, $products, $as_template) {
-  foreach ($products as $product) {
-    if ($product->data['module'] == 'hotel_booking') {
-      $numnights[$product->order_product_id] = count($product->data['nights']);
-    }
-  }
-
-  foreach ($products as $product) {
-    if ($product->data['module'] == 'hotel_booking') {
-      $title = check_plain($item->title);
-      $title .= ' ('. count($item->data['nights']) .t(' Nights, ');
-      $title .= format_plural($item->data['adults'], '1 Adult', '@count Adults');
-      $title .= format_plural($item->data['children'], ', 1 Child', ', @count Children');
-      $title .= ')';
-      $foo = node_load($product->nid);
-      $desc = (variable_get('hotel_booking_teaser_in_panes','FALSE')) ? '' : $foo->teaser;
-      $desc .= '<div class="booking_details_blurb"><p>'. t('The following table breaks down your stay by day, listing price per night of the room');
-      $desc .= ($product->data['booking_upgrades']) ? ', '. t('along with any applicable date based Add-On items.</p><p>Other Add-On items apply to your entire stay.') .'</p>' : '.</p>';
-      $desc .= '</div>';
-      $contents['booking_details'][$product->order_product_id] = array(
-        '#type' => 'fieldset',
-        '#title' => $title,
-        '#description' => $desc,
-        '#collapsible' => TRUE,
-        // Default to collapsed if there are multiple room booking items in the cart,
-        // or the booking has more than three nights and more than two addons, or if
-        // the a single booking item has more than 5 nights.
-        '#collapsed' => (sizeof($numnights) > 1 || (count($product->data['nights']) > 3 && sizeof($product->data['booking_upgrades']) > 2) || (count($product->data['nights']) > 5)) ? TRUE : FALSE,
-      );
-      $val = hotel_booking_order_details_table($product, $products, FALSE, $as_template);
-      $contents['booking_details'][$product->order_product_id]['nid'] = array(
-        '#value' => $val[0],
-      );
-      if ($val[1]) {
-        $contents['booking_details'][$product->order_product_id]['nid']['additional'] = array(
-          '#value' => hotel_booking_order_details_table($product, $products, TRUE, $as_template),
-        );
-      }
-    }
-  }
-  return array('contents' => $contents);
-}
-
-/**
- * Utility, provides a table in the booking panes
- * @param $item object the product item
- * @param $products array all products in the cart
- * @param $additional bool whether the table is for additional items
- * @param $as_template bool whether the table is being displayed in an invoice template (printed/email)
- *                          and as such, needs to include style tags
-*/
-function hotel_booking_order_details_table(&$item, $products, $additional = FALSE, $as_template = FALSE) {
-  $addons = $table_attributes = array();
-  if ($as_template) {
-    $table_attributes = array('width' => '100%', 'style' => 'font-family: verdana, arial, helvetica; font-size: small;');
-  }
-  if ($item->data['booking_upgrades_order']) {
-    foreach ($item->data['booking_upgrades_order'] as $nid => $child_id) {
-      for ($i = 0; $i < count($products); $i++) {
-        if ($products[$i]->nid == $nid && $products[$i]->data['child_id'] == $child_id) {
-          $addons[$products[$i]->nid]['order'] = $products[$i];
-          $addons[$products[$i]->nid]['data'] = $products[$i]->data;
-          $addons[$products[$i]->nid]['daily'] = ($addons[$products[$i]->nid]['data']['days']) ? TRUE : FALSE;
-          if (!$additional_items) {
-            $additional_items = (!$addons[$products[$i]->nid]['daily']) ? TRUE : FALSE;
-          }
-          if (!$daily_items) {
-            $daily_items = ($addons[$products[$i]->nid]['daily']) ? TRUE : FALSE;
-          }
-        }
-      }
-    }
-  }
-  if (!$additional) {
-    if ($addons && $daily_items) {
-      $addon_title = t('Date Based Add-On Items');
-      $qtys = t('Qty.');
-    }
-    $header = array(t('Dates'), array('data' => $addon_title, 'width' => '45%'), array('data' => t(''), 'colspan' => 2), $qtys, t('Total'));
-    for ($i = 0; $i < sizeof($item->data['nights']); $i++) {
-      $checkin = ($i == 0) ? t('Check-In') : '';
-      $thisday = $item->data['nights'][$i];
-      $foo = explode('-', $thisday);
-      $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2], $foo[0]));
-      $rows[] = array($today, '',  t('Night !night', array('!night' => ($i + 1))), $checkin, '', array('data' => '$'. $item->data['prices'][$i], 'class' => 'price'));
-      foreach ($addons as $nid => $info) {
-        if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
-          $rows[] = array('', l($addons[$nid]['order']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => '$' . number_format(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['order']->price), 2, '.', ','), 'class' => 'price'));
-        }
-      }
-    }
-    $thisday = date('Y-m-d', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
-    $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
-    $rows[] = array($today, '', '', t('Check-Out'), '', '');
-    foreach ($addons as $nid => $info) {
-      if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
-        $rows[] = array('', l($addons[$nid]['order']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => '$' . number_format(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['order']->price), 2, '.', ','), 'class' => 'price'));
-      }
-    }
-
-    $table = theme('table', $header, $rows, $table_attributes);
-    if ($additional_items) {
-    }
-    return array($table, $additional_items);
-  }
-  else {
-    $header = array(array('data' => t('Additional Add-On & Upgrade Items'), 'colspan' => 2, 'width' => '100%'), 'data' => t('Total'));
-    foreach ($addons as $nid => $info) {
-      if (!$addons[$nid]['daily']) {
-        $rows[] = array($addons[$nid]['order']->qty .'x', array('data' => l($addons[$nid]['order']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']), 'width' => '100%'), array('data' => '$' . number_format(($addons[$nid]['order']->qty * $addons[$nid]['order']->price), 2, '.', ','), 'class' => 'price'));
-      }
-    }
-
-    return theme('table', $header, $rows, $table_attributes);
-  }
-}
-
-
-/**
- * Functions to build fieldsets & tables for cart pane
- */
-
-function hotel_booking_details_pane_cart() {
-  $items = uc_cart_get_contents();
-  foreach ($items as $item) {
-    if ($item->module == 'hotel_booking') {
-      $numnights[$item->cart_item_id] = count($item->data['nights']);
-    }
-  }
-
-  $contents['booking_details'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Booking Details'),
-      '#description' => (sizeof($numnights) > 1) ? t('Click on the Room Types below to view your booking details.') : '',
-      '#collapsible' => TRUE,
-      '#collapsed'   => FALSE,
-  );
-
-  foreach ($items as $item) {
-    if ($item->module == 'hotel_booking') {
-      $title = t('@title', array('@title' => $item->title));
-      $title .= ' ('. count($item->data['nights']);
-      $title .= (count($item->data['nights']) > 1) ? t(' Nights, ') : t(' Night, ');
-      $title .= ($item->data['adults'] > 1) ? $item->data['adults'] .t(' Adults') : $item->data['adults'] .t(' Adult');
-      if ($item->data['children']) {
-        $title .= ($item->data['children'] > 1) ? ', '. $item->data['children'] .t(' Children') : ', '. $item->data['children'] .t(' Child');
-      }
-      $title .= ')';
-      $foo = node_load($item->nid);
-
-      $desc = (variable_get('hotel_booking_teaser_in_panes','FALSE')) ? $foo->teaser : '';
-      $desc .= '<div class="booking_details_blurb"><p>The following table breaks down your stay by day, listing price per night of the room';
-      $desc .= ($item->data['booking_upgrades']) ? ', along with any applicable date based Add-On items.</p><p>Other Add-On items apply to your entire stay.</p>' : '.</p>';
-      if (substr(drupal_get_destination(), -8, 8) != 'checkout') {
-        $desc .= (is_array($item->data['booking_upgrades'])) ? '<p>'. l('Edit Addons & Upgrades', 'booking_upgrades/'. $item->cart_item_id) .'</p></div>' : '</div>';
-      }
-      else {
-        $desc .= '</div>';
-      }
-      $contents['booking_details'][$item->cart_item_id] = array(
-        '#type' => 'fieldset',
-        '#title' => $title,
-        '#description' => $desc,
-        '#collapsible' => TRUE,
-        // Default to collapsed if there are multiple room booking items in the cart,
-        // or the booking has more than three nights and more than two addons, or if
-        // the a single booking item has more than 5 nights.
-        '#collapsed' => (sizeof($numnights) > 1 || ($numnights[$item->cart_item_id] > 3 && sizeof($item->data['booking_upgrades']) > 2) || ($numnights[$item->cart_item_id] > 5)) ? TRUE : FALSE,
-      );
-      $val = hotel_booking_cart_details_table($item);
-      $contents['booking_details'][$item->cart_item_id]['nid'] = array(
-        '#value' => $val[0],
-      );
-      if ($val[1]) {
-        $contents['booking_details'][$item->cart_item_id]['nid']['additional'] = array(
-          '#value' => hotel_booking_cart_details_table($item, TRUE),
-        );
-      }
-    }
-  }
-  return array('contents' => $contents);
-}
-
-
-
-/**
- * Callbacks for checkout pane
- */
-function hotel_booking_rewards($op, &$order, $newvalue) {
-  switch ($op) {
-    case 'view':
-      $description = t('If you have a reward membership card, please enter the number here.');
-      $contents['reward_membership'] = array(
-        '#type'          => 'textfield',
-        '#title'         => variable_get('hotel_booking_reward_prompt', ''),
-        '#default_value' => ($order->reward_membership) ? $order->reward_membership : '',
-      );
-      return array('description' => $description, 'contents' => $contents);
-    case 'process':
-      $order->reward_membership = $newvalue['reward_membership'];
-      return TRUE;
-    case 'review':
-      $review = ($order->reward_membership) ? $order->reward_membership : NULL;
-      return $review;
-  }
-}
-
-function hotel_booking_details_pane_checkout($op, &$order, $arg2) {
-  switch ($op) {
-    case 'view':
-      $contents = array();
-
-      $items = uc_cart_get_contents();
-      foreach ($items as $item) {
-        if ($item->module == 'hotel_booking') {
-          $numnights[$item->cart_item_id] = count($item->data['nights']);
-        }
-      }
-
-      foreach ($items as $item) {
-        if ($item->module == 'hotel_booking') {
-          $title = check_plain($item->title);
-          $title .= ' ('. count($item->data['nights']) .t(' Nights, ');
-          $title .= format_plural($item->data['adults'], '1 Adult', '@count Adults');
-          $title .= format_plural($item->data['children'], ', 1 Child', ', @count Children');
-          $title .= ')';
-          $foo = node_load($item->nid);
-
-          $desc = (variable_get('hotel_booking_teaser_in_panes','FALSE')) ? $foo->teaser : '';
-          $desc .= '<div class="booking_details_blurb"><p>The following table breaks down your stay by day, listing price per night of the room';
-          $desc .= ($item->data['booking_upgrades']) ? ', along with any applicable date based Add-On items.</p><p>Other Add-On items apply to your entire stay.</p>' : '.</p>';
-          if (substr(drupal_get_destination(), -8, 8) != 'checkout') {
-            $desc .= (is_array($item->data['booking_upgrades'])) ? '<p>'. l('Edit Addons & Upgrades', 'booking_upgrades/'. $item->cart_item_id) .'</p></div>' : '</div>';
-          }
-          else {
-            $desc .= '</div>';
-          }
-          $contents['booking_details'][$item->cart_item_id] = array(
-            '#type' => 'fieldset',
-            '#title' => $title,
-            '#description' => $desc,
-            '#collapsible' => TRUE,
-            // Default to collapsed if there are multiple room booking items in the cart,
-            // or the booking has more than three nights and more than two addons, or if
-            // the a single booking item has more than 5 nights.
-            '#collapsed' => (sizeof($numnights) > 1 || ($numnights[$item->cart_item_id] > 3 && sizeof($item->data['booking_upgrades']) > 2) || ($numnights[$item->cart_item_id] > 5)) ? TRUE : FALSE,
-          );
-          $val = hotel_booking_cart_details_table($item);
-          $contents['booking_details'][$item->cart_item_id]['nid'] = array(
-            '#value' => $val[0],
-          );
-          if ($val[1]) {
-            $contents['booking_details'][$item->cart_item_id]['nid']['additional'] = array(
-              '#value' => hotel_booking_cart_details_table($item, TRUE),
-            );
-          }
-        }
-      }
-      return array('contents' => $contents);
-  }
-}
-
-function hotel_booking_cart_details_table(&$item, $additional = FALSE) {
-  $addons = array();
-  if ($item->data['booking_upgrades']) {
-    foreach($item->data['booking_upgrades'] as $nid => $cart_item_id) {
-      $addons[$nid]['cart'] = db_fetch_array(db_query('SELECT * FROM {uc_cart_products} WHERE cart_item_id = %d', $cart_item_id));
-      $addons[$nid]['data'] = unserialize($addons[$nid]['cart']['data']);
-      $addons[$nid]['daily'] = ($addons[$nid]['data']['days']) ? TRUE : FALSE;
-      if (!$additional_items) {
-        $additional_items = (!$addons[$nid]['daily']) ? TRUE : FALSE;
-      }
-      if (!$daily_items) {
-        $daily_items = ($addons[$nid]['daily']) ? TRUE : FALSE;
-      }
-
-      // For the first time running through this function ($additional = FALSE)
-      // If the item is not a daily addon item, we just won't pay it any mind.
-      if (!$additional && $addons[$nid]['daily']) {
-        $addons[$nid]['node'] = node_load($nid);
-      }
-
-      // If we're coming around a second time for non-daily items don't do
-      // a node load on those daily items.
-      elseif ($additional && !$addons[$nid]['daily']) {
-        $addons[$nid]['node'] = node_load($nid);
-      }
-    }
-  }
-  if (!$additional) {
-    if ($addons && $daily_items) {
-      $addon_title = t('Date Based Add-On Items');
-      $qtys = t('Qty.');
-    }
-    $header = array(t('Dates'), array('data' => $addon_title, 'width' => '45%'), array('data' => t(''), 'colspan' => 2), $qtys, t('Total'));
-    for ($i = 0; $i < sizeof($item->data['nights']); $i++) {
-      $checkin = ($i == 0) ? t('Check-In') : '';
-      $thisday = $item->data['nights'][$i];
-      $foo = explode('-', $thisday);
-      $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2], $foo[0]));
-      $rows[] = array($today, '',  t('Night !night', array('!night' => ($i + 1))), $checkin, '', array('data' => '$'. $item->data['prices'][$i], 'class' => 'price'));
-      foreach ($addons as $nid => $info) {
-        if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
-          $rows[] = array('', l($addons[$nid]['node']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => '$' . number_format(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['node']->sell_price), 2, '.', ','), 'class' => 'price'));
-        }
-      }
-    }
-    $thisday = date('Y-m-d', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
-    $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
-    $rows[] = array($today, '', '', t('Check-Out'), '', '');
-    foreach ($addons as $nid => $info) {
-      if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
-        $rows[] = array('', l($addons[$nid]['node']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => '$' . number_format(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['node']->sell_price), 2, '.', ','), 'class' => 'price'));
-      }
-    }
-
-    $table = theme('table', $header, $rows);
-    if ($additional_items) {
-    }
-    return array($table, $additional_items);
-  }
-  else {
-    $header = array(array('data' => t('Additional Add-On & Upgrade Items'), 'colspan' => 2, 'width' => '100%'), 'data' => t('Total'));
-    foreach ($addons as $nid => $info) {
-      if (!$addons[$nid]['daily']) {
-        $rows[] = array($addons[$nid]['cart']['qty'] .'x', array('data' => l($addons[$nid]['node']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']), 'width' => '100%'), array('data' => '$' . number_format(($addons[$nid]['cart']['qty'] * $addons[$nid]['node']->sell_price), 2, '.', ','), 'class' => 'price'));
-      }
-    }
-    return theme('table', $header, $rows);
-  }
-}
-
-
-function hotel_booking_pad_with_zeros($s, $n) {
-  return sprintf("%0". $n ."d", $s);
-}
-
-/**
-* Implements hook_token_list().
-* Provides tokens for hotel booking pane and check in/out dates
-* @author larowlan leerowlands at rowlands-bcs.com
-*/
-function hotel_booking_token_list($type = 'site') {
-  $tokens = array();
-  if ($type == 'order' || $type == 'all') {
-
-    $tokens['order']['bookings-pane'] = t('Hotel bookings pane');
-    $tokens['order']['check-out-date'] = t('Check out date (latest if more than one');
-    $tokens['order']['check-in-date'] = t('Check in date (earliest if more than one');
-    
-  }
-
-  return $tokens;
-  
-}
-
-
-/**
-* Implements hook_token_values().
-* Evaluate the token values
-* @author larowlan leerowlands at rowlands-bcs.com
-*/
-function hotel_booking_token_values($type, $object = NULL, $options = array()) {
-  $tokens = array();
- 
-  if ($type == 'order') {   
-    $order = $object;
-    $order->as_template = TRUE; //notify booking pane that this item is being shown in a template
-        
-    $tokens['bookings-pane'] = hotel_booking_booking_pane('customer', $order);
-    $tokens['check-in-date'] = NULL;
-    $tokens['check-out-date'] = NULL;
-    
-    $dates_exist = FALSE;
-    if ($order->products && is_array($order->products)) {
-      $first = TRUE;
-      $first_check_in = $last_check_out = FALSE;
-      foreach ($order->products as $product) {
-        if ($product->data['module'] == 'hotel_booking') {
-          list($check_in, $check_out) = _hotel_booking_check_in_out($product->data['nights']);
-          //have we had 1 pass yet?
-          if ($first) {
-            $first_check_in = $check_in;
-            $last_check_out = $check_out;
-            $first = FALSE;
-            $dates_exist = TRUE;
-            continue; //next loop
-          }
-          if ($last_check_out->getTimestamp() < $check_out->getTimestamp()) {
-            //this check out is later
-            $last_check_out = $check_out;
-          }
-          if ($first_check_in->getTimestamp() > $check_in->getTimestamp()) {
-            //this check in is eariler
-            $first_check_in = $check_in;
-          }
-        }
-      }
-    }
-    if ($dates_exist) {
-      $format = variable_get('uc_date_format_default', 'd M Y');
-      $tokens['check-in-date'] = $first_check_in->format($format);
-      $tokens['check-out-date'] = $last_check_out->format($format);
-    }
-  }
-  
-  return $tokens;
-}
-
-
-/**
- * Utility function to fetch check in night and check out night
- * @param $nights array array of nights as per product->data['nights'] in cart and order products
- * @return array($check_in, $check_out)
- * @author larowlan leerowlands at rowlands-bcs.com
-*/
-function _hotel_booking_check_in_out($nights) {
-  $check_in = date_make_date($nights[0], NULL, DATE_ISO);
-  $last_night = date_make_date($nights[count($nights) - 1], NULL, DATE_ISO);
-  $last_night->modify('+ 1 day'); //check out is day after last night
-  return array($check_in, $last_night);
+<?php
+// $Id: hotel_booking.module,v 1.19 2010/05/15 03:15:09 larowlan Exp $
+
+/**
+ * Ubercart Hotel Booking module.
+ *
+ * @file
+ * Provides a hotel room type node type that pricing and availability information can be tied to.
+ * Originally based on Availability Calendars module by Dan Karran (geodaniel).
+ * @author Will Vincent (tcindie) <tcindie at gmail dot com>
+ */
+
+
+
+/**
+ * Implementation of hook_perm().
+ */
+function hotel_booking_perm() {
+  return array('edit hotel room availability', 'administer hotel booking settings', 'view hotel search results');
+}
+
+function hotel_booking_can_edit() {
+      return user_access('edit hotel room availability');
+}
+
+function hotel_search_can_view() {
+      return user_access('view hotel search results');
+}
+
+
+
+/**
+ * Implementation of hook_menu().
+ */
+function hotel_booking_menu() {
+  $items = array();
+
+  $items['admin/store/hotel_booking'] = array(
+    'title'            => 'Hotel Booking',
+    'description'      => t('Administer Hotel Booking settings, configure base rate(s), rate and occupancy modifiers, and add-on/upgrade products.'),
+    'page callback'    => 'hotel_booking_show_rates',
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_NORMAL_ITEM,
+    'file'             => 'hotel_booking_admin.inc',
+  );
+  $items['admin/store/hotel_booking/rates'] = array(
+    'title'            => 'Base Rates',
+    'page callback'    => 'hotel_booking_show_rates',
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_DEFAULT_LOCAL_TASK,
+    'weight'           => 0,
+    'file'             => 'hotel_booking_admin.inc',
+  );
+  $items['admin/store/hotel_booking/rates/add'] = array(
+    'title'            => 'Add Rate',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_rates_form'),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/rates/%'] = array(
+    'title'            => 'View Rate',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_rates_form', 4),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/rates/%/delete'] = array(
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_rates_delete_form', 4),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/rate_modifiers'] = array(
+    'title'            => 'Rate Modifiers',
+    'page callback'    => 'hotel_booking_show_rate_modifiers',
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_LOCAL_TASK,
+    'weight'           => 1,
+    'file'             => 'hotel_booking_admin.inc',
+  );
+  $items['admin/store/hotel_booking/rate_modifiers/add'] = array(
+    'title'            => 'Add Rate',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_rate_modifiers_form'),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/rate_modifiers/%'] = array(
+    'title'            => 'View Rate',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_rate_modifiers_form', 4),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/rate_modifiers/%/delete'] = array(
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_rate_modifiers_delete_form', 4),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/occupancy_modifiers'] = array(
+    'title'            => 'Occupancy Modifiers',
+    'page callback'    => 'hotel_booking_show_occupancy_modifiers',
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_LOCAL_TASK,
+    'weight'           => 2,
+    'file'             => 'hotel_booking_admin.inc',
+  );
+  $items['admin/store/hotel_booking/occupancy_modifiers/add'] = array(
+    'title'            => 'Add Occupancy Modifier',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_occupancy_modifiers_form'),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/occupancy_modifiers/%'] = array(
+    'title'            => 'View Occupancy Modifier',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_occupancy_modifiers_form', 4),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/occupancy_modifiers/%/delete'] = array(
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_occupancy_modifiers_delete_form', 4),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'hotel_booking_admin.inc'
+  );
+  $items['admin/store/hotel_booking/hotel_settings'] = array(
+    'title'            => 'Settings',
+    'description'      => 'Configure global settings for Hotel Booking module.',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hotel_booking_admin_settings'),
+    'access arguments' => array('administer hotel booking settings'),
+    'type'             => MENU_LOCAL_TASK,
+    'weight'           => 4,
+    'file'             => 'hotel_booking_admin.inc',
+  );
+  $items['room_search/%'] = array(
+    'title'           => 'Hotel Room Search Results',
+    'page callback'   => 'hotel_search_view',
+    'page arguments'  => array(1),
+    'access callback' => 'hotel_search_can_view',
+    'type'            => MENU_CALLBACK,
+  );
+  $items['room_search/book_room'] = array(
+    'title'           => '',
+    'page callback'   => 'hotel_book_room',
+    'access callback' => 'hotel_search_can_view',
+    'type'            => MENU_CALLBACK,
+  );
+
+  return $items;
+}
+
+
+
+function hotel_booking_get_rates() {
+  $result = db_query("SELECT * FROM {hotel_rate_types}");
+  $rate_list = array();
+  while ($row = db_fetch_object($result)) {
+    $rate_list[$row->hrid] = $row;
+  }
+  return $rate_list;
+}
+
+
+function hotel_booking_get_rate_modifiers() {
+  $result = db_query("SELECT * FROM {hotel_rate_modifiers} ORDER BY method DESC, value ASC");
+  $modifiers = array();
+  while ($row = db_fetch_object($result)) {
+    $modifiers[$row->hrmid] = $row;
+  }
+  return $modifiers;
+}
+
+
+function hotel_booking_get_occupancy_modifiers() {
+  $result = db_query("SELECT * FROM {hotel_occupancy_modifiers} ORDER BY adult_child ASC, threshold ASC, value ASC");
+  $modifiers = array();
+  while ($row = db_fetch_object($result)) {
+    $modifiers[$row->hoid] = $row;
+  }
+  return $modifiers;
+}
+
+
+/**
+ * Implementation of hook_block().
+ */
+function hotel_booking_block($op = 'list', $delta = 0, $edit = array()) {
+  switch ($op) {
+    case 'list':
+
+      $blocks[0] = array(
+        'info'       => t('Hotel Booking: Search Widget'),
+      );
+      return $blocks;
+
+
+    case 'configure':
+
+      $form = array();
+
+      // Build list of room types
+      $room_types[0] = t('None');
+      $results = db_query('SELECT hrt.nid, n.title FROM {hotel_room_types} AS hrt, {node} AS n WHERE n.nid = hrt.nid');
+      while ($result = db_fetch_array($results)) {
+        $room_types['node/'. $result['nid']] = check_plain($result['title']);
+      }
+
+      $form['best_rate_link'] = array(
+        '#type'          => 'select',
+        '#title'         => t('Room with best rate'),
+        '#default_value' => variable_get('hotel_booking_best_rate', '0'),
+        '#options'       => $room_types,
+        '#description'   => t("Select the room type with the best rate to display a link to it in the search block, if no room type is selected, the link will not be displayed."),
+      );
+      $form['search_children'] = array(
+        '#type'          => 'select',
+        '#title'         => t('Children Selection'),
+        '#default_value' => variable_get('hotel_booking_block_children', '1'),
+        '#options'       => array(0 => 'No', 1 => 'Yes'),
+        '#description'   => t('Select whether or not to display the children selection option in search block. Value will be 0 for searches if No is selected here.'),
+      );
+      $form['search_smoking'] = array(
+        '#type'          => 'select',
+        '#title'         => t('Smoking Preference Selection'),
+        '#default_value' => variable_get('hotel_booking_block_smoking', '1'),
+        '#options'       => array(0 => 'No', 1 => 'Yes'),
+        '#description'   => t('Select whether or not to display the smoking preference selection option in search block. Value will be No Preference if No is selected here.'),
+      );
+
+      return $form;
+
+
+    case 'save':
+      variable_set('hotel_booking_best_rate', $edit['best_rate_link']);
+      variable_set('hotel_booking_block_children', $edit['search_children']);
+      variable_set('hotel_booking_block_smoking', $edit['search_smoking']);
+
+      return;
+
+
+    case 'view': default:
+      drupal_add_css(drupal_get_path('module', 'hotel_booking') .'/css/hotel_block.css');
+      $block['subject'] = t('Room Search');
+      $block['content'] = drupal_get_form('hotel_booking_widget_form');
+      return $block;
+  }
+}
+
+
+
+
+/**
+ * hotel booking widget block content.
+ */
+function hotel_booking_widget_form() {
+  if (variable_get('hotel_booking_best_rate', '')) {
+    $form['roomsearch']['link'] = array(
+      '#prefix' => '<div class="bking-best-rate">',
+      '#value'  => l(t('View Availability of Best Room Rate'), variable_get('hotel_booking_best_rate', '')),
+      '#suffix' => '</div>',
+    );
+  }
+
+  $form['roomsearch']['checkin'] = array(
+    '#prefix' => '<div class="bking-date">',
+    '#type' => 'date_popup',
+    '#title' => t('Check-In Date'),
+    '#required' => TRUE,
+    '#size' => 14,
+    '#date_type' => DATE_ISO,
+    '#date_timezone' => date_default_timezone_name(),
+    '#date_format' => 'm/d/Y',
+    '#date_year_range' => '-0:+1',
+    '#suffix' => '</div>',
+  );
+  $form['roomsearch']['staylength'] = array(
+    '#prefix' => '<div class="bking-stay-length">',
+    '#type' => 'select',
+    '#title' => t('Nights'),
+    '#options' => array(
+        '1' => '1',
+        '2' => '2',
+        '3' => '3',
+        '4' => '4',
+        '5' => '5',
+        '6' => '6',
+        '7' => '7',
+        '8' => '8',
+        '9' => '9',
+        '10' => '10',
+        '11' => '11',
+        '12' => '12',
+        '13' => '13',
+        '14' => '14',
+      ),
+    '#default_value' => 1,
+    '#suffix' => '</div>',
+  );
+  $form['roomsearch']['adults'] = array(
+    '#prefix' => '<div class="bking-adults">',
+    '#type' => 'select',
+    '#title' => t('Adults'),
+    '#options' => array(
+        '1' => '1',
+        '2' => '2',
+        '3' => '3',
+        '4' => '4',
+        '5' => '5',
+        '6' => '6',
+        '7' => '7',
+        '8' => '8',
+      ),
+    '#default_value' => 1,
+    '#suffix' => '</div>',
+  );
+  if (variable_get('hotel_booking_block_children', 1)) {
+    $form['roomsearch']['children'] = array(
+      '#prefix' => '<div class="bking-children">',
+      '#type' => 'select',
+      '#title' => t('Children'),
+      '#options' => range(0, 8),
+      '#suffix' => '</div>',
+    );
+  }
+  else {
+    $form['roomsearch']['children'] = array(
+      '#type' => 'hidden',
+      '#value' => 0,
+    );
+  }
+  if (variable_get('hotel_booking_block_smoking', 1)) {
+    $form['roomsearch']['smoking'] = array(
+      '#prefix' => '<div class="bking-smoking">',
+      '#type' => 'select',
+      '#title' => t('Preference'),
+      '#options' => array(
+        '1' => t('Non-Smoking'),
+        '2' => t('Smoking'),
+        '3' => t('No Preference'),
+      ),
+      '#default_value' => 1,
+      '#suffix' => '</div>',
+    );
+  }
+  else {
+    $form['roomsearch']['smoking'] = array(
+      '#type' => 'hidden',
+      '#value' => 3,
+    );
+  }
+
+  $form['roomsearch']['submit'] = array(
+    '#prefix' => '<div class="bking-submit">',
+    '#type'   => 'submit',
+    '#title'  => t('Search'),
+    '#value'  => t('Search Rooms'),
+    '#suffix' => '</div>',
+  );
+  return $form;
+}
+
+
+
+function hotel_booking_widget_form_submit($form, $form_state) {
+  // $adults = number of adults
+  $adults = $form_state['values']['adults'];
+
+  // $children = number of children
+  $children = $form_state['values']['children'];
+
+  // Smoking Preference:
+  // 0 = Non Smoking
+  // 1 = Smoking
+  // 2 = No Preference
+  $smoking = $form_state['values']['smoking']-1;
+
+  // $checkin = Check In Date in the format YYYY-MM-DD
+  $foo = explode(" ", $form_state['values']['checkin']);
+  $checkin = $foo[0];
+
+  // $nights = number of nights
+  $nights = $form_state['values']['staylength'];
+
+  // Combine all of the above into arguments separated by underscores
+  $args = $checkin .'_'. $nights .'_'. $adults .'_'. $children .'_'. $smoking;
+
+  drupal_goto("room_search/". $args);
+}
+
+
+
+function hotel_search_view($args) {
+
+  $values = explode("_", $args);
+
+  $checkin = $values[0];
+  $nights = $values[1];
+  $adults = $values[2];
+  $children = $values[3];
+  $smoking = $values[4];
+
+  $visitors = $adults + $children;
+
+  if ($smoking < 2) {
+    $result = db_query('SELECT nid,rate_type,rate_modifier FROM {hotel_room_types} WHERE smoking = %d AND %d <= capacity', $smoking, $visitors);
+  }
+  else {
+    $result = db_query('SELECT nid,rate_type,rate_modifier FROM {hotel_room_types} WHERE %d <= capacity', $visitors);
+  }
+
+  $foo = $checkin ."+ ". ($nights-1) ." days";
+  $lastnight = date("Y-m-d", strtotime($foo));
+  $checkout = date("Y-m-d", strtotime("$lastnight + 1 day"));
+
+  $roomtypes = array();
+
+  while ($results = db_fetch_array($result)) {
+    $roomtypes[$results['nid']]['rate_type'] = $results['rate_type'];
+    $roomtypes[$results['nid']]['rate_modifier'] = $results['rate_modifier'];
+  }
+
+  $roomtype = array();
+
+  foreach ($roomtypes as $rtid => $data) {
+    $chkin = db_fetch_array(db_query('SELECT nocheckin FROM {hotel_availability_calendars} WHERE rtid = %d and caldate = "%s 00:00:00"', $rtid, $checkin));
+    $chkout = db_fetch_array(db_query('SELECT nocheckout FROM {hotel_availability_calendars} WHERE rtid = %d and caldate = "%s 00:00:00"', $rtid, $checkout));
+    if (!$chkin['nocheckin'] && !$chkout['nocheckout']) {
+      // First get the rate modifier information for room type.
+      if ($data['rate_modifier'] > 0) {
+        $query = db_query('SELECT method, value FROM {hotel_rate_modifiers} WHERE hrmid = %d', $data['rate_modifier']);
+        $thisresult = db_fetch_array($query);
+        $roomtype[$rtid]['modifier']['amount'] = $thisresult['value'];
+        $roomtype[$rtid]['modifier']['method'] = $thisresult['method'];
+      }
+      else {
+        $roomtype[$rtid]['modifier']['amount'] = 0;
+        $roomtype[$rtid]['modifier']['method'] = "value";
+      }
+
+      // Loop through each night of the stay and gather info for room type.
+      for ($night = 0; $night < $nights; $night++) {
+        $thisdate = date("Y-m-d", strtotime("$checkin + $night day"));
+        $result = db_query('SELECT a.caldate, a.minoccupancy, a.minstay, r.rate FROM {hotel_availability_calendars} AS a, {hotel_rate_calendars} AS r WHERE a.rtid = %d AND a.caldate = "%s" AND r.caldate = a.caldate AND a.avail_quantity > 0 AND r.hrid = %d AND %d >= a.minoccupancy AND %d >= a.minstay', $rtid, $thisdate, $data['rate_type'], $visitors, $nights);
+
+        while ($results = db_fetch_array($result)) {
+          $foo = explode(" ", $results['caldate']);
+          $roomtype[$rtid]['nights'][$foo[0]]['price'] = $results['rate'];
+          $roomtype[$rtid]['nights'][$foo[0]]['minstay'] = $results['minstay'];
+          $roomtype[$rtid]['nights'][$foo[0]]['minoccupancy'] = $results['minoccupancy'];
+        }
+      }
+    }
+  }
+
+ /***
+ /* The result of our room search queries, thus far, is an array of available
+ /* room types
+ /*
+ /* The key of each element of the array is the room type ID (this is also the Node ID)
+ /* Rate modifier information for each room type is contained within the array
+ /* as well as unmodified rates for each night.
+ /* The result looks something like this:
+ /*
+ /* Array (
+ /*
+ /*   [1] => Array (                      // Room type ID.
+ /*     [nights] => Array(                // Array of nights
+ /*       [2009-06-01] => Array (         // Date of night.
+ /*         [price] => 125.500            // Floating Point value of base price.
+ /*         [minstay] => 0                // Min. Night stay requirement for
+ /*                                           this date.
+ /*         [minoccupancy] => 0           // Min. occupancy requirement for
+ /*                                           this date.
+ /*       )
+ /*     )
+ /*
+ /*     [modifier] => Array (             // Rate modifier for this room type.
+ /*       [amount] => 15.000              // Floating point value of modifier
+ /*                                           amount, or 0 if none.
+ /*       [method] => value               // Whether modifier is a monetary
+ /*                                           value or percentage.
+ /*     )
+ /*   )
+ /* )
+ /***/
+
+ // Build a new array containing only rooms with the correct number of nights
+  $rooms = array();
+  foreach ($roomtype as $rtid => $data) {
+    if (sizeof($roomtype[$rtid]['nights']) == $nights) {
+      $rooms[$rtid] = $data;
+    }
+  }
+
+ // Now we'll adjust price per night for each room type with base price
+ // modifiers, and occupancy modifiers.
+  $sorted_rates = array();
+  foreach ($rooms as $rtid => $data) {
+    $adult_query = db_query('SELECT o.threshold, o.value FROM {hotel_occupancy_modifiers} AS o, {hotel_room_occupancy_modifiers} AS ro WHERE ro.nid = %d AND ro.hoid = o.hoid AND adult_child = "adult" AND %d > threshold', $rtid, $adults);
+    $child_query = db_query('SELECT o.threshold, o.value FROM {hotel_occupancy_modifiers} AS o, {hotel_room_occupancy_modifiers} AS ro WHERE ro.nid = %d AND ro.hoid = o.hoid AND adult_child = "child" AND %d > threshold', $rtid, $children);
+    $both_query = db_query('SELECT o.threshold, o.value FROM {hotel_occupancy_modifiers} AS o, {hotel_room_occupancy_modifiers} AS ro WHERE ro.nid = %d AND ro.hoid = o.hoid AND adult_child = "occup" AND %d > threshold', $rtid, ($adults + $children));
+    $adult_om = array();
+    $child_om = array();
+    $both_om = array();
+    while ($adult_result = db_fetch_array($adult_query)) {
+      $adult_om[] = $adult_result;
+    }
+    while ($child_result = db_fetch_array($child_query)) {
+      $child_om[] = $child_result;
+    }
+    while ($both_result = db_fetch_array($both_query)) {
+      $both_om[] = $both_result;
+    }
+    $total = 0;
+    foreach ($data['nights'] as $night => $nightdata) {
+      $a = $adults;
+      $c = $children;
+      $b = $a + $c;
+      if ($data['modifier']['method'] == 'value') {
+        $rooms[$rtid]['nights'][$night]['price'] += $data['modifier']['amount'];
+      }
+      else {
+        $rooms[$rtid]['nights'][$night]['price'] += ($data['nights'][$night]['price'] * ($data['modifier']['amount']/100));
+      }
+      // Apply Adult Occupancy Modifier(s)
+      for ($z = sizeof($adult_om)-1; $z >= 0; $z--) {
+        if ($a > $adult_om[$z]['threshold']) {
+          $new_a = $a - $adult_om[$z]['threshold'];
+          $rooms[$rtid]['nights'][$night]['price'] += ($new_a * $adult_om[$z]['value']);
+          $a -= $new_a;
+        }
+      }
+
+      // Apply Child Occupancy Modifier(s)
+      for ($z = sizeof($child_om)-1; $z >= 0; $z--) {
+        if ($c > $child_om[$z]['threshold']) {
+          $new_c = $c - $child_om[$z]['threshold'];
+          $rooms[$rtid]['nights'][$night]['price'] += ($new_c * $child_om[$z]['value']);
+          $c -= $new_c;
+        }
+      }
+
+      // Apply Overall Occupant (Adults & Children) Occupancy Modifier(s)
+      for ($z = sizeof($both_om)-1; $z >= 0; $z--) {
+        if ($b > $both_om[$z]['threshold']) {
+          $new_b = $b - $both_om[$z]['threshold'];
+          $rooms[$rtid]['nights'][$night]['price'] += ($new_b * $both_om[$z]['value']);
+          $b -= $new_b;
+        }
+      }
+      $total += $rooms[$rtid]['nights'][$night]['price'];
+    }
+    $sorted_rates[$rtid] = $total;
+  }
+
+  // Sort results by rate. Default to Ascending if no preference is set.
+  if (variable_get('hotel_booking_sort_order', 'ASC') == 'ASC') {
+    asort($sorted_rates);
+  }
+  else {
+    arsort($sorted_rates);
+  }
+
+  $content = '<div class="hotelsearch-prefix';
+  if (count($sorted_rates) < 1) {
+    $content .= ' hotelsearch-noresults';
+  }
+  $content .= '">';
+  $content .= '<p>'. format_plural(count($sorted_rates), 'Your search returned 1 result', 'Your search returned @count results') .'</p>';
+  if (count($sorted_rates) < 1) {
+    $content .= variable_get('hotel_booking_no_search_results', t('<p>Please select different dates and try your search again.</p>'));
+  }
+  $content .= '</div>';
+  $resultcount = 0;
+  foreach ($sorted_rates as $rtid => $total) {
+      $node = node_load($rtid);
+      $avg = $total / $nights;
+      $pp = $total / $visitors;
+      $content .= '<div class="hotelsearchresult ';
+      $content .= ($resultcount%2) ? 'hotel-search-odd">' : 'hotel-search-even">';
+      $content .= '<form action="book_room" method="post"><div>';
+      $content .= '<input type="hidden" name="nodeid[]" value="'. $node->nid .'" /></div>';
+      $content .= '<h3 class="booking-title">'. l($node->title, drupal_get_path_alias('node/'. $node->nid)) .'</h3>';
+      $content .= '<h3 class="booking-price">'. uc_price($total, array('revision' => 'formatted')) .'</h3>';
+       if (variable_get('hotel_booking_search_teaser_body', 'teaser') == 'teaser') {
+        $content .= '<div class="hotel-roomdesc">'. check_markup($node->teaser, $node->format, FALSE)
+         .' '. l(t('more'), drupal_get_path_alias('node/'. $node->nid)) 
+          ."</div>";
+      }
+      elseif (variable_get('hotel_booking_search_teaser_body', 'teaser') == 'body') {
+        $content .= '<div class="hotel-roomdesc">'. check_markup($node->body, $node->format, FALSE) ."</div>";
+      }
+
+      $content .= '<div class="hotel-button"><input class="form-submit" type="submit" value="';
+      $content .= t('Book This Room') .'" /></div>';
+
+      $content .= '<fieldset class="clear collapsible collapsed"><legend><a href="#">'. t('Pricing Details') .'</a></legend>';
+      $content .= '<div class="hotel-total">Room Total:<br />'. uc_price($total, array('revision' => 'formatted')) .'</div>';
+      $content .= '<div class="hotel-perperson-total">'. t('Total / Person:') .'<br />'. uc_price($pp, array('revision' => 'formatted')) .'</div>';
+      $content .= '<div class="hotel-avgpernight">'. t('Avg / Night:') .'<br />'. uc_price($avg, array('revision' => 'formatted')) .'</div>';
+      $content .= '<h5 class="clear">'. t('Nightly Breakdown:') .'</h5>';
+      $content .= '<div class="hotel-result-days">';
+      $content .= '<input type="hidden" name="roomtype" value="'. $node->nid .'" />';
+      $content .= '<input type="hidden" name="adults" value="'. $adults .'" />';
+      $content .= '<input type="hidden" name="children" value="'. $children .'" />';
+      $content .= '<input type="hidden" name="total" value="'. $total .'" />';
+
+      for ($z = 0; $z < sizeof($rooms[$rtid]['nights']); $z++) {
+        $content .= '<div class="hotel-result-day">'. date('M j', strtotime("$checkin + $z day")) ."<br />" . uc_price( $rooms[$rtid]['nights'][date("Y-m-d", strtotime("$checkin + $z day"))]['price'], array('revision' => 'formatted'));
+        $content .= '<input type="hidden" name="date[]" value="'. date('Y-m-d', strtotime("$checkin + $z day")) .'" />';
+        $content .= '<input type="hidden" name="price[]" value="'. number_format($rooms[$rtid]['nights'][date("Y-m-d", strtotime("$checkin + $z day"))]['price'], 2, '.', ',') .'" />';
+        $content .= '</div>';
+      }
+      $content .= '</div></fieldset>';
+
+      if (module_exists('imagecache') && ($field = variable_get('uc_image_'. $node->type, '')) && isset($node->$field) && file_exists($node->{$field}[0]['filepath'])) {
+        $content .= theme('uc_product_image', $node->$field, $teaser, $page);
+      }
+      $content .= hotel_calendars_node($node, date('Y', strtotime($checkin)), date('n', strtotime($checkin)), 2, TRUE) . '</div>';
+
+      $content .= '</form><div class="clear"></div></div>';
+      $resultcount++;
+  }
+  drupal_add_js("misc/collapse.js");
+  drupal_add_js(drupal_get_path('module', 'hotel_calendars') .'/js/calTip.js');
+  drupal_add_css(drupal_get_path('module', 'hotel_calendars') .'/js/calTip.css');
+  drupal_add_css(drupal_get_path('module', 'hotel_booking') .'/css/hotel_search_results.css');
+  print theme('page', $content);
+}
+
+
+
+function hotel_book_room() {
+  global $user;
+  $node = node_load($_POST['nodeid'][0]);
+  foreach ($_POST['date'] as $dates) {
+    $nights[] = $dates;
+  }
+  foreach ($_POST['price'] as $price) {
+    $prices[] = $price;
+  }
+  $total = $_POST['total'];
+  $adults = $_POST['adults'];
+  $children = $_POST['children'];
+  $data = array(
+    'module' => 'hotel_booking',
+    'prices' => $prices,
+    'nights' => $nights,
+    'total' => $total,
+    'adults' => $adults,
+    'children' => $children,
+  );
+
+  $redirect_destination = variable_get('hotel_booking_redirect', 'cart');
+  uc_cart_add_item($node->nid, 1, $data);
+  $cart_item_id = db_last_insert_id('{uc_cart_products}', 'cart_item_id');
+
+  if ($redirect_destination == 'cart') {
+    drupal_goto($redirect_destination);
+  }
+  elseif ($redirect_destination == 'addon') {
+    drupal_goto('booking_upgrades/'. $cart_item_id);
+  }
+  else {
+    drupal_goto(variable_get('hotel_booking_redirect_otherurl', ''));
+  }
+
+}
+
+/**
+ * Implementation of hook_cart_item().
+ */
+function hotel_booking_cart_item($op, &$item) {
+  switch ($op) {
+    case 'load':
+      if ($item->module == 'hotel_booking') {
+        $data = $item->data;
+        $item->price = $data['total'];
+        $item->qty = 1;
+      }
+      break;
+    case 'remove':
+      $data = unserialize($item->data);
+      if ($data['module'] == 'hotel_booking') {
+        $item->price = $data['total'];
+        $item->qty = 1;
+
+        // Fire item_removed trigger:
+        $remove['rtid'] = $item->nid;
+        $remove['nights'] = $data['nights'];
+        $remove['module'] = $data['module'];
+        ca_pull_trigger('item_removed_from_cart', $remove);
+      }
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_cart_item_description().
+ */
+function hotel_booking_cart_item_description($item) {
+    $node = node_load($item->nid);
+    return theme('hotel_booking_room_cart_description', $node->teaser, $item->data);
+}
+
+/**
+ * Default implementation of theme_hotel_booking_room_description().
+ */
+function theme_hotel_booking_room_cart_description($teaser = '', $data) {
+  $content = '<div class="item-list">';
+  if ($teaser && variable_get('hotel_booking_teaser_in_cart', FALSE)) {
+    $content .= $teaser .'<br />';
+  }
+  $content .= theme('hotel_booking_night_list', $data['nights'], $data['prices'], $data['adults'], $data['children']);
+  return $content;
+}
+
+/**
+ * Default implementation of theme_hotel_booking_quantity().
+ */
+function theme_hotel_booking_quantity($data = array()) {
+  $output = 1;
+
+  // The commented code that follows will set the quantity to the number of adults & children.
+  // This will lead to confusion between the cart block & checkout pages. Quantities should default to one.
+  // Otherwise people will get to the checkout page and see a different quantity and think it means they are booking
+  // Multiple rooms, rather than multiple nights for multiple people in a single room.
+
+  /*
+  $adults = $data['adults'];
+  $children = $data['children'];
+  $output = '';
+  if ($adults) {
+    $output .= t('Adults').':&nbsp;'.$adults;
+  }
+  if ($children) {
+    if ($output) $output .= '<br />';
+    $output .= t('Children').':&nbsp;'.$children;
+  } */
+
+  return $output;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function hotel_booking_theme() {
+  return array('hotel_booking_night_list' => array(
+      'arguments'  => array(
+        'nights'   => array(),
+        'prices'   => array(),
+        'adults'   => int,
+        'children' => int,
+        'html'     => FALSE,
+      ),
+    ),
+    'hotel_booking_room_cart_description' => array(
+      'arguments' => array(
+        'teaser'  => '',
+        'data'    => array()
+      ),
+    ),
+  );
+
+  /* 'hotel_booking_quantity' => array(
+      'arguments' => array(
+        'data'    => array()
+      ),
+    ),
+  );*/
+}
+
+/**
+ * Default implementation of theme_hotel_booking_night_list().
+ *
+ * html argument is for order pane product list which does a check plain
+ */
+function theme_hotel_booking_night_list($nights = array(), $prices = array(), $adults = 0, $children = 0, $html = TRUE, $review = FALSE) {
+    if ($adults) {
+      $occupants = $adults .' Adult';
+      if ($adults > 1) {
+        $occupants .= 's';
+      }
+    }
+    if ($children) {
+      $occupants .= ', '. $children .' Child';
+      if ($children > 1) {
+        $occupants .= 'ren';
+      }
+    }
+    if ($adults || $children) {
+      $occupants .= '<br />';
+    }
+    if (count($nights)) {
+      $i = 0;
+      foreach ($nights as $night) {
+        $date = strtotime($night);
+        $nights_formatted[] = uc_date_format(date('m', $date), date('d', $date), date('Y', $date)) .': '. uc_currency_format($prices[$i]);
+        $i++;
+      }
+      if ($review) {
+        return count($nights) .' '. t('Night Stay:') .'<ul><li>'. implode('</li><li>', $nights_formatted) . '</li><ul>';
+      }
+      if ($html) {
+        return $occupants . count($nights) .' '. t('Night Stay:') .'<ul class="product-description"><li>'. implode('</li><li>', $nights_formatted) .'</li></ul></div>';
+      }
+      else {
+        return ' ('. implode(', ', $nights_formatted) .')';
+      }
+    }
+    return;
+}
+
+/**
+ * Implementation of hook_cart_display().
+ */
+function hotel_booking_cart_display($item) {
+    $node = node_load($item->nid);
+    $element = array();
+    $element['nid'] = array('#type' => 'value', '#value' => $node->nid);
+    $element['module'] = array('#type' => 'value', '#value' => 'hotel_booking');
+    $element['remove'] = array('#type' => 'checkbox');
+
+    $title = check_plain($item->title);
+    $title .= ' ('. count($item->data['nights']) .t(' Nights, ');
+    $title .= format_plural($item->data['adults'], '1 Adult', '@count Adults');
+    $title .= format_plural($item->data['children'], ', 1 Child', ', @count Children');
+    $title .= ')';
+    $element['title'] = array(
+      '#value' => node_access('view', $node) ? l($title, 'node/'. $node->nid) : check_plain($item->title),
+    );
+
+    $context = array(
+      'revision' => 'altered',
+      'location' => 'cart-item',
+      'subject' => array(
+        'cart_item' => $item,
+      ),
+      'extras' => array(
+        'node' => $node,
+      ),
+    );
+    $price_info = array(
+      'price' => $item->price,
+      'qty' => $item->qty,
+    );
+
+    $element['#total'] = uc_price($price_info, $context);
+    $element['data'] = array('#type' => 'hidden', '#value' => serialize($item->data));
+    $element['qty'] = array(
+      '#type'          => 'markup',
+      '#value'         => 1,
+      '#default_value' => 1,
+    );
+
+    if (variable_get('hotel_booking_teaser_in_cart', FALSE)) {
+      $description = theme_hotel_booking_room_cart_description($node->teaser, NULL); //$item->data);
+    }
+    else {
+      $description = theme_hotel_booking_room_cart_description('', NULL); //$item->data);
+    }
+    if ($description) {
+      $element['description'] = array('#value' => $description);
+    }
+
+    return $element;
+}
+
+/**
+ * Helper function to remove addon items from the cart.
+ */
+function hotel_booking_remove_upgrades($data = array()) {
+  if ($data) {
+    foreach ($data as $nid => $cart_item_id) {
+      db_query('DELETE FROM {uc_cart_products} WHERE cart_item_id = %d', $cart_item_id);
+    }
+  }
+  return;
+}
+
+/**
+ * Implementation of hook_update_cart_item().
+ */
+function hotel_booking_update_cart_item($nid, $data = array(), $qty, $cid = NULL) {
+    if (!$nid) return NULL;
+
+  $cid = !(is_null($cid) || empty($cid)) ? $cid : uc_cart_get_id();
+  if ($qty === 0) {
+    // If the Addon module is enabled, remove all the upgrade & addon items from
+    // the cart when their parent item is deleted.
+    if (module_exists('hotel_addons_upgrades')) {
+      hotel_booking_remove_upgrades($data['booking_upgrades']);
+    }
+    uc_cart_remove_item($nid, $cid, $data);
+  }
+  else {
+    db_query("UPDATE {uc_cart_products} SET qty = %d, changed = %d WHERE nid = %d AND cart_id = '%s' AND data = '%s'", $qty, time(), $nid, $cid, serialize($data));
+  }
+
+  // Rebuild the items hash
+  uc_cart_get_contents(NULL, 'rebuild');
+}
+
+/**
+ * Implementation of hook_order().
+ */
+function hotel_booking_order($op, &$order) {
+  $proceed = FALSE;
+  for ($i = 0; $i < count($order->products); $i++) {
+    if ($order->products[$i]->data['module'] == 'hotel_booking') {
+      //this is a hotel booking product
+      $proceed = TRUE;
+    }
+  }
+  switch ($op) {
+    case 'load':
+      if ($proceed && variable_get('hotel_booking_reward_prompt', '')) {
+        $result = db_query('SELECT * FROM {hotel_booking_reward_memberships} WHERE order_id = %d', $order->order_id);
+        if ($data = db_fetch_object($result)) {
+          $order->reward_membership = $data->member_number;
+        }
+      }
+      break;
+    case 'save':
+      if ($proceed && variable_get('hotel_booking_reward_prompt', '')) {
+        if(!empty($order->reward_membership)) {
+          db_query('UPDATE {hotel_booking_reward_memberships} SET member_number = "%s" WHERE order_id = %d', $order->reward_membership, $order->order_id);
+          if (db_affected_rows() == 0) {
+            db_query('INSERT INTO {hotel_booking_reward_memberships} (order_id, member_number) VALUES (%d, "%s")', $order->order_id, $order->reward_membership);
+          }
+        }
+      }
+      break;
+    case 'delete':
+      db_query('DELETE FROM {hotel_booking_reward_memberships} WHERE order_id = %d', $order->order_id);
+      break;
+  }
+}
+
+
+
+function hotel_booking_alter_availability($order) {
+ 
+  switch($order->order_status) {
+    case 'canceled':
+      $message = t("Processing canceled booking(s)");
+      $sign = "+";
+      break;
+    default:
+      $message = t("Processing booking(s)");
+      $sign = "-";
+  }
+  watchdog('hotel booking', $message);
+  if (is_array($order->products)) {
+    foreach ($order->products as $key => $product){
+      if ($product->data['module'] = 'hotel_booking') {
+        $nid = $product->nid;
+        $nights = $product->data['nights'];
+        if (is_array($nights)) {
+          foreach ($nights as $night) {
+            if (hotel_booking_non_zeroed_date($night)) {
+              watchdog('hotel booking',t('Room type: @model availability updated for !night', array('@model' => $product->model, '!night' => $night)));
+              db_query("UPDATE {hotel_availability_calendars} SET avail_quantity = avail_quantity %s 1 WHERE rtid = %d AND caldate = '%s'", $sign, $nid, $night);
+            }
+          }
+        }
+      }
+    }
+  }
+} // end of hotel_booking_alter_availability()
+
+
+/**
+ * Check given date againt the current expiration date (according to settings). Returns true in case the given date is 
+ * yet to be expired, false otherwise
+ */
+function hotel_booking_non_zeroed_date($date) {
+  if (strtotime($date) > strtotime(hotel_booking_expiration_date())) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+/**
+ * Helper function to get the proper expiration date. Using using cron exripation process and cancellation process
+ */
+function hotel_booking_expiration_date() {
+  $expiration = variable_get('hotel_booking_expiration', 'yesterday');
+  switch ($expiration) {
+    case 'yesterday':
+      $day   = date('j', mktime(0, 0, 0, date('n'), date('j') - 1, date('y')));
+      $month = date('n', mktime(0, 0, 0, date('n'), date('j') - 1, date('y')));
+      $year  = date('Y', mktime(0, 0, 0, date('n'), date('j') - 1, date('y')));
+      break;
+    case 'today':
+      $day   = date('j', mktime(0, 0, 0, date('n'), date('j'), date('y')));
+      $month = date('n', mktime(0, 0, 0, date('n'), date('j'), date('y')));
+      $year  = date('Y', mktime(0, 0, 0, date('n'), date('j'), date('y')));
+      break;
+    case 'tomorrow':
+      $day   = date('j', mktime(0, 0, 0, date('n'), date('j') + 1, date('y')));
+      $month = date('n', mktime(0, 0, 0, date('n'), date('j') + 1, date('y')));
+      $year  = date('Y', mktime(0, 0, 0, date('n'), date('j') + 1, date('y')));
+      break;
+  }
+  return sprintf("%s-%s-%s", $year, $month, $day);
+} // end of hotel_booking_expiration_date()
+
+/**
+* Implementation of hook_ca_predicate().
+*/
+function hotel_booking_ca_predicate() {
+  // Set the order status to "Payment Received" when a payment is received
+  // and the balance is less than or equal to 0.
+  //uc_checkout_complete
+  $configurations['hotel_booking_payment_received'] = array(
+    '#title' => t('Reduce room availability status on full payment'),
+    '#description' => t('Only happens when a payment is entered and the balance is less than or equal to') . '&nbsp;' . uc_price(0, array('revision' => 'formatted')) . '.',
+    '#class' => 'payment',
+    '#trigger' => 'uc_payment_entered',
+    '#status' => 1,
+    '#conditions' => array(
+      '#operator' => 'AND',
+      '#conditions' => array(
+        array(
+          '#name' => 'uc_payment_condition_order_balance',
+          '#title' => t('If the balance is less than or equal to') . '&nbsp;' . uc_price(0, array('revision' => 'formatted')) . '.',
+          '#argument_map' => array(
+            'order' => 'order',
+          ),
+          '#settings' => array(
+            'negate' => FALSE,
+            'balance_comparison' => 'less_equal',
+          ),
+        ),
+        array(
+          '#name' => 'uc_order_status_condition',
+          '#title' => t('If the order status is not already Payment Received.'),
+          '#argument_map' => array(
+            'order' => 'order',
+          ),
+          '#settings' => array(
+            'negate' => TRUE,
+            'order_status' => 'payment_received',
+          ),
+        ),
+      ),
+    ),
+    '#actions' => array(
+      array(
+        '#name' => 'hotel_booking_reduce_availability',
+        '#title' => t('Reduce the room availability.'),
+        '#argument_map' => array(
+          'order' => 'order',
+        ),
+        '#settings' => array(
+          'order_status' => 'payment_received',
+        ),
+      ),
+    ),
+  );
+
+  $configurations['hotel_booking_checkout_complete'] = array(
+    '#title' => t('Reduce room availability status on checkout with full payment'),
+    '#description' => t('Only happens when checkout occurs and a payment is entered and the balance is less than or equal to') . '&nbsp;' . uc_price(0, array('revision' => 'formatted')) . '.',
+    '#class' => 'payment',
+    '#trigger' => 'uc_checkout_complete',
+    '#status' => 0,
+    '#conditions' => array(
+      '#operator' => 'AND',
+      '#conditions' => array(
+        array(
+          '#name' => 'uc_payment_condition_order_balance',
+          '#title' => t('If the balance is less than or equal to') . '&nbsp;' . uc_price(0, array('revision' => 'formatted')) . '.',
+          '#argument_map' => array(
+            'order' => 'order',
+          ),
+          '#settings' => array(
+            'negate' => FALSE,
+            'balance_comparison' => 'less_equal',
+          ),
+        ),
+      ),
+    ),
+    '#actions' => array(
+      array(
+        '#name' => 'hotel_booking_reduce_availability',
+        '#title' => t('Reduce the room availability.'),
+        '#argument_map' => array(
+          'order' => 'order',
+        ),
+        '#settings' => array(
+          'order_status' => 'completed',
+        ),
+      ),
+    ),
+  );
+
+  // Set increase availability in case of cancellation
+  $configurations['hotel_booking_order_cancelled'] = array(
+    '#title' => t('Increase room availability on order cancellation.'),
+    '#description' => t('When order is cancelled, room availability should be increased.'),
+    '#class' => 'payment',
+    '#trigger' => 'uc_order_status_update',
+    '#status' => 1,
+    '#conditions' => array(
+      '#operator' => 'AND',
+      '#conditions' => array(
+        array(
+          '#name' => 'uc_order_status_condition',
+          '#title' => t('If the order status is cancelled'),
+          '#argument_map' => array(
+            'order' => 'updated_order',
+          ),
+          '#settings' => array(
+            'order_status' => 'canceled',
+          ),
+        ),
+      ),
+    ),
+    '#actions' => array(
+      array(
+        '#name' => 'hotel_booking_increase_availability',
+        '#title' => t('Increase the room availability.'),
+        '#argument_map' => array(
+          'order' => 'updated_order',
+        ),
+      ),
+    ),
+  );
+
+  return $configurations;
+}
+
+/**
+ * Implementation of hook_ca_action().
+ */
+function hotel_booking_ca_action() {
+  $order_arg = array(
+    '#entity' => 'uc_order',
+    '#title' => t('Order'),
+  );
+
+  $actions['hotel_booking_reduce_availability'] = array(
+    '#title' => t('Reduce the availability of rooms'),
+    '#category' => t('Order'),
+    '#callback' => 'hotel_booking_alter_availability',
+    '#arguments' => array(
+      'order' => $order_arg,
+    ),
+  );
+  $actions['hotel_booking_increase_availability'] = array(
+    '#title' => t('Increase the availability of rooms'),
+    '#category' => t('Order'),
+    '#callback' => 'hotel_booking_alter_availability',
+    '#arguments' => array(
+      'order' => $order_arg,
+    ),
+  );
+
+  return $actions;
+}
+
+
+/**
+ * Helper function to determine if there is a booking item in the cart.
+ */
+function _booking_item_in_cart() {
+  $items = uc_cart_get_contents();
+  foreach ($items as $item) {
+    if ($item->data['module'] == 'hotel_booking') {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+
+/**
+ * ----------------------------------------
+ * Cart, Checkout, and Order Pane functions
+ * ----------------------------------------
+ */
+
+
+/**
+ * Implementation of hook_cart_pane().
+ */
+function hotel_booking_cart_pane() {
+  if (_booking_item_in_cart()) {
+    $panes[] = array(
+      'id' => 'booking_details',
+      'title' => t('Booking Details'),
+      'weight' => -15,
+      'body' => drupal_get_form('hotel_booking_details_pane_cart'),
+      'collapsible' => TRUE,
+      'collapsed'   => FALSE,
+    );
+    return $panes;
+  }
+  else {
+    return;
+  }
+}
+
+
+/**
+ * Implementation of hook_checkout_pane().
+ */
+function hotel_booking_checkout_pane() {
+  if (_booking_item_in_cart()) {
+    if (variable_get('hotel_booking_reward_prompt', '')) {
+      $panes[] = array(
+        'id'          => 'reward_membership',
+        'callback'    => 'hotel_booking_rewards',
+        'title'       => t('Reward Membership'),
+        'weight'      => 6,
+        'enabled'     => TRUE,
+        'process'     => TRUE,
+        'collapsible' => FALSE,
+      );
+    }
+    $panes[] = array(
+      'id'            => 'booking_details',
+      'callback'      => 'hotel_booking_details_pane_checkout',
+      'title'         => t('Booking Details'),
+      'weight'        => -8,
+      'enabled'       => TRUE,
+      'collapsible'   => TRUE,
+      'process'       => TRUE,
+    );
+    return $panes;
+  }
+  else {
+    return;
+  }
+}
+
+
+
+
+/**
+ * Implementation of hook_order_pane().
+ */
+function hotel_booking_order_pane() {
+  $panes[] = array(
+      'id' => 'hotel_booking',
+      'callback' => 'hotel_booking_booking_pane',
+      'title' => t('Booking Details'),
+      'desc' => t('Display details of room bookings.'),
+      'class' => 'abs-left',
+      'weight' => 5,
+      'show' => array('view', 'customer'),
+    );
+    if (variable_get('hotel_booking_reward_prompt', '')) {
+      $panes[] = array(
+        'id' => 'reward_membership',
+        'callback' => 'hotel_booking_pane_rewards',
+        'title' => t('Reward Membership'),
+        'weight' => 5,
+        'show' => array('view', 'customer'),
+      );
+    }
+  return $panes;
+}
+
+
+/**
+ * Callbacks for order pane
+ */
+function hotel_booking_booking_pane($op, $order) {
+  $proceed = FALSE;
+  for ($i = 0; $i < count($order->products); $i++) {
+    if ($order->products[$i]->data['module'] == 'hotel_booking') {
+      //this is a hotel booking product
+      $proceed = TRUE;
+    }
+  }
+  switch ($op) {
+    case 'view':
+    case 'customer':
+      if ($proceed) {
+        return drupal_get_form('hotel_booking_details_pane_order', $order->products, $order->as_template);
+      }
+      else {
+        break;
+      }
+  }
+}
+
+function hotel_booking_pane_rewards($op, $order) {
+  switch ($op) {
+    case 'view':
+    case 'customer':
+      if (!empty($order->reward_membership)) {
+        $reward_number = $order->reward_membership;
+        return t('Reward Membership Number: @reward', array('@reward' => $reward_number));
+      }
+      else {
+        break;
+      }
+  }
+}
+
+
+
+/**
+ * Functions to build fieldsets & tables for order pane
+ * @param $form_state array std drupal FAPI form state var
+ * @param $products array array of products as per $order->products
+ * @param $as_template bool whether pane is being displayed in a template (ie printed invoice, emailed)
+ */
+function hotel_booking_details_pane_order($form_state, $products, $as_template) {
+  foreach ($products as $product) {
+    if ($product->data['module'] == 'hotel_booking') {
+      $numnights[$product->order_product_id] = count($product->data['nights']);
+    }
+  }
+
+  foreach ($products as $product) {
+    if ($product->data['module'] == 'hotel_booking') {
+      $title = check_plain($item->title);
+      $title .= ' ('. count($item->data['nights']) .t(' Nights, ');
+      $title .= format_plural($item->data['adults'], '1 Adult', '@count Adults');
+      $title .= format_plural($item->data['children'], ', 1 Child', ', @count Children');
+      $title .= ')';
+      $foo = node_load($product->nid);
+      $desc = (variable_get('hotel_booking_teaser_in_panes','FALSE')) ? '' : $foo->teaser;
+      $desc .= '<div class="booking_details_blurb"><p>'. t('The following table breaks down your stay by day, listing price per night of the room');
+      $desc .= ($product->data['booking_upgrades']) ? ', '. t('along with any applicable date based Add-On items.</p><p>Other Add-On items apply to your entire stay.') .'</p>' : '.</p>';
+      $desc .= '</div>';
+      $contents['booking_details'][$product->order_product_id] = array(
+        '#type' => 'fieldset',
+        '#title' => $title,
+        '#description' => $desc,
+        '#collapsible' => TRUE,
+        // Default to collapsed if there are multiple room booking items in the cart,
+        // or the booking has more than three nights and more than two addons, or if
+        // the a single booking item has more than 5 nights.
+        '#collapsed' => (sizeof($numnights) > 1 || (count($product->data['nights']) > 3 && sizeof($product->data['booking_upgrades']) > 2) || (count($product->data['nights']) > 5)) ? TRUE : FALSE,
+      );
+      $val = hotel_booking_order_details_table($product, $products, FALSE, $as_template);
+      $contents['booking_details'][$product->order_product_id]['nid'] = array(
+        '#value' => $val[0],
+      );
+      if ($val[1]) {
+        $contents['booking_details'][$product->order_product_id]['nid']['additional'] = array(
+          '#value' => hotel_booking_order_details_table($product, $products, TRUE, $as_template),
+        );
+      }
+    }
+  }
+  return array('contents' => $contents);
+}
+
+/**
+ * Utility, provides a table in the booking panes
+ * @param $item object the product item
+ * @param $products array all products in the cart
+ * @param $additional bool whether the table is for additional items
+ * @param $as_template bool whether the table is being displayed in an invoice template (printed/email)
+ *                          and as such, needs to include style tags
+*/
+function hotel_booking_order_details_table(&$item, $products, $additional = FALSE, $as_template = FALSE) {
+  $addons = $table_attributes = array();
+  if ($as_template) {
+    $table_attributes = array('width' => '100%', 'style' => 'font-family: verdana, arial, helvetica; font-size: small;');
+  }
+  if ($item->data['booking_upgrades_order']) {
+    foreach ($item->data['booking_upgrades_order'] as $nid => $child_id) {
+      for ($i = 0; $i < count($products); $i++) {
+        if ($products[$i]->nid == $nid && $products[$i]->data['child_id'] == $child_id) {
+          $addons[$products[$i]->nid]['order'] = $products[$i];
+          $addons[$products[$i]->nid]['data'] = $products[$i]->data;
+          $addons[$products[$i]->nid]['daily'] = ($addons[$products[$i]->nid]['data']['days']) ? TRUE : FALSE;
+          if (!$additional_items) {
+            $additional_items = (!$addons[$products[$i]->nid]['daily']) ? TRUE : FALSE;
+          }
+          if (!$daily_items) {
+            $daily_items = ($addons[$products[$i]->nid]['daily']) ? TRUE : FALSE;
+          }
+        }
+      }
+    }
+  }
+  if (!$additional) {
+    if ($addons && $daily_items) {
+      $addon_title = t('Date Based Add-On Items');
+      $qtys = t('Qty.');
+    }
+    $header = array(t('Dates'), array('data' => $addon_title, 'width' => '45%'), array('data' => t(''), 'colspan' => 2), $qtys, t('Total'));
+    for ($i = 0; $i < sizeof($item->data['nights']); $i++) {
+      $checkin = ($i == 0) ? t('Check-In') : '';
+      $thisday = $item->data['nights'][$i];
+      $foo = explode('-', $thisday);
+      $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2], $foo[0]));
+      $rows[] = array($today, '',  t('Night !night', array('!night' => ($i + 1))), $checkin, '', array('data' => uc_price($item->data['prices'][$i], array('revision' => 'formatted')), 'class' => 'price'));
+      foreach ($addons as $nid => $info) {
+        if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
+          $rows[] = array('', l($addons[$nid]['order']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => uc_price(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['order']->price), array('revision' => 'formatted')), 'class' => 'price'));
+        }
+      }
+    }
+    $thisday = date('Y-m-d', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
+    $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
+    $rows[] = array($today, '', '', t('Check-Out'), '', '');
+    foreach ($addons as $nid => $info) {
+      if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
+        $rows[] = array('', l($addons[$nid]['order']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => uc_price(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['order']->price), array('revision' => 'formatted')), 'class' => 'price'));
+      }
+    }
+
+    $table = theme('table', $header, $rows, $table_attributes);
+    if ($additional_items) {
+    }
+    return array($table, $additional_items);
+  }
+  else {
+    $header = array(array('data' => t('Additional Add-On & Upgrade Items'), 'colspan' => 2, 'width' => '100%'), 'data' => t('Total'));
+    foreach ($addons as $nid => $info) {
+      if (!$addons[$nid]['daily']) {
+        $rows[] = array($addons[$nid]['order']->qty .'x', array('data' => l($addons[$nid]['order']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']), 'width' => '100%'), array('data' => uc_price(($addons[$nid]['order']->qty * $addons[$nid]['order']->price), array('revision' => 'formatted')), 'class' => 'price'));
+      }
+    }
+
+    return theme('table', $header, $rows, $table_attributes);
+  }
+}
+
+
+/**
+ * Functions to build fieldsets & tables for cart pane
+ */
+
+function hotel_booking_details_pane_cart() {
+  $items = uc_cart_get_contents();
+  foreach ($items as $item) {
+    if ($item->module == 'hotel_booking') {
+      $numnights[$item->cart_item_id] = count($item->data['nights']);
+    }
+  }
+
+  $contents['booking_details'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Booking Details'),
+      '#description' => (sizeof($numnights) > 1) ? t('Click on the Room Types below to view your booking details.') : '',
+      '#collapsible' => TRUE,
+      '#collapsed'   => FALSE,
+  );
+
+  foreach ($items as $item) {
+    if ($item->module == 'hotel_booking') {
+      $title = t('@title', array('@title' => $item->title));
+      $title .= ' ('. count($item->data['nights']);
+      $title .= (count($item->data['nights']) > 1) ? t(' Nights, ') : t(' Night, ');
+      $title .= ($item->data['adults'] > 1) ? $item->data['adults'] .t(' Adults') : $item->data['adults'] .t(' Adult');
+      if ($item->data['children']) {
+        $title .= ($item->data['children'] > 1) ? ', '. $item->data['children'] .t(' Children') : ', '. $item->data['children'] .t(' Child');
+      }
+      $title .= ')';
+      $foo = node_load($item->nid);
+
+      $desc = (variable_get('hotel_booking_teaser_in_panes','FALSE')) ? $foo->teaser : '';
+      $desc .= '<div class="booking_details_blurb"><p>The following table breaks down your stay by day, listing price per night of the room';
+      $desc .= ($item->data['booking_upgrades']) ? ', along with any applicable date based Add-On items.</p><p>Other Add-On items apply to your entire stay.</p>' : '.</p>';
+      if (substr(drupal_get_destination(), -8, 8) != 'checkout') {
+        $desc .= (is_array($item->data['booking_upgrades'])) ? '<p>'. l('Edit Addons & Upgrades', 'booking_upgrades/'. $item->cart_item_id) .'</p></div>' : '</div>';
+      }
+      else {
+        $desc .= '</div>';
+      }
+      $contents['booking_details'][$item->cart_item_id] = array(
+        '#type' => 'fieldset',
+        '#title' => $title,
+        '#description' => $desc,
+        '#collapsible' => TRUE,
+        // Default to collapsed if there are multiple room booking items in the cart,
+        // or the booking has more than three nights and more than two addons, or if
+        // the a single booking item has more than 5 nights.
+        '#collapsed' => (sizeof($numnights) > 1 || ($numnights[$item->cart_item_id] > 3 && sizeof($item->data['booking_upgrades']) > 2) || ($numnights[$item->cart_item_id] > 5)) ? TRUE : FALSE,
+      );
+      $val = hotel_booking_cart_details_table($item);
+      $contents['booking_details'][$item->cart_item_id]['nid'] = array(
+        '#value' => $val[0],
+      );
+      if ($val[1]) {
+        $contents['booking_details'][$item->cart_item_id]['nid']['additional'] = array(
+          '#value' => hotel_booking_cart_details_table($item, TRUE),
+        );
+      }
+    }
+  }
+  return array('contents' => $contents);
+}
+
+
+
+/**
+ * Callbacks for checkout pane
+ */
+function hotel_booking_rewards($op, &$order, $newvalue) {
+  switch ($op) {
+    case 'view':
+      $description = t('If you have a reward membership card, please enter the number here.');
+      $contents['reward_membership'] = array(
+        '#type'          => 'textfield',
+        '#title'         => variable_get('hotel_booking_reward_prompt', ''),
+        '#default_value' => ($order->reward_membership) ? $order->reward_membership : '',
+      );
+      return array('description' => $description, 'contents' => $contents);
+    case 'process':
+      $order->reward_membership = $newvalue['reward_membership'];
+      return TRUE;
+    case 'review':
+      $review = ($order->reward_membership) ? $order->reward_membership : NULL;
+      return $review;
+  }
+}
+
+function hotel_booking_details_pane_checkout($op, &$order, $arg2) {
+  switch ($op) {
+    case 'view':
+      $contents = array();
+
+      $items = uc_cart_get_contents();
+      foreach ($items as $item) {
+        if ($item->module == 'hotel_booking') {
+          $numnights[$item->cart_item_id] = count($item->data['nights']);
+        }
+      }
+
+      foreach ($items as $item) {
+        if ($item->module == 'hotel_booking') {
+          $title = check_plain($item->title);
+          $title .= ' ('. count($item->data['nights']) .t(' Nights, ');
+          $title .= format_plural($item->data['adults'], '1 Adult', '@count Adults');
+          $title .= format_plural($item->data['children'], ', 1 Child', ', @count Children');
+          $title .= ')';
+          $foo = node_load($item->nid);
+
+          $desc = (variable_get('hotel_booking_teaser_in_panes','FALSE')) ? $foo->teaser : '';
+          $desc .= '<div class="booking_details_blurb"><p>The following table breaks down your stay by day, listing price per night of the room';
+          $desc .= ($item->data['booking_upgrades']) ? ', along with any applicable date based Add-On items.</p><p>Other Add-On items apply to your entire stay.</p>' : '.</p>';
+          if (substr(drupal_get_destination(), -8, 8) != 'checkout') {
+            $desc .= (is_array($item->data['booking_upgrades'])) ? '<p>'. l('Edit Addons & Upgrades', 'booking_upgrades/'. $item->cart_item_id) .'</p></div>' : '</div>';
+          }
+          else {
+            $desc .= '</div>';
+          }
+          $contents['booking_details'][$item->cart_item_id] = array(
+            '#type' => 'fieldset',
+            '#title' => $title,
+            '#description' => $desc,
+            '#collapsible' => TRUE,
+            // Default to collapsed if there are multiple room booking items in the cart,
+            // or the booking has more than three nights and more than two addons, or if
+            // the a single booking item has more than 5 nights.
+            '#collapsed' => (sizeof($numnights) > 1 || ($numnights[$item->cart_item_id] > 3 && sizeof($item->data['booking_upgrades']) > 2) || ($numnights[$item->cart_item_id] > 5)) ? TRUE : FALSE,
+          );
+          $val = hotel_booking_cart_details_table($item);
+          $contents['booking_details'][$item->cart_item_id]['nid'] = array(
+            '#value' => $val[0],
+          );
+          if ($val[1]) {
+            $contents['booking_details'][$item->cart_item_id]['nid']['additional'] = array(
+              '#value' => hotel_booking_cart_details_table($item, TRUE),
+            );
+          }
+        }
+      }
+      return array('contents' => $contents);
+  }
+}
+
+function hotel_booking_cart_details_table(&$item, $additional = FALSE) {
+  $addons = array();
+  if ($item->data['booking_upgrades']) {
+    foreach($item->data['booking_upgrades'] as $nid => $cart_item_id) {
+      $addons[$nid]['cart'] = db_fetch_array(db_query('SELECT * FROM {uc_cart_products} WHERE cart_item_id = %d', $cart_item_id));
+      $addons[$nid]['data'] = unserialize($addons[$nid]['cart']['data']);
+      $addons[$nid]['daily'] = ($addons[$nid]['data']['days']) ? TRUE : FALSE;
+      if (!$additional_items) {
+        $additional_items = (!$addons[$nid]['daily']) ? TRUE : FALSE;
+      }
+      if (!$daily_items) {
+        $daily_items = ($addons[$nid]['daily']) ? TRUE : FALSE;
+      }
+
+      // For the first time running through this function ($additional = FALSE)
+      // If the item is not a daily addon item, we just won't pay it any mind.
+      if (!$additional && $addons[$nid]['daily']) {
+        $addons[$nid]['node'] = node_load($nid);
+      }
+
+      // If we're coming around a second time for non-daily items don't do
+      // a node load on those daily items.
+      elseif ($additional && !$addons[$nid]['daily']) {
+        $addons[$nid]['node'] = node_load($nid);
+      }
+    }
+  }
+  if (!$additional) {
+    if ($addons && $daily_items) {
+      $addon_title = t('Date Based Add-On Items');
+      $qtys = t('Qty.');
+    }
+    $header = array(t('Dates'), array('data' => $addon_title, 'width' => '45%'), array('data' => t(''), 'colspan' => 2), $qtys, t('Total'));
+    for ($i = 0; $i < sizeof($item->data['nights']); $i++) {
+      $checkin = ($i == 0) ? t('Check-In') : '';
+      $thisday = $item->data['nights'][$i];
+      $foo = explode('-', $thisday);
+      $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2], $foo[0]));
+      $rows[] = array($today, '',  t('Night !night', array('!night' => ($i + 1))), $checkin, '', array('data' => uc_price($item->data['prices'][$i], array('revision' => 'formatted')), 'class' => 'price'));
+      foreach ($addons as $nid => $info) {
+        if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
+          $rows[] = array('', l($addons[$nid]['node']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => uc_price(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['node']->sell_price), array('revision' => 'formatted')), 'class' => 'price'));
+        }
+      }
+    }
+    $thisday = date('Y-m-d', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
+    $today = date('l F j, Y', mktime(0, 0, 0, $foo[1], $foo[2]+1, $foo[0]));
+    $rows[] = array($today, '', '', t('Check-Out'), '', '');
+    foreach ($addons as $nid => $info) {
+      if ($addons[$nid]['daily'] && $addons[$nid]['data']['days'][$thisday]) {
+        $rows[] = array('', l($addons[$nid]['node']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']),'','',array('data' => $addons[$nid]['data']['days'][$thisday], 'class' => 'qty'), array('data' => uc_price(($addons[$nid]['data']['days'][$thisday] * $addons[$nid]['node']->sell_price), array('revision' => 'formatted')), 'class' => 'price'));
+      }
+    }
+
+    $table = theme('table', $header, $rows);
+    if ($additional_items) {
+    }
+    return array($table, $additional_items);
+  }
+  else {
+    $header = array(array('data' => t('Additional Add-On & Upgrade Items'), 'colspan' => 2, 'width' => '100%'), 'data' => t('Total'));
+    foreach ($addons as $nid => $info) {
+      if (!$addons[$nid]['daily']) {
+        $rows[] = array($addons[$nid]['cart']['qty'] .'x', array('data' => l($addons[$nid]['node']->title, 'booking_upgrades/'. $addons[$nid]['data']['parent_id']), 'width' => '100%'), array('data' => uc_price(($addons[$nid]['cart']['qty'] * $addons[$nid]['node']->sell_price), array('revision' => 'formatted')), 'class' => 'price'));
+      }
+    }
+    return theme('table', $header, $rows);
+  }
+}
+
+
+function hotel_booking_pad_with_zeros($s, $n) {
+  return sprintf("%0". $n ."d", $s);
+}
+
+/**
+* Implements hook_token_list().
+* Provides tokens for hotel booking pane and check in/out dates
+* @author larowlan leerowlands at rowlands-bcs.com
+*/
+function hotel_booking_token_list($type = 'site') {
+  $tokens = array();
+  if ($type == 'order' || $type == 'all') {
+
+    $tokens['order']['bookings-pane'] = t('Hotel bookings pane');
+    $tokens['order']['check-out-date'] = t('Check out date (latest if more than one');
+    $tokens['order']['check-in-date'] = t('Check in date (earliest if more than one');
+    
+  }
+
+  return $tokens;
+  
+}
+
+
+/**
+* Implements hook_token_values().
+* Evaluate the token values
+* @author larowlan leerowlands at rowlands-bcs.com
+*/
+function hotel_booking_token_values($type, $object = NULL, $options = array()) {
+  $tokens = array();
+ 
+  if ($type == 'order') {   
+    $order = $object;
+    $order->as_template = TRUE; //notify booking pane that this item is being shown in a template
+        
+    $tokens['bookings-pane'] = hotel_booking_booking_pane('customer', $order);
+    $tokens['check-in-date'] = NULL;
+    $tokens['check-out-date'] = NULL;
+    
+    $dates_exist = FALSE;
+    if ($order->products && is_array($order->products)) {
+      $first = TRUE;
+      $first_check_in = $last_check_out = FALSE;
+      foreach ($order->products as $product) {
+        if ($product->data['module'] == 'hotel_booking') {
+          list($check_in, $check_out) = _hotel_booking_check_in_out($product->data['nights']);
+          //have we had 1 pass yet?
+          if ($first) {
+            $first_check_in = $check_in;
+            $last_check_out = $check_out;
+            $first = FALSE;
+            $dates_exist = TRUE;
+            continue; //next loop
+          }
+          if ($last_check_out->getTimestamp() < $check_out->getTimestamp()) {
+            //this check out is later
+            $last_check_out = $check_out;
+          }
+          if ($first_check_in->getTimestamp() > $check_in->getTimestamp()) {
+            //this check in is eariler
+            $first_check_in = $check_in;
+          }
+        }
+      }
+    }
+    if ($dates_exist) {
+      $format = variable_get('uc_date_format_default', 'd M Y');
+      $tokens['check-in-date'] = $first_check_in->format($format);
+      $tokens['check-out-date'] = $last_check_out->format($format);
+    }
+  }
+  
+  return $tokens;
+}
+
+
+/**
+ * Utility function to fetch check in night and check out night
+ * @param $nights array array of nights as per product->data['nights'] in cart and order products
+ * @return array($check_in, $check_out)
+ * @author larowlan leerowlands at rowlands-bcs.com
+*/
+function _hotel_booking_check_in_out($nights) {
+  $check_in = date_make_date($nights[0], NULL, DATE_ISO);
+  $last_night = date_make_date($nights[count($nights) - 1], NULL, DATE_ISO);
+  $last_night->modify('+ 1 day'); //check out is day after last night
+  return array($check_in, $last_night);
 }
\ No newline at end of file
Index: hotel_calendars/hotel_calendars.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_hotel/hotel_calendars/hotel_calendars.module,v
retrieving revision 1.8
diff -u -p -r1.8 hotel_calendars.module
--- hotel_calendars/hotel_calendars.module	15 May 2010 03:15:09 -0000	1.8
+++ hotel_calendars/hotel_calendars.module	18 May 2010 16:33:49 -0000
@@ -555,7 +555,7 @@ function hotel_calendars_month($node, $y
       $output .= '<div class="calprice">';
       if ($day_prices[$day_num]['qty'] > 0) {
         if ($day_prices[$day_num]['rate']) {
-          $output .='$'; // prefix monetary sign (this should be changed to a variable rather than hardcoded)
+          $output .='';
         }
         else {
           $output .='&nbsp;'; // blank space to even out spacing of empty vs full dates.
Index: hotel_room_type/hotel_room_type.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_hotel/hotel_room_type/hotel_room_type.module,v
retrieving revision 1.4
diff -u -p -r1.4 hotel_room_type.module
--- hotel_room_type/hotel_room_type.module	15 May 2010 03:15:09 -0000	1.4
+++ hotel_room_type/hotel_room_type.module	18 May 2010 16:33:49 -0000
@@ -338,7 +338,7 @@ function _get_occupancy_modifiers($a_or_
   }
 
   while ($result = db_fetch_array($results)) {
-    $modifiers[$result['hoid']] = '$'. number_format($result['value'], 2, '.', ',') .' each additional over '. $result['threshold'];
+    $modifiers[$result['hoid']] = uc_price($result['value'], array('revision' => 'formatted')) .' each additional over '. $result['threshold'];
   }
 
   return $modifiers;
