🏨 Hotel Booking Enhancements: - Implemented Eagle Booking Advanced Pricing add-on - Added Booking.com-style rate management system - Created professional calendar interface for pricing - Integrated deals and discounts functionality 💰 Advanced Pricing Features: - Dynamic pricing models (per room, per person, per adult) - Base rates, adult rates, and child rates management - Length of stay discounts and early bird deals - Mobile rates and secret deals implementation - Seasonal promotions and flash sales 📅 Availability Management: - Real-time availability tracking - Stop sell and restriction controls - Closed to arrival/departure functionality - Minimum/maximum stay requirements - Automatic sold-out management 💳 Payment Integration: - Maintained Redsys payment gateway integration - Seamless integration with existing Eagle Booking - No modifications to core Eagle Booking plugin 🛠️ Technical Implementation: - Custom database tables for advanced pricing - WordPress hooks and filters integration - AJAX-powered admin interface - Data migration from existing Eagle Booking - Professional calendar view for revenue management 📊 Admin Interface: - Booking.com-style management dashboard - Visual rate and availability calendar - Bulk operations for date ranges - Statistics and analytics dashboard - Modal dialogs for quick editing 🔧 Code Quality: - WordPress coding standards compliance - Secure database operations with prepared statements - Proper input validation and sanitization - Error handling and logging - Responsive admin interface 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
487 lines
11 KiB
PHP
487 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Eagle Booking Advanced Pricing - Helper Functions
|
|
*
|
|
* @package EB_Advanced_Pricing
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
/**
|
|
* Get Eagle Booking Advanced Pricing instance
|
|
*
|
|
* @return EB_Advanced_Pricing
|
|
*/
|
|
function eb_ap() {
|
|
return EB_Advanced_Pricing::instance();
|
|
}
|
|
|
|
/**
|
|
* Get rates instance
|
|
*
|
|
* @return EB_AP_Rates
|
|
*/
|
|
function eb_ap_rates() {
|
|
return EB_AP_Rates::instance();
|
|
}
|
|
|
|
/**
|
|
* Get availability instance
|
|
*
|
|
* @return EB_AP_Availability
|
|
*/
|
|
function eb_ap_availability() {
|
|
return EB_AP_Availability::instance();
|
|
}
|
|
|
|
/**
|
|
* Get deals instance
|
|
*
|
|
* @return EB_AP_Deals
|
|
*/
|
|
function eb_ap_deals() {
|
|
return EB_AP_Deals::instance();
|
|
}
|
|
|
|
/**
|
|
* Calculate advanced price for a room
|
|
*
|
|
* @param int $room_id
|
|
* @param string $checkin_date
|
|
* @param string $checkout_date
|
|
* @param int $adults
|
|
* @param int $children
|
|
* @return array
|
|
*/
|
|
function eb_ap_calculate_price($room_id, $checkin_date, $checkout_date, $adults = 1, $children = 0) {
|
|
$start = new DateTime($checkin_date);
|
|
$end = new DateTime($checkout_date);
|
|
$nights = $end->diff($start)->days;
|
|
|
|
$total_price = 0;
|
|
$night_prices = array();
|
|
$applied_deals = array();
|
|
|
|
// Calculate price for each night
|
|
$current_date = clone $start;
|
|
for ($i = 0; $i < $nights; $i++) {
|
|
$date_str = $current_date->format('Y-m-d');
|
|
$night_price = eb_ap_rates()->calculate_price($room_id, $date_str, $adults, $children);
|
|
|
|
$night_prices[] = array(
|
|
'date' => $date_str,
|
|
'price' => $night_price
|
|
);
|
|
|
|
$total_price += $night_price;
|
|
$current_date->add(new DateInterval('P1D'));
|
|
}
|
|
|
|
// Apply deals
|
|
$deal_result = eb_ap_deals()->apply_deals(
|
|
$total_price,
|
|
$room_id,
|
|
$checkin_date,
|
|
$checkout_date,
|
|
$nights,
|
|
current_time('Y-m-d')
|
|
);
|
|
|
|
return array(
|
|
'room_id' => $room_id,
|
|
'checkin_date' => $checkin_date,
|
|
'checkout_date' => $checkout_date,
|
|
'nights' => $nights,
|
|
'adults' => $adults,
|
|
'children' => $children,
|
|
'night_prices' => $night_prices,
|
|
'subtotal' => $total_price,
|
|
'original_price' => $deal_result['original_price'],
|
|
'discounted_price' => $deal_result['discounted_price'],
|
|
'discount_amount' => $deal_result['discount_amount'],
|
|
'applied_deals' => $deal_result['applied_deals'],
|
|
'final_price' => $deal_result['discounted_price']
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if room is available for booking
|
|
*
|
|
* @param int $room_id
|
|
* @param string $checkin_date
|
|
* @param string $checkout_date
|
|
* @param int $rooms_needed
|
|
* @return bool
|
|
*/
|
|
function eb_ap_check_availability($room_id, $checkin_date, $checkout_date, $rooms_needed = 1) {
|
|
return eb_ap_availability()->is_available_range($room_id, $checkin_date, $checkout_date, $rooms_needed);
|
|
}
|
|
|
|
/**
|
|
* Check if arrival is allowed on date
|
|
*
|
|
* @param int $room_id
|
|
* @param string $checkin_date
|
|
* @return bool
|
|
*/
|
|
function eb_ap_check_arrival($room_id, $checkin_date) {
|
|
return eb_ap_availability()->is_arrival_allowed($room_id, $checkin_date);
|
|
}
|
|
|
|
/**
|
|
* Check if departure is allowed on date
|
|
*
|
|
* @param int $room_id
|
|
* @param string $checkout_date
|
|
* @return bool
|
|
*/
|
|
function eb_ap_check_departure($room_id, $checkout_date) {
|
|
return eb_ap_availability()->is_departure_allowed($room_id, $checkout_date);
|
|
}
|
|
|
|
/**
|
|
* Get room minimum rate for a date range
|
|
*
|
|
* @param int $room_id
|
|
* @param string $start_date
|
|
* @param string $end_date
|
|
* @return float
|
|
*/
|
|
function eb_ap_get_min_rate($room_id, $start_date, $end_date) {
|
|
return eb_ap_rates()->get_min_rate($room_id, $start_date, $end_date);
|
|
}
|
|
|
|
/**
|
|
* Get active deals for a room
|
|
*
|
|
* @param int $room_id
|
|
* @param string $checkin_date
|
|
* @param string $checkout_date
|
|
* @param int $nights
|
|
* @return array
|
|
*/
|
|
function eb_ap_get_active_deals($room_id, $checkin_date, $checkout_date, $nights) {
|
|
return eb_ap_deals()->get_applicable_deals($room_id, $checkin_date, $checkout_date, $nights);
|
|
}
|
|
|
|
/**
|
|
* Format price with currency
|
|
*
|
|
* @param float $price
|
|
* @param bool $include_currency
|
|
* @return string
|
|
*/
|
|
function eb_ap_format_price($price, $include_currency = true) {
|
|
if (function_exists('eb_price') && $include_currency) {
|
|
return eb_price($price);
|
|
} elseif (function_exists('eb_formatted_price')) {
|
|
return eb_formatted_price($price, false);
|
|
} else {
|
|
return number_format($price, 2);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get available rooms for a date
|
|
*
|
|
* @param int $room_id
|
|
* @param string $date
|
|
* @return int
|
|
*/
|
|
function eb_ap_get_available_rooms($room_id, $date) {
|
|
$availability = eb_ap_availability()->get_availability($room_id, $date);
|
|
return $availability ? $availability['available_rooms'] : 0;
|
|
}
|
|
|
|
/**
|
|
* Reserve rooms for a booking
|
|
*
|
|
* @param int $room_id
|
|
* @param string $checkin_date
|
|
* @param string $checkout_date
|
|
* @param int $rooms_count
|
|
* @return bool
|
|
*/
|
|
function eb_ap_reserve_rooms($room_id, $checkin_date, $checkout_date, $rooms_count = 1) {
|
|
return eb_ap_availability()->reserve_rooms($room_id, $checkin_date, $checkout_date, $rooms_count);
|
|
}
|
|
|
|
/**
|
|
* Release rooms from a booking
|
|
*
|
|
* @param int $room_id
|
|
* @param string $checkin_date
|
|
* @param string $checkout_date
|
|
* @param int $rooms_count
|
|
* @return bool
|
|
*/
|
|
function eb_ap_release_rooms($room_id, $checkin_date, $checkout_date, $rooms_count = 1) {
|
|
return eb_ap_availability()->release_rooms($room_id, $checkin_date, $checkout_date, $rooms_count);
|
|
}
|
|
|
|
/**
|
|
* Get deal types
|
|
*
|
|
* @return array
|
|
*/
|
|
function eb_ap_get_deal_types() {
|
|
return eb_ap_deals()->get_deal_types();
|
|
}
|
|
|
|
/**
|
|
* Get discount types
|
|
*
|
|
* @return array
|
|
*/
|
|
function eb_ap_get_discount_types() {
|
|
return eb_ap_deals()->get_discount_types();
|
|
}
|
|
|
|
/**
|
|
* Create early bird deal
|
|
*
|
|
* @param int $room_id
|
|
* @param string $name
|
|
* @param int $advance_days
|
|
* @param float $discount_value
|
|
* @param string $discount_type
|
|
* @param string $date_from
|
|
* @param string $date_to
|
|
* @return bool|int
|
|
*/
|
|
function eb_ap_create_early_bird_deal($room_id, $name, $advance_days, $discount_value, $discount_type, $date_from, $date_to) {
|
|
return eb_ap_deals()->create_early_bird_deal($room_id, $name, $advance_days, $discount_value, $discount_type, $date_from, $date_to);
|
|
}
|
|
|
|
/**
|
|
* Create length of stay deal
|
|
*
|
|
* @param int $room_id
|
|
* @param string $name
|
|
* @param int $min_nights
|
|
* @param float $discount_value
|
|
* @param string $discount_type
|
|
* @param string $date_from
|
|
* @param string $date_to
|
|
* @return bool|int
|
|
*/
|
|
function eb_ap_create_length_of_stay_deal($room_id, $name, $min_nights, $discount_value, $discount_type, $date_from, $date_to) {
|
|
return eb_ap_deals()->create_length_of_stay_deal($room_id, $name, $min_nights, $discount_value, $discount_type, $date_from, $date_to);
|
|
}
|
|
|
|
/**
|
|
* Log debug message
|
|
*
|
|
* @param string $message
|
|
* @param string $level
|
|
*/
|
|
function eb_ap_log($message, $level = 'info') {
|
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
|
$log_message = '[EB Advanced Pricing] ' . $message;
|
|
|
|
if (function_exists('eb_log')) {
|
|
eb_log($log_message, $level);
|
|
} else {
|
|
error_log($log_message);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get plugin option
|
|
*
|
|
* @param string $option_name
|
|
* @param mixed $default
|
|
* @return mixed
|
|
*/
|
|
function eb_ap_get_option($option_name, $default = false) {
|
|
return get_option($option_name, $default);
|
|
}
|
|
|
|
/**
|
|
* Update plugin option
|
|
*
|
|
* @param string $option_name
|
|
* @param mixed $value
|
|
* @return bool
|
|
*/
|
|
function eb_ap_update_option($option_name, $value) {
|
|
return update_option($option_name, $value);
|
|
}
|
|
|
|
/**
|
|
* Check if plugin is enabled
|
|
*
|
|
* @return bool
|
|
*/
|
|
function eb_ap_is_enabled() {
|
|
return eb_ap_get_option('eb_ap_enabled', 'yes') === 'yes';
|
|
}
|
|
|
|
/**
|
|
* Get rooms list
|
|
*
|
|
* @return array
|
|
*/
|
|
function eb_ap_get_rooms() {
|
|
$rooms = get_posts(array(
|
|
'post_type' => 'eagle_rooms',
|
|
'posts_per_page' => -1,
|
|
'post_status' => 'publish'
|
|
));
|
|
|
|
$room_list = array();
|
|
foreach ($rooms as $room) {
|
|
$room_list[$room->ID] = $room->post_title;
|
|
}
|
|
|
|
return $room_list;
|
|
}
|
|
|
|
/**
|
|
* Get current date in site timezone
|
|
*
|
|
* @param string $format
|
|
* @return string
|
|
*/
|
|
function eb_ap_current_date($format = 'Y-m-d') {
|
|
return current_time($format);
|
|
}
|
|
|
|
/**
|
|
* Convert date format
|
|
*
|
|
* @param string $date
|
|
* @param string $from_format
|
|
* @param string $to_format
|
|
* @return string
|
|
*/
|
|
function eb_ap_convert_date($date, $from_format, $to_format) {
|
|
$datetime = DateTime::createFromFormat($from_format, $date);
|
|
return $datetime ? $datetime->format($to_format) : $date;
|
|
}
|
|
|
|
/**
|
|
* Validate date string
|
|
*
|
|
* @param string $date
|
|
* @param string $format
|
|
* @return bool
|
|
*/
|
|
function eb_ap_validate_date($date, $format = 'Y-m-d') {
|
|
$d = DateTime::createFromFormat($format, $date);
|
|
return $d && $d->format($format) === $date;
|
|
}
|
|
|
|
/**
|
|
* Calculate nights between dates
|
|
*
|
|
* @param string $checkin_date
|
|
* @param string $checkout_date
|
|
* @return int
|
|
*/
|
|
function eb_ap_calculate_nights($checkin_date, $checkout_date) {
|
|
$start = new DateTime($checkin_date);
|
|
$end = new DateTime($checkout_date);
|
|
return $end->diff($start)->days;
|
|
}
|
|
|
|
/**
|
|
* Get date range array
|
|
*
|
|
* @param string $start_date
|
|
* @param string $end_date
|
|
* @return array
|
|
*/
|
|
function eb_ap_get_date_range($start_date, $end_date) {
|
|
$start = new DateTime($start_date);
|
|
$end = new DateTime($end_date);
|
|
$end->add(new DateInterval('P1D')); // Include end date
|
|
|
|
$period = new DatePeriod($start, new DateInterval('P1D'), $end);
|
|
$dates = array();
|
|
|
|
foreach ($period as $date) {
|
|
$dates[] = $date->format('Y-m-d');
|
|
}
|
|
|
|
return $dates;
|
|
}
|
|
|
|
/**
|
|
* Check if user can manage advanced pricing
|
|
*
|
|
* @return bool
|
|
*/
|
|
function eb_ap_user_can_manage() {
|
|
return current_user_can('manage_options') || current_user_can('eb_manage_pricing');
|
|
}
|
|
|
|
/**
|
|
* Sanitize pricing data
|
|
*
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
function eb_ap_sanitize_pricing_data($data) {
|
|
$sanitized = array();
|
|
|
|
if (isset($data['base_rate'])) {
|
|
$sanitized['base_rate'] = floatval($data['base_rate']);
|
|
}
|
|
|
|
if (isset($data['adult_rate'])) {
|
|
$sanitized['adult_rate'] = floatval($data['adult_rate']);
|
|
}
|
|
|
|
if (isset($data['child_rate'])) {
|
|
$sanitized['child_rate'] = floatval($data['child_rate']);
|
|
}
|
|
|
|
if (isset($data['min_guests'])) {
|
|
$sanitized['min_guests'] = intval($data['min_guests']);
|
|
}
|
|
|
|
if (isset($data['max_guests'])) {
|
|
$sanitized['max_guests'] = intval($data['max_guests']);
|
|
}
|
|
|
|
if (isset($data['min_stay'])) {
|
|
$sanitized['min_stay'] = intval($data['min_stay']);
|
|
}
|
|
|
|
if (isset($data['max_stay'])) {
|
|
$sanitized['max_stay'] = intval($data['max_stay']);
|
|
}
|
|
|
|
return $sanitized;
|
|
}
|
|
|
|
/**
|
|
* Sanitize availability data
|
|
*
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
function eb_ap_sanitize_availability_data($data) {
|
|
$sanitized = array();
|
|
|
|
if (isset($data['available_rooms'])) {
|
|
$sanitized['available_rooms'] = intval($data['available_rooms']);
|
|
}
|
|
|
|
if (isset($data['stop_sell'])) {
|
|
$sanitized['stop_sell'] = $data['stop_sell'] ? 1 : 0;
|
|
}
|
|
|
|
if (isset($data['closed_to_arrival'])) {
|
|
$sanitized['closed_to_arrival'] = $data['closed_to_arrival'] ? 1 : 0;
|
|
}
|
|
|
|
if (isset($data['closed_to_departure'])) {
|
|
$sanitized['closed_to_departure'] = $data['closed_to_departure'] ? 1 : 0;
|
|
}
|
|
|
|
return $sanitized;
|
|
} |