PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
← All changes | templates/booking-confirmation.php +803 -41 3.0.2.8 → 3.0.16 View file →
@@ -30,8 +30,52 @@
30 30 // Format dates
31 31 $travel_date_formatted = \Yatra\Helpers\FormatHelper::formatDate((string) ($booking->travel_date ?? ''));
32 32 $booking_date_formatted = \Yatra\Helpers\FormatHelper::formatDateTime((string) ($booking->created_at ?? ''));
33 33
34 +// "Balance just paid" context detection.
35 +// A `?balance=paid` query arg is appended by the remaining-payment flows
36 +// (see PaymentGatewayController::create_remaining_balance_intent and
37 +// BookingSessionController::process_remaining_payment). We only render the
38 +// "balance paid" copy when BOTH the flag is present AND the booking actually
39 +// reports a paid status — that way a stale bookmarked URL or a tampered
40 +// query string can't show misleading content if a balance is still due.
41 +$is_balance_paid_request = isset($_GET['balance']) && sanitize_key((string) $_GET['balance']) === 'paid';
42 +$booking_payment_status = (string) ($booking->payment_status ?? '');
43 +$booking_amount_due = (float) ($booking->amount_due ?? 0);
44 +$booking_is_fully_paid = $booking_payment_status === 'paid' || $booking_amount_due <= 0.01;
45 +$show_balance_paid_banner = $is_balance_paid_request && $booking_is_fully_paid;
46 +
47 +// A gateway may redirect back here with `?payment=cancelled` (user aborted the
48 +// payment at the provider) or `?payment=failed`. Show an informative notice only
49 +// when the booking is not already fully paid, so a genuinely-paid booking that
50 +// happens to carry a stale query arg never shows a misleading "cancelled" message.
51 +$payment_result_flag = isset($_GET['payment']) ? sanitize_key((string) $_GET['payment']) : '';
52 +$show_payment_cancelled_notice = in_array($payment_result_flag, ['cancelled', 'failed'], true) && !$booking_is_fully_paid;
53 +
54 +// Resolve the most recent gateway used on this booking.
55 +// `$booking->payment_gateway` is the *initial* method chosen at booking time
56 +// (e.g. Pay Later), which is misleading when the customer later settled the
57 +// balance via a different gateway (e.g. Stripe). Show the latest payment's
58 +// gateway in the Payment Method line; fall back to the booking's stored
59 +// gateway when no payment row exists yet.
60 +$display_payment_gateway = (string) ($booking->payment_gateway ?? '');
61 +if (!empty($booking->id)) {
62 + try {
63 + $latest_payment = (new \Yatra\Repositories\PaymentRepository())->findLatestByBookingId((int) $booking->id);
64 + if ($latest_payment) {
65 + $latest_gateway = (string) ($latest_payment->payment_gateway ?? $latest_payment->gateway ?? '');
66 + if ($latest_gateway !== '') {
67 + $display_payment_gateway = $latest_gateway;
68 + }
69 + }
70 + } catch (\Throwable $e) {
71 + // Repository unavailable for some reason — keep the booking's stored gateway.
72 + }
73 +}
74 +
75 +// Resolved customer account URL (configurable via Settings → Permalink → Account base).
76 +$yatra_account_url = home_url('/' . \Yatra\Services\SettingsService::getAccountBase());
77 +
34 78 // Get status color
35 79 $status_colors = [
36 80 'pending' => ['bg' => '#fef3c7', 'text' => '#d97706', 'label' => 'Pending'],
37 81 'confirmed' => ['bg' => '#d1fae5', 'text' => '#059669', 'label' => 'Confirmed'],
@@ -43,8 +87,21 @@
43 87 ];
44 88
45 89 $status_style = $status_colors[$booking->status] ?? $status_colors['pending'];
46 90
91 +// Ensure Font Awesome CSS is available for icon-picker rendered icons (fa-solid/fa-regular).
92 +// This template can be displayed outside normal "trip page" contexts, so we explicitly
93 +// register/enqueue the shared stylesheet dependencies before printing the header.
94 +if (class_exists(\Yatra\Providers\FrontendAssetsProvider::class)) {
95 + \Yatra\Providers\FrontendAssetsProvider::registerCoreFrontendStylesheets();
96 + if (wp_style_is('yatra-fontawesome-6', 'registered')) {
97 + wp_enqueue_style('yatra-fontawesome-6');
98 + }
99 + if (wp_style_is('yatra-common', 'registered')) {
100 + wp_enqueue_style('yatra-common');
101 + }
102 +}
103 +
47 104 yatra_get_header();
48 105
49 106 // Hook for Pro modules to add custom scripts (Facebook Pixel, etc.)
50 107 do_action('yatra_booking_confirmation_header', $booking);
@@ -61,10 +118,12 @@
61 118 <polyline points="9,12 12,15 16,10"></polyline>
62 119 </svg>
63 120 </div>
64 121 <h1 class="yatra-confirmation-title">
65 - <?php
66 - if ($booking->status === 'confirmed') {
122 + <?php
123 + if ($show_balance_paid_banner) {
124 + esc_html_e('Balance Paid!', 'yatra');
125 + } elseif ($booking->status === 'confirmed') {
67 126 esc_html_e('Booking Confirmed!', 'yatra');
68 127 } elseif ($booking->status === 'pending') {
69 128 esc_html_e('Booking Received!', 'yatra');
70 129 } elseif ($booking->status === 'cancelled') {
@@ -74,10 +133,12 @@
74 133 }
75 134 ?>
76 135 </h1>
77 136 <p class="yatra-confirmation-subtitle">
78 - <?php
79 - if ($booking->status === 'confirmed') {
137 + <?php
138 + if ($show_balance_paid_banner) {
139 + esc_html_e('Your remaining balance has been received. This booking is now fully paid.', 'yatra');
140 + } elseif ($booking->status === 'confirmed') {
80 141 esc_html_e('Thank you for your booking. We look forward to hosting you!', 'yatra');
81 142 } elseif ($booking->status === 'pending') {
82 143 esc_html_e('Thank you for your booking. Your booking is pending confirmation.', 'yatra');
83 144 } elseif ($booking->status === 'cancelled') {
@@ -92,10 +153,58 @@
92 153 <span class="yatra-ref-code"><?php echo esc_html($booking->reference); ?></span>
93 154 </div>
94 155 </div>
95 156
157 + <?php if ($show_balance_paid_banner) : ?>
158 + <div class="yatra-balance-paid-banner" role="status" aria-live="polite" style="margin: 16px 0; padding: 14px 18px; background: #d1fae5; border: 1px solid #6ee7b7; border-left: 4px solid #059669; border-radius: 8px; color: #065f46; display: flex; gap: 12px; align-items: flex-start;">
159 + <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="flex: 0 0 22px; width: 22px; height: 22px; margin-top: 1px;">
160 + <path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
161 + </svg>
162 + <div style="flex: 1; line-height: 1.45;">
163 + <strong style="display: block; margin-bottom: 2px;">
164 + <?php esc_html_e('Balance payment received.', 'yatra'); ?>
165 + </strong>
166 + <span>
167 + <?php
168 + printf(
169 + wp_kses(
170 + /* translators: 1: booking reference number (HTML <strong> wrapped), 2: link labelled "payment history" pointing to the customer account page (HTML <a> wrapped). */
171 + __('You\'ve completed payment for booking %1$s. A receipt has been emailed to you. View or download your %2$s anytime from your account.', 'yatra'),
172 + ['a' => ['href' => true], 'strong' => []]
173 + ),
174 + '<strong>' . esc_html((string) ($booking->reference ?? '')) . '</strong>',
175 + '<a href="' . esc_url(add_query_arg('tab', 'payments', $yatra_account_url)) . '">' . esc_html__('payment history', 'yatra') . '</a>'
176 + );
177 + ?>
178 + </span>
179 + </div>
180 + </div>
181 + <?php endif; ?>
182 +
183 + <?php if ($show_payment_cancelled_notice) : ?>
184 + <div class="yatra-payment-cancelled-banner" role="status" aria-live="polite" style="margin: 16px 0; padding: 14px 18px; background: #fef3c7; border: 1px solid #fcd34d; border-left: 4px solid #d97706; border-radius: 8px; color: #92400e; display: flex; gap: 12px; align-items: flex-start;">
185 + <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="flex: 0 0 22px; width: 22px; height: 22px; margin-top: 1px;">
186 + <circle cx="12" cy="12" r="10"></circle>
187 + <line x1="12" y1="8" x2="12" y2="12"></line>
188 + <line x1="12" y1="16" x2="12.01" y2="16"></line>
189 + </svg>
190 + <div style="flex: 1; line-height: 1.45;">
191 + <strong style="display: block; margin-bottom: 2px;">
192 + <?php esc_html_e('Payment not completed.', 'yatra'); ?>
193 + </strong>
194 + <span>
195 + <?php esc_html_e('Your payment was cancelled and no charge was made. Your booking has been saved — you can complete payment anytime from your account.', 'yatra'); ?>
196 + </span>
197 + </div>
198 + </div>
199 + <?php endif; ?>
200 +
96 201 <?php
97 - // Resolve featured image URL (handle attachment ID or direct URL)
202 + // Resolve featured image URL (handle attachment ID or direct URL).
203 + // Falls back to the bundled trip-placeholder.svg so the confirmation
204 + // card always renders with a visual on the left — never an empty
205 + // text-only block, regardless of whether the operator set a featured
206 + // image for the trip.
98 207 $featured_image_url = '';
99 208 if (!empty($booking->featured_image)) {
100 209 if (is_numeric($booking->featured_image)) {
101 210 $featured_image_url = wp_get_attachment_url((int) $booking->featured_image) ?: '';
@@ -102,8 +211,14 @@
102 211 } else {
103 212 $featured_image_url = $booking->featured_image;
104 213 }
105 214 }
215 + if ($featured_image_url === '') {
216 + $featured_image_url = YATRA_PLUGIN_URL . 'assets/images/trip-placeholder.svg';
217 + $featured_image_is_placeholder = true;
218 + } else {
219 + $featured_image_is_placeholder = false;
220 + }
106 221 ?>
107 222
108 223 <div class="yatra-confirmation-content">
109 224 <!-- Trip Summary Card -->
@@ -108,23 +223,66 @@
108 223 <div class="yatra-confirmation-content">
109 224 <!-- Trip Summary Card -->
110 225 <div class="yatra-confirmation-card yatra-trip-summary-card">
111 226 <div class="yatra-trip-summary">
112 - <?php if (!empty($featured_image_url)) : ?>
113 - <div class="yatra-trip-image">
114 - <img src="<?php echo esc_url($featured_image_url); ?>" alt="<?php echo esc_attr($booking->trip_title); ?>">
227 + <div class="yatra-trip-image<?php echo $featured_image_is_placeholder ? ' yatra-trip-image--placeholder' : ''; ?>">
228 + <img src="<?php echo esc_url($featured_image_url); ?>"
229 + alt="<?php echo esc_attr($booking->trip_title); ?>"
230 + loading="lazy"
231 + onerror="this.onerror=null;this.src='<?php echo esc_url(YATRA_PLUGIN_URL . 'assets/images/trip-placeholder.svg'); ?>';this.parentNode.classList.add('yatra-trip-image--placeholder');">
115 232 </div>
116 - <?php endif; ?>
117 233
118 234 <div class="yatra-trip-info">
119 235 <h2 class="yatra-trip-name"><?php echo esc_html($booking->trip_title); ?></h2>
120 236
121 237 <?php if (!empty($booking->trip_average_rating) && $booking->trip_review_count >= 0) : ?>
238 + <?php
239 + // The confirmation page isn't a "booking page" (it has its
240 + // own route), so booking.css — which colours the rating
241 + // stars amber — is never enqueued here and the filled stars
242 + // fell back to the grey base colour. The rest of this page
243 + // is inline-styled, so rather than loading the whole
244 + // stylesheet (and risk restyling it) the rating rules are
245 + // scoped inline here, mirroring assets/css/booking.css.
246 + ?>
247 + <?php
248 + // IMPORTANT: these rules are deliberately scoped to
249 + // `.yatra-trip-rating .yatra-rating-stars .yatra-star*`
250 + // (specificity 0,3,0 / 0,4,1) and set `fill` directly on
251 + // the SVG — NOT just `color` + `fill="currentColor"`.
252 + // trip.css / booking.css define `.yatra-rating-stars
253 + // .yatra-star { color:#d1d5db }` (0,2,0) and colour the
254 + // "filled" state with a `.filled` (dot) class, not the
255 + // `-filled` (hyphen) class this markup uses. If either
256 + // stylesheet is present on the confirmation page, its
257 + // grey base out-specifies a plain `.yatra-star-filled`
258 + // and its amber rule never matches — so every star showed
259 + // grey even at 4.8. Winning on specificity + an explicit
260 + // fill makes the amber stick regardless of what's loaded.
261 + ?>
262 + <style>
263 + .yatra-trip-rating{display:flex;align-items:center;gap:12px;margin-bottom:12px}
264 + .yatra-trip-rating .yatra-rating-stars{display:inline-flex;gap:4px}
265 + .yatra-trip-rating .yatra-rating-stars .yatra-star{width:20px;height:20px;color:#e2e8f0;font-size:0;line-height:0}
266 + .yatra-trip-rating .yatra-rating-stars .yatra-star svg{width:100%;height:100%;display:block;fill:currentColor}
267 + .yatra-trip-rating .yatra-rating-stars .yatra-star-filled{color:#f59e0b}
268 + .yatra-trip-rating .yatra-rating-stars .yatra-star-filled svg{fill:#f59e0b}
269 + .yatra-trip-rating .yatra-rating-stars .yatra-star-half{position:relative;color:#e2e8f0}
270 + .yatra-trip-rating .yatra-rating-stars .yatra-star-half svg{fill:#e2e8f0}
271 + .yatra-trip-rating .yatra-rating-stars .yatra-star-half::after{content:"";position:absolute;top:0;left:0;bottom:0;width:50%;overflow:hidden;background:#f59e0b;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%}
272 + .yatra-trip-rating .yatra-rating-meta strong{color:#0f172a;margin-right:6px}
273 + .yatra-trip-rating .yatra-rating-meta span{color:#64748b;font-size:14px}
274 + </style>
122 275 <div class="yatra-trip-rating">
123 276 <div class="yatra-rating-stars">
124 277 <?php
125 - $filled_stars = floor($booking->trip_average_rating);
126 - $has_half = ($booking->trip_average_rating - $filled_stars) >= 0.5;
278 + // Shared with the reviews block and listing cards so every
279 + // surface draws the same rating. Rounds to the nearest half:
280 + // flooring drew 4.9 as four-and-a-half stars, which looked
281 + // wrong beside the printed "4.9".
282 + $star_parts = yatra_rating_star_parts($booking->trip_average_rating);
283 + $filled_stars = $star_parts['full'];
284 + $has_half = $star_parts['half'];
127 285 for ($i = 1; $i <= 5; $i++) :
128 286 $class = $i <= $filled_stars ? 'yatra-star-filled' : ($has_half && $i === $filled_stars + 1 ? 'yatra-star-half' : '');
129 287 ?>
130 288 <span class="yatra-star <?php echo esc_attr($class); ?>">
@@ -135,10 +293,15 @@
135 293 <div class="yatra-rating-meta">
136 294 <strong><?php echo esc_html(number_format($booking->trip_average_rating, 1)); ?></strong>
137 295 <span>
138 296 <?php
139 - /* translators: %d review count */
140 - printf(esc_html(_n('%d Review', '%d Reviews', (int) $booking->trip_review_count, 'yatra')), (int) $booking->trip_review_count);
297 + printf(
298 + esc_html(
299 + /* translators: %d: number of reviews. */
300 + _n('%d Review', '%d Reviews', (int) $booking->trip_review_count, 'yatra')
301 + ),
302 + (int) $booking->trip_review_count
303 + );
141 304 ?>
142 305 </span>
143 306 </div>
144 307 </div>
@@ -144,24 +307,72 @@
144 307 </div>
145 308 <?php endif; ?>
146 309
147 310 <div class="yatra-trip-meta">
148 - <?php if (!empty($booking->duration_days)) : ?>
311 + <?php if (!empty($booking->duration_days) || !empty($booking->duration_hours)) : ?>
149 312 <span class="yatra-meta-item">
150 313 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
151 314 <circle cx="12" cy="12" r="10"></circle>
152 315 <polyline points="12 6 12 12 16 14"></polyline>
153 316 </svg>
154 - <?php printf(esc_html__('%d Days / %d Nights', 'yatra'), (int) $booking->duration_days, (int) $booking->duration_nights); ?>
317 + <?php
318 + $days = (int) ($booking->duration_days ?? 0);
319 + $nights = (int) ($booking->duration_nights ?? 0);
320 + $hours = (int) ($booking->duration_hours ?? 0);
321 +
322 + if ($hours > 0) {
323 + // Hour-based day tour: "8 Hours", not "1 Day".
324 + printf(
325 + esc_html(
326 + /* translators: %d: number of hours. */
327 + _n('%d Hour', '%d Hours', $hours, 'yatra')
328 + ),
329 + $hours
330 + );
331 + } elseif ($days > 0 && $nights > 0) {
332 + printf(
333 + /* translators: 1: number of days, 2: number of nights. */
334 + esc_html__('%1$d Days / %2$d Nights', 'yatra'),
335 + $days,
336 + $nights
337 + );
338 + } elseif ($days > 0) {
339 + printf(
340 + esc_html(
341 + /* translators: %d: number of days. */
342 + _n('%d Day', '%d Days', $days, 'yatra')
343 + ),
344 + $days
345 + );
346 + } elseif ($nights > 0) {
347 + printf(
348 + esc_html(
349 + /* translators: %d: number of nights. */
350 + _n('%d Night', '%d Nights', $nights, 'yatra')
351 + ),
352 + $nights
353 + );
354 + }
355 + ?>
155 356 </span>
156 357 <?php endif; ?>
157 358
158 359 <?php if (!empty($booking->difficulty_level)) : ?>
159 360 <span class="yatra-meta-item">
160 - <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
161 - <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
162 - </svg>
163 - <?php echo esc_html(ucfirst($booking->difficulty_level)); ?>
361 + <?php
362 + $difficulty = \Yatra\Models\Trip::resolveDifficultyDisplay(
363 + (string) $booking->difficulty_level
364 + );
365 +
366 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
367 + echo yatra_stored_picker_icon_markup(
368 + $difficulty['icon_picker'] ?? null,
369 + '',
370 + 'yatra-icon-sm'
371 + );
372 +
373 + echo esc_html($difficulty['level'] ?? (string) $booking->difficulty_level);
374 + ?>
164 375 </span>
165 376 <?php endif; ?>
166 377 </div>
167 378
@@ -210,18 +421,8 @@
210 421 </div>
211 422 </div>
212 423 <?php endif; ?>
213 424
214 - <?php if (!empty($booking->trip_attributes_list)) : ?>
215 - <div class="yatra-trip-tags">
216 - <span class="yatra-tag-label"><?php esc_html_e('Features:', 'yatra'); ?></span>
217 - <div class="yatra-tag-group">
218 - <?php foreach ($booking->trip_attributes_list as $attribute) : ?>
219 - <span class="yatra-tag-item yatra-attribute-tag"><?php echo esc_html($attribute); ?></span>
220 - <?php endforeach; ?>
221 - </div>
222 - </div>
223 - <?php endif; ?>
224 425 </div>
225 426 </div>
226 427 </div>
227 428
@@ -522,18 +723,37 @@
522 723 </div>
523 724 <?php endif; ?>
524 725
525 726 <?php if ($amount_due > 0): ?>
727 + <?php
728 + // Label the "due now" amount by payment type so a
729 + // deposit/partial reads clearly instead of just "Due Now".
730 + $payment_method_type = (string) ($booking->payment_method ?? 'full');
731 + $remaining_balance = max(0.0, $total_amount - $amount_paid - $amount_due);
732 + if ($payment_method_type === 'deposit') {
733 + $due_now_label = __('Deposit Due Now', 'yatra');
734 + } elseif ($payment_method_type === 'partial') {
735 + $due_now_label = __('Partial Payment Due Now', 'yatra');
736 + } else {
737 + $due_now_label = __('Due Now', 'yatra');
738 + }
739 + ?>
526 740 <div class="yatra-payment-row yatra-due-row">
527 - <span><strong><?php esc_html_e('Due Now', 'yatra'); ?></strong></span>
741 + <span><strong><?php echo esc_html($due_now_label); ?></strong></span>
528 742 <span><strong><?php echo esc_html(yatra_format_price($amount_due, $booking->currency)); ?></strong></span>
529 743 </div>
744 + <?php if ($payment_method_type !== 'full' && $remaining_balance > 0.01): ?>
745 + <div class="yatra-payment-row" style="margin-top: 6px;">
746 + <span><?php esc_html_e('Remaining Balance', 'yatra'); ?></span>
747 + <span><?php echo esc_html(yatra_format_price($remaining_balance, $booking->currency)); ?></span>
748 + </div>
530 749 <?php endif; ?>
750 + <?php endif; ?>
531 751 </div>
532 752
533 753 <div class="yatra-payment-method">
534 754 <span class="yatra-pm-label"><?php esc_html_e('Payment Method:', 'yatra'); ?></span>
535 - <span class="yatra-pm-value"><?php echo esc_html(ucwords(str_replace('_', ' ', $booking->payment_gateway))); ?></span>
755 + <span class="yatra-pm-value"><?php echo esc_html(yatra_payment_gateway_label((string) $display_payment_gateway)); ?></span>
536 756 </div>
537 757 </div>
538 758
539 759 <!-- Contact Info Card -->
@@ -647,15 +867,31 @@
647 867 <?php esc_html_e('Return to Home', 'yatra'); ?>
648 868 </a>
649 869
650 870 <?php
651 - // Get latest payment for this booking to enable invoice download
871 + // Get latest payment for this booking to enable invoice download.
872 + // The invoice endpoint authorises via: admin → owner → signed invoice_token → guest booking_token.
873 + // We always issue a signed invoice_token here so the link works for guests
874 + // (no session required) AND for logged-in users who don't own the booking
875 + // (e.g. site admins viewing the page) — without re-checking login on the client.
652 876 $paymentRepository = new \Yatra\Repositories\PaymentRepository();
653 877 $latestPayment = $paymentRepository->findLatestByBookingId((int) $booking->id);
654 - if ($latestPayment && in_array($latestPayment->status, ['completed', 'paid'], true)) :
878 + if ($latestPayment && in_array($latestPayment->status, ['completed', 'paid'], true)) :
879 + $invoiceToken = \Yatra\Controllers\PaymentGatewayController::issueInvoiceToken(
880 + (int) $latestPayment->id,
881 + (int) ($latestPayment->booking_id ?? $booking->id)
882 + );
883 + $invoiceUrl = add_query_arg(
884 + [
885 + 'download' => '1',
886 + 'invoice_token' => $invoiceToken,
887 + ],
888 + rest_url('yatra/v1/payment/' . (int) $latestPayment->id . '/invoice')
889 + );
655 890 ?>
656 - <a href="<?php echo esc_url(rest_url('yatra/v1/payment/' . $latestPayment->id . '/invoice')); ?>"
657 - target="_blank"
891 + <a href="<?php echo esc_url($invoiceUrl); ?>"
892 + target="_blank"
893 + rel="noopener"
658 894 class="yatra-btn yatra-btn-primary">
659 895 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
660 896 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
661 897 <polyline points="7 10 12 15 17 10"></polyline>
@@ -662,11 +898,36 @@
662 898 <line x1="12" y1="15" x2="12" y2="3"></line>
663 899 </svg>
664 900 <?php esc_html_e('Download Invoice', 'yatra'); ?>
665 901 </a>
902 + <?php
903 + // No completed payment yet (e.g. Bank Transfer / offline): offer a
904 + // pro-forma invoice that carries the payment instructions so the
905 + // customer knows how to pay. Uses a booking-scoped invoice token.
906 + elseif ((float) ($booking->amount_due ?? $booking->total_amount ?? 0) > 0) :
907 + $proformaToken = \Yatra\Controllers\PaymentGatewayController::issueInvoiceToken(0, (int) $booking->id);
908 + $proformaUrl = add_query_arg(
909 + [
910 + 'download' => '1',
911 + 'invoice_token' => $proformaToken,
912 + ],
913 + rest_url('yatra/v1/booking/' . (int) $booking->id . '/invoice')
914 + );
915 + ?>
916 + <a href="<?php echo esc_url($proformaUrl); ?>"
917 + target="_blank"
918 + rel="noopener"
919 + class="yatra-btn yatra-btn-primary">
920 + <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
921 + <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
922 + <polyline points="7 10 12 15 17 10"></polyline>
923 + <line x1="12" y1="15" x2="12" y2="3"></line>
924 + </svg>
925 + <?php esc_html_e('Download Invoice', 'yatra'); ?>
926 + </a>
666 927 <?php endif; ?>
667 928
668 - <button onclick="window.print();" class="yatra-btn yatra-btn-outline">
929 + <button type="button" data-yatra-print="confirmation" class="yatra-btn yatra-btn-outline">
669 930 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
670 931 <polyline points="6 9 6 2 18 2 18 9"></polyline>
671 932 <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
672 933 <rect x="6" y="14" width="12" height="8"></rect>
@@ -813,8 +1074,68 @@
813 1074 color: #111827;
814 1075 margin: 0 0 12px;
815 1076 }
816 1077
1078 +/* Star rating. This confirmation page only enqueues yatra-common + fontawesome,
1079 + not booking.css/trip.css where these live, so without them the inline SVG
1080 + stars render with no size or colour (invisible). Mirrors booking.css. */
1081 +.yatra-trip-rating {
1082 + display: flex;
1083 + align-items: center;
1084 + gap: 12px;
1085 + margin-bottom: 12px;
1086 +}
1087 +
1088 +.yatra-rating-stars {
1089 + display: inline-flex;
1090 + gap: 4px;
1091 +}
1092 +
1093 +.yatra-star {
1094 + width: 20px;
1095 + height: 20px;
1096 + color: #e2e8f0;
1097 +}
1098 +
1099 +.yatra-star svg {
1100 + width: 100%;
1101 + height: 100%;
1102 +}
1103 +
1104 +.yatra-star-filled {
1105 + color: #f59e0b;
1106 +}
1107 +
1108 +/* Half star: base star stays grey; overlay the left half in amber via an
1109 + SVG mask (size-independent, so it tracks the star's dimensions). */
1110 +.yatra-star-half {
1111 + position: relative;
1112 + color: #e2e8f0;
1113 +}
1114 +
1115 +.yatra-star-half::after {
1116 + content: "";
1117 + position: absolute;
1118 + top: 0;
1119 + left: 0;
1120 + bottom: 0;
1121 + width: 50%;
1122 + overflow: hidden;
1123 + background: #f59e0b;
1124 + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%;
1125 + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%;
1126 +}
1127 +
1128 +.yatra-rating-meta strong {
1129 + color: #0f172a;
1130 + margin-right: 6px;
1131 +}
1132 +
1133 +.yatra-rating-meta span {
1134 + color: #64748b;
1135 + font-size: 14px;
1136 +}
1137 +
817 1138 .yatra-trip-meta {
818 1139 display: flex;
819 1140 gap: 20px;
820 1141 flex-wrap: wrap;
@@ -862,8 +1183,13 @@
862 1183 .yatra-trip-summary {
863 1184 flex-direction: column;
864 1185 text-align: center;
865 1186 }
1187 +
1188 + .yatra-info-grid {
1189 + grid-template-columns: 1fr;
1190 + gap: 12px;
1191 + }
866 1192 }
867 1193
868 1194 .yatra-info-grid {
869 1195 display: grid;
@@ -874,13 +1200,18 @@
874 1200 .yatra-info-item {
875 1201 display: flex;
876 1202 flex-direction: column;
877 1203 gap: 4px;
1204 + padding: 12px 14px;
1205 + background: #f9fafb;
1206 + border: 1px solid #eef2f7;
1207 + border-radius: 12px;
878 1208 }
879 1209
880 1210 .yatra-info-label {
881 1211 font-size: 13px;
882 1212 color: #6b7280;
1213 + line-height: 1.2;
883 1214 }
884 1215
885 1216 .yatra-info-value {
886 1217 font-size: 15px;
@@ -885,8 +1216,10 @@
885 1216 .yatra-info-value {
886 1217 font-size: 15px;
887 1218 font-weight: 600;
888 1219 color: #111827;
1220 + line-height: 1.25;
1221 + text-align: left;
889 1222 }
890 1223
891 1224 .yatra-status-badge {
892 1225 display: inline-block;
@@ -961,8 +1294,44 @@
961 1294 .yatra-discount-row span:last-child {
962 1295 color: #22c55e;
963 1296 }
964 1297
1298 +/* Bank-transfer details (markup injected by Yatra Pro's Bank Transfer gateway
1299 + into this page). The card reuses this page's .yatra-confirmation-card /
1300 + .yatra-card-title classes, but its rows had no styling at all, so the values
1301 + sat immediately after their label while every other row on the page is
1302 + flex/space-between — the bank values were the only ones not flush right.
1303 + Styling lives here because this template owns the confirmation page's CSS
1304 + and Pro enqueues no stylesheet on this page. */
1305 +.yatra-bank-info-grid {
1306 + border: 1px solid #e5e7eb;
1307 + border-radius: 8px;
1308 + overflow: hidden;
1309 +}
1310 +
1311 +.yatra-bank-info-item {
1312 + display: flex;
1313 + justify-content: space-between;
1314 + align-items: baseline;
1315 + gap: 12px;
1316 + padding: 12px 16px;
1317 + border-bottom: 1px solid #e5e7eb;
1318 +}
1319 +
1320 +.yatra-bank-info-item:last-child {
1321 + border-bottom: none;
1322 +}
1323 +
1324 +.yatra-bank-label {
1325 + color: #6b7280;
1326 + flex-shrink: 0;
1327 +}
1328 +
1329 +.yatra-bank-value {
1330 + text-align: right;
1331 + word-break: break-word;
1332 +}
1333 +
965 1334 .yatra-payment-method {
966 1335 margin-top: 16px;
967 1336 padding: 12px;
968 1337 background: white;
@@ -1070,18 +1439,411 @@
1070 1439 border-color: #3b82f6;
1071 1440 color: #3b82f6;
1072 1441 }
1073 1442
1074 -/* Print Styles */
1443 +/* =====================================================================
1444 + Print Styles — produce a clean, single-page-friendly receipt.
1445 + Triggered by the print button (adds .yatra-printing-confirmation
1446 + to <body> + clones the confirmation card into .yatra-print-root).
1447 + ===================================================================== */
1075 1448 @media print {
1076 - .yatra-confirmation-actions {
1077 - display: none;
1449 + @page {
1450 + size: A4;
1451 + margin: 9mm 10mm;
1078 1452 }
1079 -
1080 - .yatra-confirmation-wrapper {
1453 +
1454 + /* Force browsers to print our colors / borders */
1455 + body.yatra-printing-confirmation,
1456 + body.yatra-printing-confirmation * {
1457 + -webkit-print-color-adjust: exact !important;
1458 + print-color-adjust: exact !important;
1459 + color-adjust: exact !important;
1460 + }
1461 +
1462 + /* Reset body, kill animations & transitions */
1463 + body.yatra-printing-confirmation {
1464 + background: #fff !important;
1465 + color: #111827 !important;
1466 + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
1467 + Helvetica, Arial, sans-serif !important;
1468 + font-size: 10pt !important;
1469 + line-height: 1.45 !important;
1470 + }
1471 + body.yatra-printing-confirmation *,
1472 + body.yatra-printing-confirmation *::before,
1473 + body.yatra-printing-confirmation *::after {
1474 + animation: none !important;
1475 + transition: none !important;
1476 + box-shadow: none !important;
1477 + text-shadow: none !important;
1478 + }
1479 +
1480 + /* Hide everything except our cloned print root */
1481 + body.yatra-printing-confirmation > *:not(.yatra-print-root) {
1482 + display: none !important;
1483 + }
1484 + body.yatra-printing-confirmation .yatra-print-root,
1485 + body.yatra-printing-confirmation .yatra-print-root * {
1486 + visibility: visible;
1487 + }
1488 + body.yatra-printing-confirmation .yatra-print-root {
1489 + position: static !important;
1490 + left: auto;
1491 + top: auto;
1492 + width: 100%;
1493 + margin: 0;
1081 1494 padding: 0;
1082 1495 }
1496 +
1497 + /* Wrappers — remove screen padding/widths */
1498 + body.yatra-printing-confirmation .yatra-confirmation-wrapper,
1499 + body.yatra-printing-confirmation .yatra-confirmation-container {
1500 + max-width: none !important;
1501 + margin: 0 !important;
1502 + padding: 0 !important;
1503 + }
1504 +
1505 + /* Hide things that don't belong on paper */
1506 + body.yatra-printing-confirmation .yatra-confirmation-actions,
1507 + body.yatra-printing-confirmation .yatra-no-print,
1508 + body.yatra-printing-confirmation .yatra-whats-next,
1509 + body.yatra-printing-confirmation .yatra-trip-rating {
1510 + display: none !important;
1511 + }
1512 +
1513 + /* Confirmation header — compact, two-column with status icon left & ref right */
1514 + body.yatra-printing-confirmation .yatra-confirmation-header {
1515 + display: flex !important;
1516 + align-items: center !important;
1517 + justify-content: space-between !important;
1518 + gap: 16pt !important;
1519 + text-align: left !important;
1520 + margin: 0 0 8pt !important;
1521 + padding: 0 0 6pt !important;
1522 + border-bottom: 1pt solid #111827 !important;
1523 + }
1524 + body.yatra-printing-confirmation .yatra-confirmation-icon {
1525 + width: 28pt !important;
1526 + height: 28pt !important;
1527 + margin: 0 !important;
1528 + background: #16a34a !important;
1529 + flex-shrink: 0 !important;
1530 + }
1531 + body.yatra-printing-confirmation .yatra-confirmation-icon svg {
1532 + width: 16pt !important;
1533 + height: 16pt !important;
1534 + }
1535 + body.yatra-printing-confirmation .yatra-confirmation-title {
1536 + font-size: 14pt !important;
1537 + font-weight: 700 !important;
1538 + margin: 0 !important;
1539 + flex: 1 !important;
1540 + color: #111827 !important;
1541 + }
1542 + body.yatra-printing-confirmation .yatra-confirmation-subtitle {
1543 + display: none !important;
1544 + }
1545 + body.yatra-printing-confirmation .yatra-confirmation-reference {
1546 + display: inline-flex !important;
1547 + flex-direction: column !important;
1548 + align-items: flex-end !important;
1549 + gap: 2pt !important;
1550 + background: transparent !important;
1551 + padding: 0 !important;
1552 + border: none !important;
1553 + border-radius: 0 !important;
1554 + }
1555 + body.yatra-printing-confirmation .yatra-ref-label {
1556 + font-size: 8pt !important;
1557 + text-transform: uppercase !important;
1558 + letter-spacing: 0.4pt !important;
1559 + color: #6b7280 !important;
1560 + }
1561 + body.yatra-printing-confirmation .yatra-ref-code {
1562 + font-size: 11pt !important;
1563 + font-weight: 700 !important;
1564 + color: #111827 !important;
1565 + letter-spacing: 0.6pt !important;
1566 + }
1567 +
1568 + /* Cards — flat, thin border, never split across pages */
1569 + body.yatra-printing-confirmation .yatra-confirmation-card {
1570 + background: #fff !important;
1571 + border: 0.75pt solid #d1d5db !important;
1572 + border-radius: 3pt !important;
1573 + padding: 8pt 10pt !important;
1574 + margin: 0 0 6pt !important;
1575 + page-break-inside: avoid !important;
1576 + break-inside: avoid !important;
1577 + }
1578 + body.yatra-printing-confirmation .yatra-trip-summary-card {
1579 + background: #f9fafb !important;
1580 + border-color: #d1d5db !important;
1581 + }
1582 + body.yatra-printing-confirmation .yatra-card-title {
1583 + font-size: 10.5pt !important;
1584 + font-weight: 700 !important;
1585 + gap: 6pt !important;
1586 + margin: 0 0 8pt !important;
1587 + padding: 0 0 5pt !important;
1588 + border-bottom: 0.5pt solid #e5e7eb !important;
1589 + color: #111827 !important;
1590 + }
1591 + body.yatra-printing-confirmation .yatra-card-title svg {
1592 + width: 12pt !important;
1593 + height: 12pt !important;
1594 + color: #111827 !important;
1595 + }
1596 +
1597 + /* Trip summary — small image, tight spacing */
1598 + body.yatra-printing-confirmation .yatra-trip-summary {
1599 + gap: 10pt !important;
1600 + align-items: flex-start !important;
1601 + }
1602 + /* Images often render as empty placeholders in print preview; hide for a cleaner receipt. */
1603 + body.yatra-printing-confirmation .yatra-trip-image {
1604 + display: none !important;
1605 + }
1606 + body.yatra-printing-confirmation .yatra-trip-name {
1607 + font-size: 12pt !important;
1608 + font-weight: 700 !important;
1609 + margin: 0 0 4pt !important;
1610 + color: #111827 !important;
1611 + }
1612 + body.yatra-printing-confirmation .yatra-trip-meta {
1613 + font-size: 9pt !important;
1614 + gap: 10pt !important;
1615 + margin-bottom: 4pt !important;
1616 + color: #374151 !important;
1617 + }
1618 + body.yatra-printing-confirmation .yatra-trip-meta svg,
1619 + body.yatra-printing-confirmation .yatra-trip-location svg {
1620 + width: 9pt !important;
1621 + height: 9pt !important;
1622 + }
1623 + body.yatra-printing-confirmation .yatra-trip-location {
1624 + font-size: 9pt !important;
1625 + margin: 0 0 4pt !important;
1626 + color: #374151 !important;
1627 + }
1628 +
1629 + /* Tags — outline pills, no fills */
1630 + body.yatra-printing-confirmation .yatra-trip-tags {
1631 + font-size: 9pt !important;
1632 + margin-top: 4pt !important;
1633 + }
1634 + body.yatra-printing-confirmation .yatra-tag-label {
1635 + font-weight: 700 !important;
1636 + color: #374151 !important;
1637 + margin-right: 4pt !important;
1638 + }
1639 + body.yatra-printing-confirmation .yatra-tag-item {
1640 + display: inline-block !important;
1641 + background: #fff !important;
1642 + border: 0.5pt solid #d1d5db !important;
1643 + padding: 1pt 5pt !important;
1644 + border-radius: 2pt !important;
1645 + font-size: 8.5pt !important;
1646 + color: #374151 !important;
1647 + margin: 1pt 2pt 1pt 0 !important;
1648 + }
1649 +
1650 + /* Two-column grid stays two columns on paper */
1651 + body.yatra-printing-confirmation .yatra-confirmation-grid {
1652 + display: grid !important;
1653 + grid-template-columns: 1.15fr 0.85fr !important;
1654 + gap: 6pt !important;
1655 + align-items: start !important;
1656 + }
1657 + body.yatra-printing-confirmation .yatra-confirmation-column {
1658 + min-width: 0 !important;
1659 + }
1660 +
1661 + /* Booking info grid */
1662 + body.yatra-printing-confirmation .yatra-info-grid {
1663 + display: grid !important;
1664 + grid-template-columns: 1fr 1fr !important;
1665 + gap: 5pt 9pt !important;
1666 + }
1667 + body.yatra-printing-confirmation .yatra-info-item {
1668 + display: flex !important;
1669 + flex-direction: column !important;
1670 + gap: 1pt !important;
1671 + }
1672 + body.yatra-printing-confirmation .yatra-info-label {
1673 + font-size: 7.5pt !important;
1674 + text-transform: uppercase !important;
1675 + letter-spacing: 0.3pt !important;
1676 + color: #6b7280 !important;
1677 + }
1678 + body.yatra-printing-confirmation .yatra-info-value {
1679 + font-size: 10pt !important;
1680 + font-weight: 600 !important;
1681 + color: #111827 !important;
1682 + }
1683 + body.yatra-printing-confirmation .yatra-status-badge {
1684 + display: inline-block !important;
1685 + padding: 1pt 6pt !important;
1686 + border: 0.75pt solid currentColor !important;
1687 + border-radius: 2pt !important;
1688 + font-size: 8.5pt !important;
1689 + font-weight: 700 !important;
1690 + }
1691 +
1692 + /* Travelers */
1693 + body.yatra-printing-confirmation .yatra-travelers-list {
1694 + margin: 0 !important;
1695 + }
1696 + body.yatra-printing-confirmation .yatra-traveler-item {
1697 + display: flex !important;
1698 + align-items: center !important;
1699 + gap: 8pt !important;
1700 + padding: 4pt 0 !important;
1701 + border-bottom: 0.5pt solid #e5e7eb !important;
1702 + }
1703 + body.yatra-printing-confirmation .yatra-traveler-item:last-child {
1704 + border-bottom: none !important;
1705 + }
1706 + body.yatra-printing-confirmation .yatra-traveler-number {
1707 + display: inline-flex !important;
1708 + align-items: center !important;
1709 + justify-content: center !important;
1710 + width: 16pt !important;
1711 + height: 16pt !important;
1712 + background: #111827 !important;
1713 + color: #fff !important;
1714 + border-radius: 50% !important;
1715 + font-size: 8.5pt !important;
1716 + font-weight: 700 !important;
1717 + flex-shrink: 0 !important;
1718 + }
1719 + body.yatra-printing-confirmation .yatra-traveler-name {
1720 + font-size: 10pt !important;
1721 + font-weight: 600 !important;
1722 + color: #111827 !important;
1723 + }
1724 + body.yatra-printing-confirmation .yatra-traveler-dob {
1725 + font-size: 8.5pt !important;
1726 + color: #6b7280 !important;
1727 + }
1728 +
1729 + /* Payment summary rows */
1730 + body.yatra-printing-confirmation .yatra-payment-rows {
1731 + margin: 0 !important;
1732 + }
1733 + body.yatra-printing-confirmation .yatra-payment-row,
1734 + body.yatra-printing-confirmation .yatra-bank-info-item {
1735 + display: flex !important;
1736 + justify-content: space-between !important;
1737 + align-items: baseline !important;
1738 + gap: 12pt !important;
1739 + font-size: 9.25pt !important;
1740 + padding: 1.5pt 0 !important;
1741 + color: #111827 !important;
1742 + }
1743 + body.yatra-printing-confirmation .yatra-due-row {
1744 + background: #fef3c7 !important;
1745 + padding: 4pt 6pt !important;
1746 + margin-top: 5pt !important;
1747 + border-radius: 2pt !important;
1748 + border: 0.5pt solid #fbbf24 !important;
1749 + }
1750 + body.yatra-printing-confirmation .yatra-payment-method {
1751 + margin-top: 6pt !important;
1752 + padding-top: 5pt !important;
1753 + font-size: 9pt !important;
1754 + border-top: 0.5pt solid #e5e7eb !important;
1755 + color: #374151 !important;
1756 + }
1757 +
1758 + /* Contact info */
1759 + body.yatra-printing-confirmation .yatra-contact-info {
1760 + margin: 0 !important;
1761 + }
1762 + body.yatra-printing-confirmation .yatra-contact-item {
1763 + font-size: 9.5pt !important;
1764 + margin: 0 0 3pt !important;
1765 + color: #111827 !important;
1766 + }
1767 + body.yatra-printing-confirmation .yatra-contact-item strong {
1768 + color: #6b7280 !important;
1769 + font-weight: 600 !important;
1770 + margin-right: 4pt !important;
1771 + }
1772 +
1773 + /* Links — print as plain text, no underline (URL is still in browser footer) */
1774 + body.yatra-printing-confirmation a,
1775 + body.yatra-printing-confirmation a:visited {
1776 + color: inherit !important;
1777 + text-decoration: none !important;
1778 + }
1779 +
1780 + /* Avoid orphan headings */
1781 + body.yatra-printing-confirmation h1,
1782 + body.yatra-printing-confirmation h2,
1783 + body.yatra-printing-confirmation h3,
1784 + body.yatra-printing-confirmation h4 {
1785 + page-break-after: avoid !important;
1786 + break-after: avoid !important;
1787 + }
1083 1788 }
1084 1789 </style>
1790 +
1791 +<script>
1792 +(function () {
1793 + document.addEventListener('click', function (e) {
1794 + var btn = e.target.closest('[data-yatra-print="confirmation"]');
1795 + if (!btn) {
1796 + return;
1797 + }
1798 + e.preventDefault();
1799 +
1800 + var card = document.querySelector('.yatra-confirmation-container');
1801 + if (!card) {
1802 + window.print();
1803 + return;
1804 + }
1805 +
1806 + // Wrap (or reuse) a print-only root so the @media print rules can target a single
1807 + // direct child of <body>. Reused on the account page if the same data attribute
1808 + // and CSS rules are added there.
1809 + var root = document.querySelector('.yatra-print-root');
1810 + var addedWrapper = false;
1811 + if (!root) {
1812 + root = document.createElement('div');
1813 + root.className = 'yatra-print-root';
1814 + document.body.appendChild(root);
1815 + addedWrapper = true;
1816 + }
1817 + var clone = card.cloneNode(true);
1818 + // Drop the action buttons from the clone so they don't appear on paper.
1819 + clone.querySelectorAll('.yatra-confirmation-actions').forEach(function (n) { n.remove(); });
1820 + root.innerHTML = '';
1821 + root.appendChild(clone);
1822 +
1823 + document.body.classList.add('yatra-printing-confirmation');
1824 +
1825 + var cleanup = function () {
1826 + document.body.classList.remove('yatra-printing-confirmation');
1827 + if (addedWrapper && root && root.parentNode) {
1828 + root.parentNode.removeChild(root);
1829 + } else if (root) {
1830 + root.innerHTML = '';
1831 + }
1832 + window.removeEventListener('afterprint', cleanup);
1833 + };
1834 +
1835 + window.addEventListener('afterprint', cleanup);
1836 + // Safety net for browsers that don't fire afterprint reliably.
1837 + window.setTimeout(function () {
1838 + if (document.body.classList.contains('yatra-printing-confirmation')) {
1839 + cleanup();
1840 + }
1841 + }, 5000);
1842 +
1843 + window.print();
1844 + });
1845 +})();
1846 +</script>
1085 1847
1086 1848 <?php yatra_get_footer(); ?>
1087 1849