Prices for a week and a month

Hello everyone,

Is there a way to have multiple prices for a listing, such as a weekend price (Fri-Sun), a weekly price (7 days), and a monthly price (30 days)? I know there are daily prices, and it’s also possible to set different prices for specific days, but that’s not what I’m trying to achieve. Ideally, I need four pricing options: one per day, one for 3 days (weekend), one for 7 days (full week), and one for 30 days (full month).

I am using HivePress with all extensions, including Marketplace, Bookings, etc. I was wondering if the tier price option might be suitable for this case. However, the issue I’m facing is that tier prices do not appear in the RentalHive theme. I’m unsure if this is a bug or something else. I have added tier prices for a listing, but they are not visible on the listing page.

Thanks in advance for your help.

Best regards, Vik

Hi,

Your request is related to a premium product. Please add the license key to the account settings to access forums for your purchased products and get the Premium Support badge on your profile. If the support for your purchase has expired, please consider renewing it for assistance Renew Support | HivePress

Hi Andrii,

done, thanks for this tip! I didn’t know I should do that. However, my support has already expired. Do I need to renew the license for all extensions only, or do I also need to do the same with the RentalHive license?

Hi,

You can extend the premium support for RentalHive theme.

Ok great, done.

Hi,

Thank you for renewing!

This extension version does not have this feature, but we plan to add it in future updates. However, you can use a workaround, the discount feature How to enable discounts for bookings - HivePress Help Center, where the number is days. Then, you can do this using the example of Airbnb, i.e., for 7 days, you can set a certain discount; for 30 days, another discount, etc. And as soon as the 29 days are changed to 30 days, the next tier will be applied.

​I hope this is helpful to you

Hi Andrii,

I knew that you would suggest this option :sweat_smile:. I had this in mind, but unfortunately, that’s not how we want it.

Let me ask you something else: Is there a hook or filter to override the booking price while making the booking (not after the booking is made) but still on the listing page, where the users can see the current price, while adding extras, choose the date etc? I can’t find the logic or function where the prices are calculated. If I knew where this happens, I could add the prices that I need.

Thank you in advance.

Sorry for the delay.

You can try using hivepress/v1/models/listing/cart filter hook, it’s used when the price is calculated on the listing page and before the redirect to the booking confirmation page. This way it’s possible to adjust any pricing parameters (quantity, fees, etc). You can use the hivepress()->helper->is_rest() check to apply the code to the listing page price calculation only.

Hope this helps

Hello Ihor,

thank you very much for the nudge in the right direction. The “hivepress/v1/models/listing/cart” filter was exactly what I needed. I couldn’t directly change the cart price with it, but by additionally using the WooCommerce action “add_action(‘woocommerce_before_calculate_totals’)”, I was able to achieve what I wanted. The price is now updated and displayed immediately when selecting a price or package.

Before clicking a price:

After clicking a price:

1 Like

Hello Viktor!

I have also been lookign for this code with almost the same functionality. You wouldn’t mind sharing the whole code snippet used? Is this also updated on the Add listings-page?

I would really like to have the price set per day but with different daily prices based on how many days you make the booking. For example $100/day if you order <3 days. $80/day if you book between 3 and 6 days, and $50/day if you book for 7 or more days. So it is almost like yours… Would really appriciate your help, or from Ihor och Andrii. :slight_smile:

Hey @aming4stars,

sorry for the late response. This is what I ended up with. I’m using the tier price option for the different prices, btw.

To output the different prices, I created a shortcode:

function display_hp_price_tiers() {
  global $post;

  if ($post && $post->post_type === 'hp_listing') {

    $price_tiers = get_post_meta($post->ID, 'hp_price_tiers', true);
    $price_tiers = maybe_unserialize($price_tiers);

    if (!empty($price_tiers) && is_array($price_tiers)) {
      $output = '<div class="hp-listing__attributes hp-listing__attributes--primary hp-block preisliste">';

      $output .= '<div class="package-prices">';

      foreach ($price_tiers as $tier) {
        if (isset($tier['name'], $tier['price'])) {
          $translations = [
            'Daily rental' => __('Daily rental', 'textdomain'),
            'Weekend rental' => __('Weekend rental', 'textdomain'),
            'Weekly rental' => __('Weekly rental', 'textdomain'),
            'Monthly rental' => __('Monthly rental', 'textdomain')
          ];
          $translated_name = isset($translations[$tier['name']]) ? $translations[$tier['name']] : $tier['name'];

          $output .= '<div class="price-option" data-price="' . esc_attr($tier['price']) . '">';
          $description = !empty($tier['description']) ? esc_html($tier['description']) : '0';
          $output .= '<div class="package-name" data-name="'. esc_html($tier['name']) .'">'. esc_html($translated_name) . '</div>';
          $output .= '<div class="package-price">' . esc_html($tier['price']) . ' €</div><div class="package-detail">'. __('incl.', 'textdomain') . ' ' .$description . ' KM</div>';
          $output .= '</div>';
        }
      }

      $output .= '</div></div>';
      return $output;
    }
  }

  return 'No prices available.';
}

