id; $trip_slug = $trip->slug ?? ''; $is_remaining_payment = !empty($booking->is_remaining_payment); $remaining_amount = isset($booking->remaining_amount) ? (float) $booking->remaining_amount : null; $existing_booking_id = $booking->existing_booking_id ?? 0; $booking_reference = $booking->booking_reference ?? ''; $amount_paid = isset($booking->amount_paid) ? (float) $booking->amount_paid : null; $total_amount = isset($booking->total_amount) ? (float) $booking->total_amount : null; // Check if login is required $require_login = \Yatra\Services\SettingsService::get('require_login', false); $allow_guest_checkout = \Yatra\Services\SettingsService::get('allow_guest_checkout', true); $needs_authentication = !is_user_logged_in() && ($require_login || !$allow_guest_checkout); // Get group discount from booking object (calculated in AppServiceProvider) $group_discount = $booking->group_discount ?? null; $group_discount_amount = $group_discount['amount'] ?? 0; $group_discount_code = $group_discount['code'] ?? null; $group_discount_label = $group_discount['label'] ?? __('Group Discount', 'yatra'); // Get pre-calculated pricing from booking object (calculated in BookingPageHandler) $pricing_calculation = $booking->pricing_calculation ?? [ 'base_amount' => 0, 'gross_total' => 0, 'final_total' => 0, 'amount_due' => 0, 'tax_calculation' => ['tax_breakdown' => [], 'total_tax_amount' => 0], ]; $tax_calculation = $pricing_calculation['tax_calculation'] ?? ['tax_breakdown' => [], 'total_tax_amount' => 0]; // Use pre-calculated amounts $summary_total_amount = $is_remaining_payment && !empty($total_amount) ? (float) $total_amount : ($pricing_calculation['final_total'] ?? 0); $summary_due_amount = $is_remaining_payment && $remaining_amount !== null ? (float) $remaining_amount : ($pricing_calculation['amount_due'] ?? $pricing_calculation['final_total'] ?? 0); ?>

is_remaining_payment)) { esc_html_e('Pay Remaining Balance', 'yatra'); } else { esc_html_e('Complete Your Booking', 'yatra'); } ?>

:
pricing_type) ? $booking->pricing_type : ($trip->pricing_type ?? 'regular'); $price_types = !empty($booking->price_types) ? $booking->price_types : ($trip->price_types ?? []); if ($trip_pricing_mode === 'regular' && empty($booking->price_types)) { $pricing_type = 'regular'; $price_types = []; } if (empty($pricing_type) && !empty($price_types)) { $pricing_type = 'traveler_based'; } // Do not override explicit regular trip pricing with orphan trip_price_types rows if (empty($price_types) && !empty($trip->price_types) && $trip_pricing_mode === 'traveler_based') { $price_types = $trip->price_types; if (empty($pricing_type) || $pricing_type === 'regular') { $pricing_type = 'traveler_based'; } } $traveler_counts = $booking->traveler_counts ?? []; // Include shared booking form fields include YATRA_PLUGIN_PATH . 'templates/partials/booking-form-fields.php'; ?>

#
<?php echo esc_attr($trip->title ?? ''); ?>

title); ?>

departure_time ?? ''; $is_day_trip = $booking->is_day_trip ?? false; $pricing_type = $booking->pricing_type ?? 'regular'; $price_types = $booking->price_types ?? []; $traveler_counts = $booking->traveler_counts ?? []; ?>
$pt) { $pt = (object) $pt; $category_id = $pt->category_id ?? $index; $category_label = $pt->category_label ?? __('Traveler', 'yatra'); $count = isset($traveler_counts[$category_id]) ? (int) $traveler_counts[$category_id] : ($index === 0 ? 1 : 0); $category_price = isset($pt->effective_price) ? (float) $pt->effective_price : ($pt->sale_price ?? $pt->discounted_price ?? $pt->original_price ?? 0); $pricing_mode = (!empty($pt->pricing_mode) && $pt->pricing_mode === 'per_group') ? 'per_group' : 'per_person'; $age_info = ''; if (isset($pt->age_min) || isset($pt->age_max)) { if (isset($pt->age_min) && isset($pt->age_max)) { $age_info = sprintf(__('(Age %d-%d)', 'yatra'), $pt->age_min, $pt->age_max); } elseif (isset($pt->age_min)) { $age_info = sprintf(__('(Age %d+)', 'yatra'), $pt->age_min); } else { $age_info = sprintf(__('(Up to age %d)', 'yatra'), $pt->age_max); } } $input_id = 'traveler_' . $category_id; $traveler_rows[] = [ 'label' => $category_label, 'subtitle' => $age_info, 'price_html' => $category_price > 0 ? '' . yatra_format_price($category_price) . '' : '', 'row_attrs' => [ 'data-category-id' => $category_id, 'data-price' => $category_price, 'data-pricing-mode' => $pricing_mode, ], 'minus_disabled' => ($index !== 0 && $count <= 0), 'plus_disabled' => false, 'minus_attrs' => [ 'data-target' => $input_id, 'aria-label' => sprintf(__('Decrease %s', 'yatra'), $category_label), ], 'plus_attrs' => [ 'data-target' => $input_id, 'aria-label' => sprintf(__('Increase %s', 'yatra'), $category_label), ], 'input_attrs' => [ 'id' => $input_id, 'name' => 'travelers[' . $category_id . ']', 'value' => $count, 'min' => 0, 'max' => $trip->max_travelers ?: 20, 'data-category-label' => $category_label, 'data-price' => $category_price, 'data-pricing-mode' => $pricing_mode, ], ]; } $traveler_display_text = !empty($traveler_rows) ? ($traveler_rows[0]['label'] . ' x ' . max(1, (int) $traveler_rows[0]['input_attrs']['value'])) : __('Traveler x 1', 'yatra'); $root_id = ''; $root_class = 'yatra-booking-field-select yatra-participants-select'; $container_attrs = []; $display_id = 'participants-display'; $display_class = 'yatra-participants-display'; $display_attrs = []; $dropdown_id = 'quantity-selector'; $dropdown_class = 'yatra-booking-quantity-selector'; $dropdown_attrs = []; $icon_html = yatra_svg_icon('users', 'yatra-icon-sm'); $rows = $traveler_rows; include YATRA_PLUGIN_PATH . 'templates/partials/traveler-selector.php'; ?>

