You are here

rooms_periodic_pricing.module in Rooms - Drupal Booking for Hotels, B&Bs and Vacation Rentals 7

File

modules/rooms_pricing/modules/rooms_periodic_pricing/rooms_periodic_pricing.module
View source
<?php

/**
 * Implements hook_form_FORM_ID_alter().
 */
function rooms_periodic_pricing_form_rooms_unit_edit_form_alter(&$form, &$form_state) {
  $unit = $form['#entity'];
  $form['weekly_monthly_discount'] = array(
    '#type' => 'fieldset',
    '#title' => t('Weekly/Monthly discount'),
    '#tree' => FALSE,
    '#weight' => -97,
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['weekly_monthly_discount']['weekly_discount'] = array(
    '#type' => 'textfield',
    '#title' => t('Weekly discount'),
    '#default_value' => isset($unit->weekly_discount) ? $unit->weekly_discount : '',
    '#size' => '5',
    '#field_suffix' => t('% (> 7 days)'),
    '#description' => t('You can provide here a percentage that will be applied as a discount to the standard cost for bookings that exceed 7 days.'),
    '#maxlength' => 10,
  );
  $form['weekly_monthly_discount']['monthly_discount'] = array(
    '#type' => 'textfield',
    '#title' => t('Monthly discount'),
    '#default_value' => isset($unit->monthly_discount) ? $unit->monthly_discount : '',
    '#size' => '5',
    '#field_suffix' => t('% (> 28 days)'),
    '#description' => t('You can provide here a percentage that will be applied as a discount to the standard cost for bookings that exceed 28 days.'),
    '#maxlength' => 10,
  );
  if (isset($unit->weekly_discount) && $unit->weekly_discount == '0.00') {
    $form['weekly_monthly_discount']['weekly_discount']['#default_value'] = '';
  }
  if (isset($unit->monthly_discount) && $unit->monthly_discount == '0.00') {
    $form['weekly_monthly_discount']['monthly_discount']['#default_value'] = '';
  }
  $form['#validate'][] = 'rooms_periodic_pricing_form_rooms_unit_edit_form_validate';
  $form['#attached']['css'][] = drupal_get_path('module', 'rooms_periodic_pricing') . '/css/rooms_periodic_pricing.css';
}

/**
 * Validate 'Weekly discount' and 'Monthly discount'.
 */
function rooms_periodic_pricing_form_rooms_unit_edit_form_validate(&$form, &$form_state) {
  if (empty($form_state['values']['weekly_discount'])) {
    $form_state['values']['weekly_discount'] = '0';
  }
  elseif (!empty($form_state['values']['weekly_discount'])) {
    if (!is_numeric($form_state['values']['weekly_discount'])) {
      form_set_error('weekly_discount', t('%name: you must enter a numeric value for the weekly percentage.', array(
        '%name' => t('Weekly discount'),
      )));
    }
    elseif ($form_state['values']['weekly_discount'] < 0 || $form_state['values']['weekly_discount'] > 100) {
      form_set_error('weekly_discount', t('%name: you must enter a valid value for the weekly percentage.', array(
        '%name' => t('Weekly discount'),
      )));
    }
  }
  if (empty($form_state['values']['monthly_discount'])) {
    $form_state['values']['monthly_discount'] = '0';
  }
  elseif (!empty($form_state['values']['monthly_discount'])) {
    if (!is_numeric($form_state['values']['monthly_discount'])) {
      form_set_error('monthly_discount', t('%name: you must enter a numeric value for the monthly percentage.', array(
        '%name' => t('Monthly discount'),
      )));
    }
    elseif ($form_state['values']['monthly_discount'] < 0 || $form_state['values']['monthly_discount'] > 100) {
      form_set_error('weekly_discount', t('%name: you must enter a valid value for the monthly percentage.', array(
        '%name' => t('Monthly discount'),
      )));
    }
  }
}

/**
 * Implements hook_rooms_string_alter().
 */
function rooms_periodic_pricing_rooms_string_alter(&$string_suggestions, $context) {
  if ($context['#purpose'] == 'display_base_price') {
    $string_suggestion = reset($string_suggestions);
    if (module_exists('commerce_multicurrency')) {
      $currency_code = commerce_multicurrency_get_user_currency_code();
    }
    else {
      $currency_code = commerce_default_currency();
    }
    $price = $context['#data']['price'];
    if ($context['#component'] == 'units_per_type_form') {
      $units = reset($context['#data']['units'][$price]);
      $unit = $units['unit'];
      $price_log = $units['price_log'];
    }
    elseif ($context['#component'] == 'book_unit_form_builder') {
      $unit = $context['#data']['unit'];
      $price_log = $context['#data']['price_log'];
    }
    $start_date = $context['#data']['arrival'];
    $end_date = $context['#data']['departure'];
    if (isset($price_log['modifiers']['rooms_periodic_pricing']['dynamic_modifier']['pre'])) {
      $pre_price = $price_log['modifiers']['rooms_periodic_pricing']['dynamic_modifier']['pre'];
      $post_price = $price_log['modifiers']['rooms_periodic_pricing']['dynamic_modifier']['post'];
      $price_amount = ($pre_price - $post_price) * 100;
      if (module_exists('commerce_multicurrency')) {
        $price_amount = commerce_currency_convert($price_amount, commerce_default_currency(), $currency_code);
      }
      $string_suggestion .= ' ' . t('(Reduction of @amount)', array(
        '@amount' => commerce_currency_format($price_amount, $currency_code),
      ));
    }
    $string_suggestions[] = $string_suggestion;
  }
}

/**
 * Implements hook_rooms_price_modifier_alter().
 */
function rooms_periodic_pricing_rooms_price_modifier_alter(&$price_modifiers, $booking_info) {
  if (!isset($price_modifiers['rooms_periodic_pricing'])) {
    $unit = $booking_info['unit'];
    $end_date = $booking_info['end_date'];
    $start_date = $booking_info['start_date'];
    $weeks_months_days = rooms_periodic_pricing_calculate_weeks_months_days($start_date, $end_date);

    // If "Monthly discount" is set and the current period is greater than or equal to 28 days.
    if ($weeks_months_days['months'] > 0 && $unit->monthly_discount > 0) {

      // Add a new price modifier to decrease old price with monthly discount.
      $price_modifiers['rooms_periodic_pricing'] = array(
        '#type' => ROOMS_DYNAMIC_MODIFIER,
        '#quantity' => 1,
        '#op_type' => ROOMS_DECREASE,
        '#amount' => $unit->monthly_discount,
      );
    }
    elseif ($weeks_months_days['total_weeks'] > 0 && $unit->weekly_discount > 0) {

      // Add a new price modifier to decrease old price with weekly discount.
      $price_modifiers['rooms_periodic_pricing'] = array(
        '#type' => ROOMS_DYNAMIC_MODIFIER,
        '#quantity' => 1,
        '#op_type' => ROOMS_DECREASE,
        '#amount' => $unit->weekly_discount,
      );
    }
  }
}

/**
 * Calculate number of days, weeks and months in a given period.
 *
 * @param DateTime $start_date
 * The starting date
 *
 * @param DateTime $end_date
 * The end date of our range
 *
 * @return array
 */
function rooms_periodic_pricing_calculate_weeks_months_days($start_date, $end_date) {
  $days = $end_date
    ->diff($start_date)->days;
  $weeks = floor($days / 7);
  $months = floor($weeks / 4);
  $more_weeks = $weeks % 4;
  $more_days = $days % 7;
  return array(
    'total_days' => $days,
    'total_weeks' => $weeks,
    'more_days' => $more_days,
    'more_weeks' => $more_weeks,
    'months' => $months,
  );
}