add_shortcode('package_prices', 'display_hp_price_tiers');

To output the prices, I’ve created a hivepress Template for listings and use the shortcode [package_prices] to get this:

The whole code for chaning the prices (sorry I used no comments):

add_action('init', function() {
  if (!session_id()) {
    session_start();
  }
});


add_action('wp_footer', function() {
  if (is_singular('hp_listing')) {
    ?>
    <script>
      jQuery(document).ready(function($) {
        $('.price-option').on('click', function() {
          var packageName = $(this).find('.package-name').data('name');
          var listingId = '<?php echo get_the_ID(); ?>';

          if (!packageName) {
            return;
          }

          localStorage.setItem('selected_listing_package_' + listingId, packageName);

          $('.price-option').removeClass('selected');
          $(this).addClass('selected');

          $.ajax({
            url: '<?php echo admin_url('admin-ajax.php'); ?>',
            type: 'POST',
            data: {
              action: 'save_selected_package',
              listing_id: listingId,
              package_name: packageName
            },
            success: function(response) {
              if (response.success) {
                $('.hp-form--booking-make .hp-field--date-range .flatpickr-input').trigger('change');
                $('.hp-form--booking-make').addClass('notdisabled');
              }
            }
          });
        });
      });
    </script>
    <?php
  }
});

add_action('wp_ajax_save_selected_package', 'save_selected_package');
add_action('wp_ajax_nopriv_save_selected_package', 'save_selected_package');


function save_selected_package() {
  if (!isset($_POST['listing_id']) || !isset($_POST['package_name'])) {
    wp_send_json_error(['message' => 'Fehlende Parameter']);
    wp_die();
  }

  $listing_id = intval($_POST['listing_id']);
  $package_name = sanitize_text_field($_POST['package_name']);

  // Paketname in der Session speichern
  $_SESSION['selected_package_' . $listing_id] = $package_name;

  wp_send_json_success(['package_name' => $package_name]);
  wp_die();
}


add_filter('hivepress/v1/models/listing/cart', function ($cart, $listing) {

  if (!$listing) {
    return $cart;
  }

  $listing_id = $listing->get_id();

  $selected_package = $_SESSION['selected_package_' . $listing_id] ?? '';

  if (empty($selected_package)) {
    return $cart;
  }

  $tiers = get_post_meta($listing_id, 'hp_price_tiers', true);

  if (!$tiers || !is_array($tiers)) {
    return $cart;
  }

  $selected_price = null;
  foreach ($tiers as $tier) {
    if ($tier['name'] === $selected_package) {
      $selected_price = $tier['price'];
      break;
    }
  }

  if (!$selected_price) {
    return $cart;
  }

  $cart['meta']['price'] = floatval($selected_price);
  $cart['args']['_quantity'] = 1; // Menge immer 1 setzen

  $_SESSION['selected_package_price'] = floatval($selected_price);

  return $cart;

}, 1000, 2);


add_action('woocommerce_before_calculate_totals', function($cart) {
  if (is_admin() && !defined('DOING_AJAX')) return;

  foreach ($cart->get_cart() as $cart_item) {
    if (isset($cart_item['data'])) {
      $product = $cart_item['data'];
      $custom_price = $_SESSION['selected_package_price'] ?? null;

      if (!$custom_price) {
        continue;
      }

      $cart_item['data']->set_price($custom_price);
    }
  }
});

I’m sure there are better solutions for this, but for me, this was a big deal and it seems to work just as I need it to! :sweat_smile:

I really hope this helps you.

Cheers, Viktor

1 Like