title ?? ''); ?>

title); ?>

duration_days ?? 0); $duration_nights = isset($trip->duration_nights) ? (int) $trip->duration_nights : null; ?> 0) : ?> difficulty_level ?? null; if (!empty($trip->difficulty_name)) { $difficulty_label = (string) $trip->difficulty_name; } elseif (is_numeric($difficulty_raw) && (int) $difficulty_raw > 0) { global $wpdb; $classifications_table = \Yatra\Database\Tables\ClassificationsTable::getTableName(); $difficulty_label = (string) $wpdb->get_var($wpdb->prepare( "SELECT name FROM {$classifications_table} WHERE id = %d LIMIT 1", (int) $difficulty_raw )); } elseif (is_string($difficulty_raw) && $difficulty_raw !== '') { $difficulty_label = ucfirst($difficulty_raw); } ?> •
attributes)): ?>
attributes as $attribute): ?>
'; break; case 'textarea': // Truncate long text for sidebar $text = wp_strip_all_tags($attribute['value']); echo esc_html(substr($text, 0, 25) . (strlen($text) > 25 ? '...' : '')); break; case 'number': echo esc_html(number_format($attribute['value'], 0)); break; default: // Truncate long text for sidebar echo esc_html(substr($attribute['value'], 0, 20) . (strlen($attribute['value']) > 20 ? '...' : '')); break; } ?>
>
>
0 ? '-' . esc_html(yatra_format_price($coupon_discount_amount_for_display)) : ''; ?>

data-tooltip="" aria-label="" >
checkout ?? null; // Surface the dynamic-pricing breakdown as a template // variable so the partial can render the DP line items. // CalculationService stuffs the breakdown into // `pricing_calculation.dynamic_pricing` via the // `yatra_price_breakdown` filter; without exposing it // here the partial's DP block stays dark on first load. $dynamic_pricing = $pricing_calculation['dynamic_pricing'] ?? null; $currency = $pricing_calculation['currency'] ?? null; // The pricing-summary partial calls $render_additional_services() // at the right spot — right after the traveler/per-person rows // and before the Trip Subtotal — so the services row shares the // same compact "label … price" layout as the traveler row. // Include pricing summary template (uses $checkout model) include YATRA_PLUGIN_PATH . 'templates/partials/pricing-summary.php'; ?>
cancellation_policy)): ?>

cancellation_policy); // Truncate if too long for booking summary $max_length = 200; if (strlen($policy_text) > $max_length) { $truncated_text = substr($policy_text, 0, $max_length); // Find last complete sentence within truncation $last_period = strrpos($truncated_text, '.'); $last_exclamation = strrpos($truncated_text, '!'); $last_question = strrpos($truncated_text, '?'); $last_sentence_end = max($last_period, $last_exclamation, $last_question); if ($last_sentence_end > $max_length * 0.7) { // If we have a complete sentence, end there $display_text = substr($truncated_text, 0, $last_sentence_end + 1); } else { // Otherwise, truncate at word boundary $display_text = substr($truncated_text, 0, strrpos($truncated_text, ' ')) . '...'; } } else { $display_text = $policy_text; } echo '

' . esc_html($display_text) . '

'; // Show "more" indicator if truncated if (strlen($policy_text) > $max_length) { echo '

'; echo esc_html__('Full policy available on trip details page', 'yatra'); echo '

'; } ?>