You are here

function rooms_booking_edit_form in Rooms - Drupal Booking for Hotels, B&Bs and Vacation Rentals 7

Form callback: create or edit a booking.

Parameters

$booking: The RoomBooking object to edit or for a create form an empty booking object with only a booking type defined.

4 string references to 'rooms_booking_edit_form'
rooms_availability_event_manager_page in modules/rooms_availability/rooms_availability.module
The EventManager page shows when clicking on an event in the availability calendar - will allow a user to manipulate that event.
rooms_booking_create_form_wrapper in modules/rooms_booking/rooms_booking.admin.inc
Form callback wrapper: create a Booking.
rooms_booking_form_wrapper in modules/rooms_booking/rooms_booking.admin.inc
Form callback wrapper: edit a Booking.
rooms_booking_manager_form_alter in modules/rooms_booking_manager/rooms_booking_manager.module
Implements hook_form_alter().

File

modules/rooms_booking/rooms_booking.admin.inc, line 225
Rooms editing UI.

Code

function rooms_booking_edit_form($form, &$form_state, $booking) {
  if (isset($booking->unit_id)) {
    if (rooms_unit_load($booking->unit_id) === FALSE) {
      drupal_set_message(t('Associated unit no longer exist'), 'error');
      return $form;
    }
  }
  $form['#attributes']['class'][] = 'rooms-management-form rooms-booking-form';
  $form['#attached'] = array(
    'css' => array(
      drupal_get_path('module', 'rooms_booking') . '/css/rooms_booking.css',
    ),
    'js' => array(
      drupal_get_path('module', 'rooms') . '/js/rooms_date_popup.js',
    ),
  );
  $client = '';
  if (module_exists('commerce_multicurrency')) {
    $currency_code = commerce_multicurrency_get_user_currency_code();
  }
  else {
    $currency_code = commerce_default_currency();
  }

  // Check to see if we are loading an existing booking (existing bookings
  // have customer ids set).
  if (isset($booking->customer_id)) {

    // The Client value needs the id as well to take us back to the Customer
    // Profile in Commerce.
    $client = $booking->name . ':' . $booking->customer_id;
  }
  $form['type'] = array(
    '#type' => 'value',
    '#value' => $booking->type,
  );
  $form['client'] = array(
    '#type' => 'textfield',
    '#title' => t('Customer'),
    '#maxlength' => 60,
    '#autocomplete_path' => 'admin/rooms/bookings/customers',
    '#default_value' => $client,
    '#weight' => -1,
    '#required' => TRUE,
    '#prefix' => '<div class="rooms-booking-customer-wrapper" id="edit-customer-wrapper">',
    '#suffix' => '</div>',
    '#ajax' => array(
      'callback' => 'rooms_booking_edit_profile_callback',
      'wrapper' => 'edit-customer-wrapper',
    ),
  );
  if (module_exists('commerce_customer')) {
    $form['#after_build'][] = 'rooms_booking_edit_form_add_modal_js';
    if (user_access('create customer profiles on bookings')) {
      $form['client']['#description'] = t('Customer profiles are saved in the <a href="@store-profile">store</a>. Search for an existing one by typing the customer name or <a href="@profile-create" class="ctools-use-modal">create a new profile</a>.', array(
        '@store-profile' => url('admin/commerce/customer-profiles'),
        '@profile-create' => url('admin/rooms/add_customers'),
      ));
    }
    if (isset($booking->customer_id)) {
      $commerce_customer_id = db_select('rooms_customers')
        ->fields('rooms_customers', array(
        'commerce_customer_id',
      ))
        ->condition('id', $booking->customer_id, '=')
        ->execute()
        ->fetchField();
      if ($commerce_customer_id != NULL) {
        $form['client']['#field_suffix'] = t('<a href="@edit-profile" class="ctools-use-modal">edit profile</a>', array(
          '@edit-profile' => url('admin/rooms/customer-profiles/' . $commerce_customer_id . '/edit'),
        ));
      }
    }
  }
  $form['data']['#tree'] = TRUE;
  $form['data']['group_size'] = array(
    '#type' => 'select',
    '#title' => t('Guests'),
    '#options' => rooms_assoc_range(1, 10),
    '#default_value' => isset($booking->data['group_size']) ? $booking->data['group_size'] : '2',
    '#description' => t('The total number of people staying in this unit (including adults and children).'),
    '#ajax' => array(
      'callback' => 'rooms_booking_group_size_ajax_callback',
      'wrapper' => 'rooms_booking_group_size_children_container',
    ),
  );
  $persons = 2;
  if (isset($form_state['values']['data']['group_size'])) {
    $persons = $form_state['values']['data']['group_size'];
  }
  if (variable_get('rooms_booking_display_children', ROOMS_DISPLAY_CHILDREN) == ROOMS_DISPLAY_CHILDREN) {
    $form['data']['group_size_children'] = array(
      '#type' => 'select',
      '#title' => t('Children'),
      '#options' => rooms_range(0, $persons),
      '#default_value' => isset($booking->data['group_size_children']) ? $booking->data['group_size_children'] : '0',
      '#description' => t('The number of children staying in this unit.'),
      '#prefix' => '<div class="rooms-booking-group-size-children-container" id="rooms_booking_group_size_children_container">',
      '#suffix' => '</div>',
    );

    // If price calculation is set to 'Price per person per night'.
    if (variable_get('rooms_price_calculation', ROOMS_PER_NIGHT) == ROOMS_PER_PERSON) {

      // Show fields for enter children ages.
      $form['data']['group_size_children']['#ajax'] = array(
        'callback' => 'rooms_booking_children_change_callback',
        'wrapper' => 'rooms_booking_childrensage',
      );
      $form['data']['childrens_age'] = array(
        '#prefix' => '<div class="container-inline rooms-booking-childrensage" id="rooms_booking_childrensage">',
        '#suffix' => '</div>',
      );
      if (isset($form_state['values']['data']['group_size_children'])) {
        if ($persons >= $form_state['values']['data']['group_size_children']) {
          for ($t = 1; $t <= $form_state['values']['data']['group_size_children']; $t++) {
            $form['data']['childrens_age'][$t] = array(
              '#type' => 'textfield',
              '#title' => t('Age of child @num', array(
                '@num' => $t,
              )),
              '#size' => 5,
              '#maxlength' => 5,
              '#ajax' => array(
                'callback' => 'rooms_booking_childrens_age_ajax_callback',
                'event' => 'blur',
              ),
            );
          }
        }
      }
      elseif (!empty($booking->data['childrens_age'])) {
        foreach ($booking->data['childrens_age'] as $key => $age) {
          $form['data']['childrens_age'][$key] = array(
            '#type' => 'textfield',
            '#title' => t('Age of child @num', array(
              '@num' => $key,
            )),
            '#size' => 5,
            '#maxlength' => 5,
            '#default_value' => $age,
            '#ajax' => array(
              'callback' => 'rooms_booking_childrens_age_ajax_callback',
              'event' => 'blur',
            ),
          );
        }
      }
    }
  }

  // A fieldset to hold the date range fields.
  $form['rooms_date_range'] = array(
    '#type' => 'fieldset',
    '#attributes' => array(
      'class' => array(
        'rooms-booking-date-range-wrapper',
      ),
    ),
  );
  $form['rooms_date_range'] += rooms_date_range_fields();

  // Unset the default for max days away for bookings since we are on the admin.
  drupal_add_js(array(
    'rooms' => array(
      'roomsBookingStartDay' => 0,
    ),
  ), 'setting');

  // Set the default values for the dates.
  $form['rooms_date_range']['rooms_start_date']['#default_value'] = isset($booking->start_date) ? $booking->start_date : '';
  $form['rooms_date_range']['rooms_end_date']['#default_value'] = isset($booking->end_date) ? $booking->end_date : '';

  // Check startdate and enddate to avoid damage from dirty input.
  $startdate = '';
  if (isset($_GET['startdate'])) {
    $startdate = is_numeric(check_plain($_GET['startdate'])) ? check_plain($_GET['startdate']) : '';
    if ($startdate != '') {
      $form['rooms_date_range']['rooms_start_date']['#default_value'] = gmdate('Y-m-d', $startdate);
    }
  }
  $enddate = '';
  if (isset($_GET['enddate'])) {
    $enddate = is_numeric(check_plain($_GET['enddate'])) ? check_plain($_GET['enddate']) : '';
    if ($enddate != '') {
      $form['rooms_date_range']['rooms_end_date']['#default_value'] = gmdate('Y-m-d', $enddate);
    }
  }
  $unitid = '';
  if (isset($_GET['unitid'])) {
    $unitid = is_numeric(check_plain($_GET['unitid'])) ? check_plain($_GET['unitid']) : '';
    if (rooms_unit_load($unitid) == NULL || $startdate == '' || $enddate == '') {
      $unitid = '';
    }
  }

  // Access to availability information.
  $form['get_availability'] = array(
    '#type' => 'submit',
    '#value' => isset($booking->unit_id) ? t('Re-assign Unit') : t('Check availability'),
    '#submit' => array(
      'rooms_booking_edit_form_availability_submit',
    ),
    '#validate' => array(
      'rooms_form_start_end_dates_validate',
    ),
    '#ajax' => array(
      'callback' => 'rooms_booking_edit_form_availability_callback',
      'wrapper' => 'availability-wrapper',
    ),
    '#prefix' => '<div class="rooms-booking-availability-button-wrapper" id="availability-button">',
    '#suffix' => '</div>',
  );
  $options_list = '';

  // If a unit is assigned get the unit type label.
  if (isset($booking->unit_id)) {
    $unit = rooms_unit_load($booking->unit_id);
    $type_obj = rooms_unit_type_load($unit->type);
    foreach (rooms_unit_get_unit_options($unit) as $option) {
      $option_name = rooms_options_machine_name($option['name']);
      if (isset($booking->data[$option_name])) {
        if (!isset($form_state['values'][$option_name])) {
          $form_state['values'][$option_name] = isset($booking->data[$option_name]);
          $form['data'][$option_name] = array(
            '#type' => 'hidden',
            '#value' => isset($booking->data[$option_name]),
          );
        }
        $quantity = 1;
        if (!isset($form_state['values'][$option_name . ':quantity']) && isset($booking->data[$option_name . ':quantity'])) {
          $form_state['values'][$option_name . ':quantity'] = $booking->data[$option_name . ':quantity'];
          $form['data'][$option_name . ':quantity'] = array(
            '#type' => 'hidden',
            '#value' => $booking->data[$option_name . ':quantity'],
          );
        }
        if (isset($form_state['values'][$option_name . ':quantity']) && $option['operation'] != ROOMS_REPLACE) {
          $quantity = $form_state['values'][$option_name . ':quantity'] + 1;
        }
        $options_list .= $option['name'] . ' : ' . $quantity . ', ';
      }
    }
    $form['unit_id'] = array(
      '#type' => 'hidden',
      '#value' => $booking->unit_id,
    );
  }
  $unit_selected = isset($booking->unit_id) ? t('Currently assigned unit: @unit_name / @type', array(
    '@type' => $type_obj->label,
    '@unit_name' => $unit->name,
  )) : '';
  if ($options_list != '') {
    $unit_selected .= ' ' . t('(Options: !options)', array(
      '!options' => substr($options_list, 0, strlen($options_list) - 2),
    ));
  }
  if (isset($booking->price)) {
    $unit_selected .= '<br />' . t('Price') . ': ' . commerce_currency_format($booking->price, $currency_code);
  }
  $form['availability_fieldset'] = array(
    '#type' => 'fieldset',
    '#description' => $unit_selected,
    '#prefix' => '<div class="rooms-booking-availability-wrapper" id="availability-wrapper">',
    '#suffix' => '</div>',
  );
  $form['b_status'] = array(
    '#type' => 'fieldset',
    '#title' => t('Booking status'),
    '#attributes' => array(
      'class' => array(
        'rooms-booking-status-wrapper',
      ),
    ),
  );
  $form['b_status']['booking_status'] = array(
    '#type' => 'checkbox',
    '#title' => t('Booking Confirmed'),
    '#options' => array(
      '0' => '0',
      '1' => '1',
    ),
    '#default_value' => isset($booking->booking_status) ? $booking->booking_status : '0',
  );
  if ($booking->booking_id != '') {
    if ($booking->order_id != '') {
      $order = commerce_order_load($booking->order_id);
      $order_states = commerce_order_statuses();
      if ($order !== FALSE) {
        $form['order'] = array(
          '#type' => 'fieldset',
          '#title' => t('Order'),
          '#attributes' => array(
            'class' => array(
              'rooms-booking-order-wrapper',
            ),
          ),
        );
        $form['order']['order_link'] = array(
          '#type' => 'markup',
          '#markup' => t('Order status: @order_status', array(
            '@order_status' => $order_states[$order->status]['title'],
          )) . '<br />' . t('Edit <a href="@url">order</a> associated with this booking', array(
            '@url' => url('admin/commerce/orders/' . $booking->order_id . '/edit'),
          )),
        );
      }
    }
  }

  // If submit above pressed and we have dates we can process to assign a unit.
  if (isset($form_state['show_availability_options']) || $unitid != '') {
    $types = rooms_booking_edit_form_get_room_types();

    // Figure out which is the current unit and mark that as selected.
    $selected = '';
    if (isset($form_state['values']['unit_type'])) {
      $selected = $form_state['values']['unit_type'];
    }
    elseif (isset($booking->unit_type)) {
      $selected = $booking->unit_type;
    }
    elseif ($unitid != '') {
      $unit = rooms_unit_load($unitid);
      $selected = $unit->type;
      if ($unit->max_sleeps <= 1) {
        $form['data']['group_size']['#default_value'] = 0;
      }
      $form_state['values']['unit_type'] = $selected;
      $form_state['input']['data']['group_size'] = $unit->max_sleeps <= 1 ? 1 : 2;
      $form_state['input']['data']['group_size_children'] = 0;
      $form_state['input']['rooms_start_date']['date'] = gmdate('d/m/Y', $startdate);
      $form_state['input']['rooms_end_date']['date'] = gmdate('d/m/Y', $enddate);
      $form_state['values']['rooms_start_date'] = gmdate('Y-m-d', $startdate);
      $form_state['values']['rooms_end_date'] = gmdate('Y-m-d', $enddate);
      $form_state['show_availability_options'] = TRUE;
    }

    // Set the unit types - everytime a different type is chosen the available
    // units for that type pop-up.
    $form['availability_fieldset']['unit_type'] = array(
      '#type' => 'select',
      '#title' => t('Unit Type'),
      '#options' => $types,
      '#empty_option' => t('- Select -'),
      '#default_value' => $selected,
      '#ajax' => array(
        'callback' => 'rooms_booking_edit_form_unit_type_callback',
        'wrapper' => 'unit-wrapper',
      ),
    );
    unset($form['unit_id']);

    // This is where the available units will pop up.
    $form['availability_fieldset']['unit_fieldset'] = array(
      '#type' => 'fieldset',
      '#prefix' => '<div class="rooms-booking-unit-wrapper" id="unit-wrapper">',
      '#suffix' => '</div>',
    );
    $form['availability_fieldset']['unit_fieldset']['instructions'] = array();

    // If the user has selected a unit type or we already have a unit assigned
    // show all the available units of that type (Also the already assign unit).
    if (isset($form_state['values']['unit_type']) || isset($booking->unit_type)) {
      $search_unit_type = '';
      if (isset($form_state['values']['unit_type'])) {
        $search_unit_type = $form_state['values']['unit_type'];
      }
      elseif (isset($booking->unit_type)) {
        $search_unit_type = $booking->unit_type;
      }
      if (!empty($search_unit_type)) {
        $childrens_age = array();
        if (isset($form_state['values']['data']['childrens_age'])) {
          $childrens_age = $form_state['values']['data']['childrens_age'];
        }
        $group_size_children = isset($form_state['input']['data']['group_size_children']) ? $form_state['input']['data']['group_size_children'] : 0;
        list($start_date, $end_date) = rooms_form_input_get_start_end_dates($form_state);
        $available_units = rooms_booking_edit_form_get_rooms($search_unit_type, $booking, $start_date, $end_date, $form_state['input']['data']['group_size'], $group_size_children, $childrens_age);
        if ($available_units == ROOMS_NO_ROOMS) {
          $form['availability_fieldset']['unit_fieldset']['instructions'] = array(
            '#markup' => t('No @unit_type units are available for specified party size on the chosen dates.', array(
              '@unit_type' => $search_unit_type,
            )),
          );
        }
        else {
          foreach ($available_units as $type => $units_per_price) {

            // Load the type obj and set a title.
            $type_obj = rooms_unit_type_load($type);
            $form['availability_fieldset']['unit_fieldset']['type'] = array(
              '#type' => 'fieldset',
              '#title' => t('@unit_type available bookable units', array(
                '@unit_type' => $type_obj->label,
              )),
              '#attributes' => array(
                'class' => array(
                  'rooms-booking-unit-type-wrapper',
                ),
              ),
            );
            $form['availability_fieldset']['unit_fieldset']['instructions'] = array(
              '#markup' => t('The following units are available for the chosen dates; please select one.'),
            );
            $options = array();

            // Create elements based on type/price categorisation.
            foreach ($units_per_price as $price => $units) {
              foreach ($units as $unit) {
                $options[$unit['unit']->unit_id] = $unit['unit']->name . ' - ' . t('Cost') . ': ' . commerce_currency_format($units[key($units)]['price'] * 100, $currency_code);
              }
            }
            $form['availability_fieldset']['unit_fieldset']['type']['unit_id'] = array(
              '#type' => 'radios',
              '#options' => $options,
              '#validated' => TRUE,
              '#default_value' => isset($booking->unit_id) ? $booking->unit_id : '',
              '#ajax' => array(
                'callback' => 'rooms_booking_select_unit_callback',
                'wrapper' => 'options-wrapper',
              ),
            );
            if (isset($unitid)) {
              $form['availability_fieldset']['unit_fieldset']['type']['unit_id']['#default_value'] = $unitid;
            }
            $form['availability_fieldset']['unit_fieldset']['options_fieldset'] = array(
              '#type' => 'fieldset',
              '#prefix' => '<div class="rooms-booking-options-wrapper" id="options-wrapper">',
              '#suffix' => '</div>',
            );

            // If a unit is selected.
            if (!empty($form_state['values']['unit_id']) || isset($booking->unit_id) || $unitid != '') {
              if ($unitid != '') {
                $unit_id = $unitid;
              }
              else {
                $unit_id = isset($form_state['values']['unit_id']) ? $form_state['values']['unit_id'] : $booking->unit_id;
              }
              $unit = rooms_unit_load($unit_id);
              foreach (rooms_unit_get_unit_options($unit) as $option) {
                if (!isset($form['availability_fieldset']['unit_fieldset']['options_fieldset']['#title'])) {
                  $form['availability_fieldset']['unit_fieldset']['options_fieldset']['#title'] = t('Available options for @unit_name', array(
                    '@unit_name' => $unit->name,
                  ));
                }
                $option_name = rooms_options_machine_name($option['name']);
                $form['availability_fieldset']['unit_fieldset']['options_fieldset'][$option_name] = array(
                  '#type' => 'checkbox',
                  '#title' => t($option['name']),
                  '#default_value' => isset($booking->data[$option_name]) ? '1' : '0',
                  '#ajax' => array(
                    'callback' => 'rooms_booking_select_unit_callback',
                    'wrapper' => 'options-wrapper',
                  ),
                );
                if ($option['type'] == ROOMS_OPTION_MANDATORY) {
                  $form['availability_fieldset']['unit_fieldset']['options_fieldset'][$option_name]['#default_value'] = '1';
                  $form['availability_fieldset']['unit_fieldset']['options_fieldset'][$option_name]['#disabled'] = TRUE;
                }

                // Show quantity field selector if an option quantity is set.
                if (is_numeric($option['quantity']) && isset($form_state['values'][$option_name]) && $form_state['values'][$option_name] == 1 && $option['quantity'] > 1) {
                  $form['availability_fieldset']['unit_fieldset']['options_fieldset'][$option_name . ':quantity'] = array(
                    '#type' => 'select',
                    '#title' => t('Quantity'),
                    '#options' => rooms_range(1, $option['quantity']),
                    '#default_value' => $form_state['values'][$option_name . ':quantity'],
                    '#ajax' => array(
                      'callback' => 'rooms_booking_select_unit_callback',
                      'wrapper' => 'options-wrapper',
                    ),
                  );
                }
              }

              // Create Price Modifiers.
              $price_modifiers = array();
              foreach (rooms_unit_get_unit_options($unit) as $option) {
                $option_name = rooms_options_machine_name($option['name']);
                if ($option['type'] == ROOMS_OPTION_MANDATORY) {
                  $quantity = 1;
                  if (isset($form_state['values'][$option_name . ':quantity']) && $option['operation'] != ROOMS_REPLACE) {
                    $quantity = $form_state['values'][$option_name . ':quantity'] + 1;
                  }
                  $price_modifiers[$option_name] = array(
                    '#type' => ROOMS_DYNAMIC_MODIFIER,
                    '#op_type' => $option['operation'],
                    '#amount' => $option['value'],
                    '#quantity' => $quantity,
                  );
                }
                elseif (isset($form_state['values'][$option_name])) {
                  if ($form_state['values'][$option_name] == 1) {
                    $quantity = 1;
                    if (isset($form_state['values'][$option_name . ':quantity']) && $option['operation'] != ROOMS_REPLACE) {
                      $quantity = $form_state['values'][$option_name . ':quantity'] + 1;
                    }
                    if ($option['type'] != ROOMS_OPTION_ONREQUEST) {
                      $price_modifiers[$option_name] = array(
                        '#type' => ROOMS_DYNAMIC_MODIFIER,
                        '#op_type' => $option['operation'],
                        '#amount' => $option['value'],
                        '#quantity' => $quantity,
                      );
                    }
                  }
                }
              }
              $form['availability_fieldset']['unit_fieldset']['options_fieldset']['price'] = array(
                '#type' => 'textfield',
                '#title' => t('Price'),
                '#default_value' => '',
                '#size' => '10',
                '#required' => TRUE,
              );
              list($start_date, $end_date) = rooms_form_values_get_start_end_dates($form_state);
              $group_size = isset($form_state['values']['data']['group_size']) ? $form_state['values']['data']['group_size'] : $form_state['input']['data']['group_size'];
              if (variable_get('rooms_booking_display_children', ROOMS_DISPLAY_CHILDREN) == ROOMS_DISPLAY_CHILDREN) {
                $group_size_children = isset($form_state['values']['data']['group_size']) ? $form_state['values']['data']['group_size_children'] : $form_state['input']['data']['group_size_children'];
                $childrens_age = isset($form_state['values']['data']['childrens_age']) ? $form_state['values']['data']['childrens_age'] : array();
              }
              else {
                $group_size_children = 0;
                $childrens_age = array();
              }
              $booking_info = array(
                'start_date' => clone $start_date,
                'end_date' => clone $end_date,
                'unit' => rooms_unit_load($unit_id),
                'booking_parameters' => array(
                  'group_size' => $group_size,
                  'group_size_children' => $group_size_children,
                  'childrens_age' => $childrens_age,
                ),
              );

              // Give other modules a chance to change the price modifiers.
              drupal_alter('rooms_price_modifier', $price_modifiers, $booking_info);

              // Apply price modifiers and replace unit price.
              $price_calendar = new UnitPricingCalendar($unit_id, $price_modifiers);
              $end_date
                ->sub(new DateInterval('P1D'));
              $new_price = $price_calendar
                ->calculatePrice($start_date, $end_date, $group_size, $group_size_children, $childrens_age);
              $new_price = $new_price['full_price'];

              // When user press 'Re-assign Unit' button we don't replace price.
              if (isset($form_state['triggering_element'])) {
                if ($form_state['triggering_element']['#value'] == t('Re-assign Unit') && $form_state['triggering_element']['#name'] == 'op') {
                  $form['availability_fieldset']['unit_fieldset']['options_fieldset']['price']['#value'] = number_format($booking->price / 100, 2, '.', '');
                }
                else {
                  $form['availability_fieldset']['unit_fieldset']['options_fieldset']['price']['#value'] = number_format($new_price, 2, '.', '');
                }
              }
              else {
                $form['availability_fieldset']['unit_fieldset']['options_fieldset']['price']['#value'] = number_format($new_price, 2, '.', '');
              }
            }
          }
        }
      }
      else {
        $form['availability_fieldset']['unit_fieldset']['instructions'] = array(
          '#markup' => t('You must select a Unit type to choose a unit'),
        );
      }
    }
  }

  // Add the field related form elements.
  $form_state['rooms_booking'] = $booking;
  field_attach_form('rooms_booking', $booking, $form, $form_state);

  // Set an #ajax callback for start/end date elements for edited bookings.
  if (is_numeric($booking->booking_id)) {
    $form['rooms_date_range']['rooms_start_date']['#ajax'] = array(
      'callback' => 'rooms_booking_date_ajax_callback',
      'event' => 'blur',
    );
    $form['rooms_date_range']['rooms_end_date']['#ajax'] = array(
      'callback' => 'rooms_booking_date_ajax_callback',
      'event' => 'blur',
    );
  }

  // Management vertical tabs.
  $form['additional_settings'] = array(
    '#type' => 'vertical_tabs',
    '#weight' => 99,
  );

  // Add the user account and e-mail fields.
  $form['user'] = array(
    '#type' => 'fieldset',
    '#title' => t('User information'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#access' => user_access('bypass rooms_booking entities access'),
    '#group' => 'additional_settings',
    '#attached' => array(
      'js' => array(
        drupal_get_path('module', 'rooms_booking') . '/js/rooms_booking.js',
        array(
          'type' => 'setting',
          'data' => array(
            'anonymous' => variable_get('anonymous', t('Anonymous')),
          ),
        ),
      ),
    ),
    '#weight' => 30,
  );
  $form['user']['owner_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Owned by'),
    '#description' => t('Leave blank for %anonymous.', array(
      '%anonymous' => variable_get('anonymous', t('Anonymous')),
    )),
    '#maxlength' => 60,
    '#autocomplete_path' => 'user/autocomplete',
    '#default_value' => !empty($booking->owner_name) ? $booking->owner_name : '',
    '#weight' => -1,
  );

  // Add a log checkbox and timestamp field to a history tab.
  $form['booking_history'] = array(
    '#type' => 'fieldset',
    '#title' => t('Booking history'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#group' => 'additional_settings',
    '#attached' => array(
      'js' => array(
        drupal_get_path('module', 'rooms_booking') . '/js/rooms_booking.js',
      ),
    ),
    '#weight' => 40,
  );
  $form['booking_history']['date'] = array(
    '#type' => 'textfield',
    '#title' => t('Created on'),
    '#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array(
      '%time' => !empty($booking->date) ? date_format(date_create($booking->date), 'Y-m-d H:i:s O') : format_date($booking->created, 'custom', 'Y-m-d H:i:s O'),
      '%timezone' => !empty($booking->date) ? date_format(date_create($booking->date), 'O') : format_date($booking->created, 'custom', 'O'),
    )),
    '#maxlength' => 25,
    '#default_value' => !empty($booking->created) ? format_date($booking->created, 'custom', 'Y-m-d H:i:s O') : '',
  );
  $form['booking_history']['created'] = array(
    '#type' => 'hidden',
    '#value' => !empty($booking->created) ? format_date($booking->created, 'short') : '',
    '#attributes' => array(
      'id' => 'edit-created',
    ),
  );
  $form['booking_history']['changed'] = array(
    '#type' => 'hidden',
    '#value' => !empty($booking->changed) ? format_date($booking->changed, 'short') : '',
    '#attributes' => array(
      'id' => 'edit-changed',
    ),
  );
  $form['actions'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'class' => array(
        'form-actions',
      ),
    ),
    '#weight' => 400,
  );

  // We add the form's #submit array to this button along with the actual submit
  // handler to preserve any submit handlers added by a form callback_wrapper.
  $submit = array();
  if (!empty($form['#submit'])) {
    $submit += $form['#submit'];
  }

  // Wrapper to show validation messages where the assigned dates are changed
  // and the price is not re-assigned.
  $form['availability_fieldset']['assigned_dates_msg'] = array(
    '#markup' => '<div id="assigned-dates-msg"></div>',
  );
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save Booking'),
    '#submit' => $submit + array(
      'rooms_booking_edit_form_submit',
    ),
  );
  if (!empty($booking->name) && rooms_booking_access('delete', $booking)) {
    $form['actions']['delete'] = array(
      '#type' => 'submit',
      '#value' => t('Delete Booking'),
      '#submit' => $submit + array(
        'rooms_booking_form_submit_delete',
      ),
      '#weight' => 45,
    );
  }

  // When the form is in a modal window display a cancel button.
  if (isset($form_state['ajax']) && $form_state['ajax'] == TRUE) {
    $form['actions']['cancel'] = array(
      '#markup' => l(t('Cancel'), '', array(
        'attributes' => array(
          'class' => array(
            'ctools-close-modal',
          ),
        ),
      )),
      '#weight' => 50,
    );
  }

  // We append the validate handler to #validate in case a form callback_wrapper
  // is used to add validate handlers earlier.
  $form['#validate'][] = 'rooms_form_start_end_dates_validate';
  $form['#validate'][] = 'rooms_booking_edit_form_validate';
  return $form;
}