$room_id, 'rate_date' => $date, 'base_rate' => isset($rates['base_rate']) ? $rates['base_rate'] : 0, 'adult_rate' => isset($rates['adult_rate']) ? $rates['adult_rate'] : 0, 'child_rate' => isset($rates['child_rate']) ? $rates['child_rate'] : 0, 'min_guests' => isset($rates['min_guests']) ? $rates['min_guests'] : 1, 'max_guests' => isset($rates['max_guests']) ? $rates['max_guests'] : 10, 'min_stay' => isset($rates['min_stay']) ? $rates['min_stay'] : 1, 'max_stay' => isset($rates['max_stay']) ? $rates['max_stay'] : 0, 'updated_at' => current_time('mysql') ); // Check if rate already exists $existing = $wpdb->get_row($wpdb->prepare( "SELECT id FROM " . EB_AP_TABLE_RATES . " WHERE room_id = %d AND rate_date = %s", $room_id, $date )); if ($existing) { $result = $wpdb->update( EB_AP_TABLE_RATES, $data, array('id' => $existing->id), array('%d', '%s', '%f', '%f', '%f', '%d', '%d', '%d', '%d', '%s'), array('%d') ); } else { $data['created_at'] = current_time('mysql'); $result = $wpdb->insert( EB_AP_TABLE_RATES, $data, array('%d', '%s', '%f', '%f', '%f', '%d', '%d', '%d', '%d', '%s', '%s') ); } return $result !== false; } /** * Update rates for a date range * * @param int $room_id * @param string $start_date * @param string $end_date * @param array $rates * @return bool */ public function update_rates_bulk($room_id, $start_date, $end_date, $rates) { $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); $success_count = 0; $total_count = 0; foreach ($period as $date) { $total_count++; if ($this->update_rates($room_id, $date->format('Y-m-d'), $rates)) { $success_count++; } } return $success_count === $total_count; } /** * Get rates for a specific room and date * * @param int $room_id * @param string $date * @return array|null */ public function get_rates($room_id, $date) { global $wpdb; $rates = $wpdb->get_row($wpdb->prepare( "SELECT * FROM " . EB_AP_TABLE_RATES . " WHERE room_id = %d AND rate_date = %s", $room_id, $date ), ARRAY_A); if (!$rates) { // Return default rates from room meta if no advanced rates found return $this->get_default_rates($room_id); } return $rates; } /** * Get rates for a date range * * @param int $room_id * @param string $start_date * @param string $end_date * @return array */ public function get_rates_range($room_id, $start_date, $end_date) { global $wpdb; $rates = $wpdb->get_results($wpdb->prepare( "SELECT * FROM " . EB_AP_TABLE_RATES . " WHERE room_id = %d AND rate_date >= %s AND rate_date <= %s ORDER BY rate_date ASC", $room_id, $start_date, $end_date ), ARRAY_A); // Fill in missing dates with default rates $rate_map = array(); foreach ($rates as $rate) { $rate_map[$rate['rate_date']] = $rate; } $start = new DateTime($start_date); $end = new DateTime($end_date); $end->add(new DateInterval('P1D')); $period = new DatePeriod($start, new DateInterval('P1D'), $end); $complete_rates = array(); foreach ($period as $date) { $date_str = $date->format('Y-m-d'); if (isset($rate_map[$date_str])) { $complete_rates[] = $rate_map[$date_str]; } else { $default_rates = $this->get_default_rates($room_id); $default_rates['rate_date'] = $date_str; $complete_rates[] = $default_rates; } } return $complete_rates; } /** * Get default rates from room meta * * @param int $room_id * @return array */ private function get_default_rates($room_id) { // Get Eagle Booking default rates $base_rate = get_post_meta($room_id, 'eagle_booking_mtb_room_price', true); $min_guests = get_post_meta($room_id, 'eagle_booking_mtb_room_min_guests', true); $max_guests = get_post_meta($room_id, 'eagle_booking_mtb_room_max_guests', true); return array( 'room_id' => $room_id, 'rate_date' => '', 'base_rate' => $base_rate ? $base_rate : 0, 'adult_rate' => $base_rate ? $base_rate : 0, 'child_rate' => $base_rate ? $base_rate * 0.5 : 0, // Default child rate is 50% of adult 'min_guests' => $min_guests ? $min_guests : 1, 'max_guests' => $max_guests ? $max_guests : 10, 'min_stay' => 1, 'max_stay' => 0, 'is_default' => true ); } /** * Calculate price based on guest count and pricing model * * @param int $room_id * @param string $date * @param int $adults * @param int $children * @return float */ public function calculate_price($room_id, $date, $adults = 1, $children = 0) { $rates = $this->get_rates($room_id, $date); if (!$rates) { return 0; } $pricing_model = get_option('eb_ap_pricing_model', 'per_room'); $total_price = 0; switch ($pricing_model) { case 'per_room': // Fixed price per room regardless of guest count $total_price = $rates['base_rate']; break; case 'per_person': // Price per person $total_price = ($adults * $rates['adult_rate']) + ($children * $rates['child_rate']); break; case 'per_adult': // Price per adult, children free or discounted $total_price = $adults * $rates['adult_rate']; if ($children > 0) { $total_price += $children * $rates['child_rate']; } break; case 'base_plus_extra': // Base price + extra for additional guests $total_price = $rates['base_rate']; $base_guests = $rates['min_guests']; $extra_adults = max(0, $adults - $base_guests); $total_price += ($extra_adults * $rates['adult_rate']) + ($children * $rates['child_rate']); break; default: $total_price = $rates['base_rate']; } return $total_price; } /** * Copy rates from one date to another * * @param int $room_id * @param string $from_date * @param string $to_date * @return bool */ public function copy_rates($room_id, $from_date, $to_date) { $source_rates = $this->get_rates($room_id, $from_date); if (!$source_rates) { return false; } unset($source_rates['id']); unset($source_rates['created_at']); unset($source_rates['updated_at']); return $this->update_rates($room_id, $to_date, $source_rates); } /** * Delete rates for a specific date * * @param int $room_id * @param string $date * @return bool */ public function delete_rates($room_id, $date) { global $wpdb; $result = $wpdb->delete( EB_AP_TABLE_RATES, array( 'room_id' => $room_id, 'rate_date' => $date ), array('%d', '%s') ); return $result !== false; } /** * Get minimum rate for a room in a date range * * @param int $room_id * @param string $start_date * @param string $end_date * @return float */ public function get_min_rate($room_id, $start_date, $end_date) { global $wpdb; $min_rate = $wpdb->get_var($wpdb->prepare( "SELECT MIN(base_rate) FROM " . EB_AP_TABLE_RATES . " WHERE room_id = %d AND rate_date >= %s AND rate_date <= %s", $room_id, $start_date, $end_date )); if ($min_rate === null) { $default_rates = $this->get_default_rates($room_id); return $default_rates['base_rate']; } return $min_rate; } /** * Get maximum rate for a room in a date range * * @param int $room_id * @param string $start_date * @param string $end_date * @return float */ public function get_max_rate($room_id, $start_date, $end_date) { global $wpdb; $max_rate = $wpdb->get_var($wpdb->prepare( "SELECT MAX(base_rate) FROM " . EB_AP_TABLE_RATES . " WHERE room_id = %d AND rate_date >= %s AND rate_date <= %s", $room_id, $start_date, $end_date )); if ($max_rate === null) { $default_rates = $this->get_default_rates($room_id); return $default_rates['base_rate']; } return $max_rate; } /** * Apply percentage increase/decrease to rates * * @param int $room_id * @param string $start_date * @param string $end_date * @param float $percentage * @return bool */ public function apply_percentage_change($room_id, $start_date, $end_date, $percentage) { $rates = $this->get_rates_range($room_id, $start_date, $end_date); $success_count = 0; $total_count = count($rates); foreach ($rates as $rate) { $multiplier = 1 + ($percentage / 100); $updated_rates = array( 'base_rate' => $rate['base_rate'] * $multiplier, 'adult_rate' => $rate['adult_rate'] * $multiplier, 'child_rate' => $rate['child_rate'] * $multiplier, 'min_guests' => $rate['min_guests'], 'max_guests' => $rate['max_guests'], 'min_stay' => $rate['min_stay'], 'max_stay' => $rate['max_stay'] ); if ($this->update_rates($room_id, $rate['rate_date'], $updated_rates)) { $success_count++; } } return $success_count === $total_count; } /** * Get rate statistics for a room * * @param int $room_id * @param string $start_date * @param string $end_date * @return array */ public function get_rate_statistics($room_id, $start_date, $end_date) { global $wpdb; $stats = $wpdb->get_row($wpdb->prepare( "SELECT MIN(base_rate) as min_rate, MAX(base_rate) as max_rate, AVG(base_rate) as avg_rate, COUNT(*) as total_days FROM " . EB_AP_TABLE_RATES . " WHERE room_id = %d AND rate_date >= %s AND rate_date <= %s", $room_id, $start_date, $end_date ), ARRAY_A); return $stats ? $stats : array( 'min_rate' => 0, 'max_rate' => 0, 'avg_rate' => 0, 'total_days' => 0 ); } }