PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.7
Yatra – Travel Booking & Tour Operator Software v3.0.2.7
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
yatra / templates / partials / availability-card.php

availability-card.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.7, at templates/partials/availability-card.php

518 lines 31.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Single departure card for trip availability (included in a loop).
4 * @package Yatra
5 * @var array $card @var int $index @var object $trip_data @var string $pricing_type @var string $selected_date_filter
6 */
7 defined('ABSPATH') || exit;
8 $card = $card ?? [];
9 $index = (int) ($index ?? 0);
10 $trip_data = $trip_data ?? (object) [];
11 $pricing_type = $pricing_type ?? 'regular';
12 $selected_date_filter = $selected_date_filter ?? '';
13 $trip_id = !empty($trip_data->id) ? (int) $trip_data->id : 0;
14 $max_travelers = (int) ($trip_data->max_travelers ?? 20);
15 $item_id = isset($card['id']) ? (string) $card['id'] : (string) $index;
16
17 // Get pricing from card (already calculated with dynamic pricing in Controller)
18 $sale_price = (float) ($card['sale_price'] ?? 0);
19 $original_price = (float) ($card['original_price'] ?? 0);
20
21 // For traveler-based pricing, use first category price for initial total
22 $initial_total_price = $sale_price;
23 if (!empty($card['pricing_type']) && $card['pricing_type'] === 'traveler_based' && !empty($card['traveler_pricing'])) {
24 $first_traveler = is_array($card['traveler_pricing']) ? $card['traveler_pricing'][0] : null;
25 if ($first_traveler) {
26 $first_traveler = is_array($first_traveler) ? (object) $first_traveler : $first_traveler;
27 $initial_total_price = (float) ($first_traveler->effective_price ?? $first_traveler->discounted_price ?? $first_traveler->original_price ?? $sale_price);
28 }
29 }
30
31 $seats_available = (int) ($card['seats_available'] ?? 0);
32 $is_limited = !empty($card['is_limited']);
33 $card_status = $card['status'] ?? 'available';
34 $is_sold_out = isset($card['is_sold_out']) && $card['is_sold_out'];
35 if ($is_sold_out || $card_status === 'sold_out') {
36 $card_status = 'sold_out';
37 }
38
39 // Match Y-m-d even if DB returns datetime (e.g. 2026-08-13 00:00:00)
40 $yatra_card_date_norm = static function ($v): string {
41 $v = trim((string) $v);
42 return preg_match('/^(\d{4}-\d{2}-\d{2})/', $v, $m) ? $m[1] : $v;
43 };
44 $sel_norm = $yatra_card_date_norm($selected_date_filter ?? '');
45 $card_date_norm = $yatra_card_date_norm($card['data_date'] ?? '');
46 $is_selected_card = ($sel_norm !== '' && $card_date_norm !== '' && $sel_norm === $card_date_norm);
47 $should_be_open = $is_selected_card || $index === 0;
48
49 // Apply Yatra date format to availability header dates when the controller returns ISO.
50 $yatra_format_card_date_for_display = static function ($value): string {
51 $raw = trim((string) $value);
52 if ($raw === '') {
53 return '';
54 }
55 // Only transform ISO-like values; leave already-human strings unchanged.
56 if (!preg_match('/^\d{4}-\d{2}-\d{2}/', $raw)) {
57 return $raw;
58 }
59 return \Yatra\Helpers\FormatHelper::formatDate($raw);
60 };
61
62 $from_date_display = $yatra_format_card_date_for_display($card['from_date'] ?? '');
63 $to_date_display = $yatra_format_card_date_for_display($card['to_date'] ?? '');
64 $date_display_display = $yatra_format_card_date_for_display($card['date_display'] ?? '');
65 ?>
66 <div class="yatra-availability-card <?php echo $should_be_open ? 'open' : ''; ?> <?php echo $is_selected_card ? 'selected' : ''; ?> <?php echo $is_limited ? 'limited' : ''; ?> yatra-card-status-<?php echo esc_attr($card_status); ?>"
67 data-availability-id="<?php echo esc_attr($item_id); ?>"
68 data-month="<?php echo esc_attr($card['data_month'] ?? ''); ?>"
69 data-date="<?php echo esc_attr($card['data_date'] ?? ''); ?>"
70 data-price="<?php echo esc_attr($sale_price); ?>"
71 data-seats="<?php echo esc_attr($seats_available); ?>"
72 data-item="<?php echo esc_attr($item_id); ?>"
73 data-index="<?php echo esc_attr($index); ?>">
74
75 <!-- Card Header (Clickable) -->
76 <div class="yatra-availability-card-header yatra-availability-toggle" role="button" tabindex="0" aria-label="<?php esc_attr_e('Toggle availability details', 'yatra'); ?>">
77
78 <?php
79 // Placeholder for discount badge (will be set after price calculation)
80 $final_discount_badge = '';
81 ?>
82 <?php if (!empty($card['date_display'])): ?>
83 <!-- Day Trip: Show date as header -->
84 <div class="yatra-card-date-header">
85 <?php echo yatra_svg_icon('calendar', 'yatra-icon-sm'); ?>
86 <?php echo esc_html($date_display_display); ?>
87 </div>
88 <?php endif; ?>
89 <div class="yatra-card-header-grid <?php echo !empty($card['date_display']) ? 'yatra-day-trip-grid' : ''; ?>">
90
91 <!-- Start/Departure -->
92 <div class="yatra-card-header-item">
93 <div class="yatra-card-header-label"><?php echo esc_html($card['from_label'] ?? __('Departure', 'yatra')); ?></div>
94 <div class="yatra-card-header-date"><?php echo esc_html($from_date_display); ?></div>
95 <div class="yatra-card-header-location"><?php echo esc_html($card['from_location'] ?? ''); ?></div>
96 </div>
97
98 <!-- End/Return -->
99 <div class="yatra-card-header-item">
100 <div class="yatra-card-header-label"><?php echo esc_html($card['to_label'] ?? __('Return', 'yatra')); ?></div>
101 <div class="yatra-card-header-date"><?php echo esc_html($to_date_display); ?></div>
102 <div class="yatra-card-header-location"><?php echo esc_html($card['to_location'] ?? ''); ?></div>
103 </div>
104
105 <!-- Seats -->
106 <div class="yatra-card-header-item">
107 <div class="yatra-card-header-label"><?php esc_html_e('Seats remaining', 'yatra'); ?></div>
108 <div class="yatra-card-header-seats <?php echo $is_limited ? 'limited' : ''; ?>"><?php echo esc_html($card['seats'] ?? '0'); ?></div>
109 <div class="yatra-card-header-sub"><?php esc_html_e('per departure', 'yatra'); ?></div>
110 </div>
111
112 <!-- Price -->
113 <div class="yatra-card-header-price">
114 <div class="yatra-card-price-group">
115 <?php
116 // Pricing is already calculated with dynamic pricing in Controller
117 $display_sale_price = $sale_price;
118 $display_original_price = $original_price;
119
120 // Show discount badge if there's a discount
121 $final_discount_badge = '';
122 if (!empty($card['discount_text'])) {
123 $final_discount_badge = '<div class="yatra-card-discount-badge yatra-badge-discount">' . esc_html($card['discount_text']) . '</div>';
124 }
125
126 echo '<span class="yatra-sale-price">' . yatra_format_price($display_sale_price) . '</span>';
127 ?>
128 </div>
129 <span class="yatra-price-label"><?php echo esc_html__('per person', 'yatra'); ?></span>
130 </div>
131
132 <!-- Toggle Arrow -->
133 <div class="yatra-card-header-arrow">
134 <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
135 <path d="M5 7.5L10 12.5L15 7.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
136 </svg>
137 </div>
138 </div>
139
140 <!-- Badges Container (Status + Discount) -->
141 <div class="yatra-card-badges-container">
142 <!-- Status Badge -->
143 <?php
144 $card_status = $card['status'] ?? 'available';
145 $is_sold_out = isset($card['is_sold_out']) && $card['is_sold_out'];
146
147 // Determine status display
148 if ($is_sold_out || $card_status === 'sold_out') {
149 echo '<div class="yatra-badge-status yatra-badge-sold-out">' . esc_html__('Sold Out', 'yatra') . '</div>';
150 } elseif ($card_status === 'limited') {
151 echo '<div class="yatra-badge-status yatra-badge-limited">' . esc_html__('Limited', 'yatra') . '</div>';
152 } elseif ($card_status === 'blocked') {
153 echo '<div class="yatra-badge-status yatra-badge-blocked">' . esc_html__('Blocked', 'yatra') . '</div>';
154 } elseif ($card_status === 'closed') {
155 echo '<div class="yatra-badge-status yatra-badge-closed">' . esc_html__('Closed', 'yatra') . '</div>';
156 } elseif ($card_status === 'cancelled') {
157 echo '<div class="yatra-badge-status yatra-badge-cancelled">' . esc_html__('Cancelled', 'yatra') . '</div>';
158 } else {
159 echo '<div class="yatra-badge-status yatra-badge-available">' . esc_html__('Available', 'yatra') . '</div>';
160 }
161 ?>
162
163 <!-- Discount Badge -->
164 <?php
165 if (!empty($final_discount_badge)) {
166 echo $final_discount_badge;
167 }
168 ?>
169 </div>
170 </div>
171
172 <!-- Card Body (Expandable) -->
173 <div class="yatra-availability-card-body">
174 <div class="yatra-card-body-content">
175 <div class="yatra-card-info-grid">
176 <div class="yatra-card-info-item">
177 <div class="yatra-card-info-icon">
178 <?php echo yatra_svg_icon('calendar', 'yatra-icon-sm'); ?>
179 </div>
180 <div class="yatra-card-info-content">
181 <div class="yatra-card-info-label"><?php esc_html_e('Duration', 'yatra'); ?></div>
182 <div class="yatra-card-info-value">
183 <?php
184 $duration_days = (int) ($trip_data->duration_days ?? 1);
185 echo esc_html($duration_days . ' ' . _n('Day', 'Days', $duration_days, 'yatra'));
186 ?>
187 </div>
188 </div>
189 </div>
190
191 <div class="yatra-card-info-item">
192 <div class="yatra-card-info-icon">
193 <?php echo yatra_svg_icon('users', 'yatra-icon-sm'); ?>
194 </div>
195 <div class="yatra-card-info-content">
196 <div class="yatra-card-info-label"><?php esc_html_e('Seats left', 'yatra'); ?></div>
197 <div class="yatra-card-info-value"><?php echo esc_html(sprintf(_n('%d seat', '%d seats', $seats_available, 'yatra'), $seats_available)); ?></div>
198 </div>
199 </div>
200
201 <?php
202 $cancellation_policy = '';
203 if (method_exists($trip_data, 'getCancellationPolicy')) {
204 $cancellation_policy = $trip_data->getCancellationPolicy();
205 } elseif (isset($trip_data->cancellation_policy)) {
206 $cancellation_policy = $trip_data->cancellation_policy;
207 }
208
209 $cancellation_label = '';
210 $cancellation_value = '';
211 if (!empty($cancellation_policy)) {
212 // Extract cancellation info from policy
213 $policy_lower = strtolower($cancellation_policy);
214 if (strpos($policy_lower, 'free') !== false || strpos($policy_lower, 'no charge') !== false) {
215 $cancellation_label = __('Free Cancellation', 'yatra');
216 if (preg_match('/(\d+)\s*(hour|day|week)s?\s*before/i', $cancellation_policy, $matches)) {
217 $time_value = $matches[1];
218 $time_unit = $matches[2];
219 $cancellation_value = sprintf(
220 __('Up to %d %s%s before', 'yatra'),
221 $time_value,
222 $time_unit,
223 $time_value > 1 ? 's' : ''
224 );
225 } else {
226 $cancellation_value = __('No charge', 'yatra');
227 }
228 } else {
229 // Non-free cancellation
230 $cancellation_label = __('Cancellation Policy', 'yatra');
231 $cancellation_value = __('See details', 'yatra');
232 }
233 } else {
234 // Default fallback when no policy is set
235 $cancellation_label = __('Cancellation Policy', 'yatra');
236 $cancellation_value = __('May apply', 'yatra');
237 }
238 ?>
239 <div class="yatra-card-info-item">
240 <div class="yatra-card-info-icon">
241 <?php echo yatra_svg_icon('check', 'yatra-icon-sm'); ?>
242 </div>
243 <div class="yatra-card-info-content">
244 <div class="yatra-card-info-label"><?php echo esc_html($cancellation_label); ?></div>
245 <div class="yatra-card-info-value"><?php echo esc_html($cancellation_value); ?></div>
246 </div>
247 </div>
248 </div>
249
250 <div class="yatra-card-traveler-section">
251 <label class="yatra-card-traveler-label"><?php esc_html_e('Travelers', 'yatra'); ?></label>
252
253 <?php
254 // Use card-level pricing type as source of truth
255 $card_pricing_type = $card['pricing_type'] ?? $pricing_type ?? 'regular';
256 $card_price_types = [];
257 $dp_enabled = apply_filters('yatra_dynamic_pricing_enabled', false);
258
259 // Use availability-specific traveler_pricing for traveler-based pricing
260 if ($card_pricing_type === 'traveler_based' && !empty($card['traveler_pricing'])) {
261 $card_price_types = $card['traveler_pricing'];
262 }
263
264 // Normalize traveler pricing to objects if array
265 $normalized_price_types = [];
266 foreach ($card_price_types as $cpt) {
267 if (is_array($cpt)) {
268 $normalized_price_types[] = (object) $cpt;
269 } else {
270 $normalized_price_types[] = $cpt;
271 }
272 }
273 ?>
274
275 <?php if ($card_pricing_type === 'traveler_based' && !empty($normalized_price_types)): ?>
276 <!-- Traveler-based pricing: Show dynamic categories -->
277 <?php
278 // Build traveler rows directly from card-level traveler_pricing data
279 $traveler_rows = [];
280 $display_parts = [];
281 foreach ($normalized_price_types as $pt_index => $pt) {
282 $pt_label = $pt->category_label ?? $pt->label ?? __('Traveler', 'yatra');
283 $pt_pricing_mode = $pt->pricing_mode ?? 'per_person';
284 $pt_is_per_group = ($pt_pricing_mode === 'per_group');
285 $pt_category_id = $pt->category_id ?? $pt_index;
286 $pt_default = $pt_index === 0 ? 1 : 0;
287 $pt_min_qty = 0;
288 $pt_max_qty = (int) min($seats_available, $max_travelers);
289
290 // Determine price with fallback chain
291 $pt_price = 0;
292 if (isset($pt->effective_price) && $pt->effective_price > 0) {
293 $pt_price = (float) $pt->effective_price;
294 } elseif (isset($pt->discounted_price) && $pt->discounted_price > 0) {
295 $pt_price = (float) $pt->discounted_price;
296 } elseif (isset($pt->original_price) && $pt->original_price > 0) {
297 $pt_price = (float) $pt->original_price;
298 }
299
300 // Apply dynamic pricing to traveler category prices
301 if ($dp_enabled && $pt_price > 0) {
302 $pt_price = apply_filters('yatra_availability_price', $pt_price, $trip_id, [
303 'departure_date' => $card['date'] ?? null,
304 'spots_remaining' => $card['spots_remaining'] ?? null,
305 'availability_id' => $item_id,
306 'price_type_id' => $pt->id ?? ($pt->price_type_id ?? null),
307 ]);
308 }
309
310 // Age info
311 $pt_age_text = '';
312 $pt_age_min = isset($pt->age_min) ? (int) $pt->age_min : null;
313 $pt_age_max = isset($pt->age_max) ? (int) $pt->age_max : null;
314 if ($pt_age_min !== null || $pt_age_max !== null) {
315 if ($pt_age_min !== null && $pt_age_max !== null) {
316 $pt_age_text = sprintf(__('(Age %d-%d)', 'yatra'), $pt_age_min, $pt_age_max);
317 } elseif ($pt_age_min !== null) {
318 $pt_age_text = sprintf(__('(Age %d+)', 'yatra'), $pt_age_min);
319 } else {
320 $pt_age_text = sprintf(__('(Up to age %d)', 'yatra'), $pt_age_max);
321 }
322 }
323
324 // Build pricing label for per_group mode
325 $pricing_label = '';
326 if ($pt_is_per_group) {
327 if (!empty($pt->min_pax) && !empty($pt->max_pax)) {
328 $pricing_label = sprintf(__('per group (%d-%d pax)', 'yatra'), $pt->min_pax, $pt->max_pax);
329 } elseif (!empty($pt->max_pax)) {
330 $pricing_label = sprintf(__('per group (up to %d pax)', 'yatra'), $pt->max_pax);
331 } elseif (!empty($pt->min_pax)) {
332 $pricing_label = sprintf(__('per group (%d+ pax)', 'yatra'), $pt->min_pax);
333 } else {
334 $pricing_label = __('per group', 'yatra');
335 }
336 }
337
338 // Build price HTML
339 $pt_price_html = '';
340 if ($pt_price > 0) {
341 $pt_price_html = '<div class="yatra-quantity-price-wrapper">';
342 $pt_price_html .= '<span class="yatra-quantity-price">' . yatra_format_price($pt_price) . '</span>';
343 if ($pt_is_per_group) {
344 $pt_price_html .= '<span class="yatra-pricing-mode-label yatra-pricing-mode-group">' . esc_html($pricing_label) . '</span>';
345 }
346 $pt_price_html .= '</div>';
347 }
348
349 $input_id = 'traveler_' . $pt_category_id;
350
351 $traveler_rows[] = [
352 'label' => $pt_label,
353 'subtitle' => $pt_age_text,
354 'price_html' => $pt_price_html,
355 'row_attrs' => [
356 'data-category-id' => $pt_category_id,
357 'data-price' => $pt_price,
358 'data-pricing-mode' => $pt_pricing_mode,
359 ],
360 'minus_disabled' => $pt_default <= $pt_min_qty,
361 'plus_disabled' => $pt_default >= $pt_max_qty,
362 'minus_attrs' => [
363 'data-target' => $input_id,
364 'data-item' => $item_id,
365 'data-category' => $pt_category_id,
366 'aria-label' => sprintf(__('Decrease %s', 'yatra'), $pt_label),
367 ],
368 'plus_attrs' => [
369 'data-target' => $input_id,
370 'data-item' => $item_id,
371 'data-category' => $pt_category_id,
372 'aria-label' => sprintf(__('Increase %s', 'yatra'), $pt_label),
373 ],
374 'input_attrs' => [
375 'id' => $input_id,
376 'name' => 'travelers[' . $pt_category_id . ']',
377 'value' => $pt_default,
378 'min' => $pt_min_qty,
379 'max' => $pt_max_qty,
380 'data-item' => $item_id,
381 'data-category' => $pt_category_id,
382 'data-category-label' => $pt_label,
383 'data-price' => $pt_price,
384 'data-pricing-mode' => $pt_pricing_mode,
385 ],
386 ];
387
388 if ($pt_default > 0) {
389 $display_parts[] = $pt_label . ' x ' . $pt_default;
390 }
391 }
392
393 $traveler_display_text = !empty($display_parts) ? implode(', ', $display_parts) : __('Select travelers', 'yatra');
394
395 // Setup variables for traveler-selector.php using availability-specific data
396 $root_id = '';
397 $root_class = 'yatra-booking-field-select yatra-participants-select yatra-availability-participants';
398 $container_attrs = [
399 'data-item' => $item_id,
400 ];
401
402 $display_id = 'participants-display';
403 $display_class = 'yatra-participants-display yatra-availability-participants-display';
404 $display_attrs = [
405 'data-item' => $item_id,
406 ];
407
408 $dropdown_id = '';
409 $dropdown_class = 'yatra-booking-quantity-selector yatra-availability-quantity-selector';
410 $dropdown_attrs = [
411 'data-item' => $item_id,
412 ];
413
414 $display_text = $traveler_display_text;
415 $icon_html = yatra_svg_icon('users', 'yatra-icon-sm');
416 $rows = $traveler_rows;
417
418 include YATRA_PLUGIN_PATH . 'templates/partials/traveler-selector.php';
419 ?>
420 <?php else: ?>
421 <!-- Regular pricing: Show simple number of travelers -->
422 <div class="yatra-booking-travelers-simple yatra-availability-travelers-simple" data-item="<?php echo esc_attr($item_id); ?>">
423 <div class="yatra-booking-field-icon">
424 <?php echo yatra_svg_icon('users', 'yatra-icon-sm'); ?>
425 </div>
426 <div class="yatra-quantity-controls-inline">
427 <button type="button" class="yatra-quantity-btn yatra-quantity-minus" data-target="num-travelers-<?php echo esc_attr($item_id); ?>" aria-label="<?php esc_attr_e('Decrease travelers', 'yatra'); ?>" disabled>
428 <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
429 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 12H4"/>
430 </svg>
431 </button>
432 <input type="number"
433 id="num-travelers-<?php echo esc_attr($item_id); ?>"
434 class="yatra-quantity-input-simple yatra-availability-num-travelers"
435 data-item="<?php echo esc_attr($item_id); ?>"
436 value="1"
437 min="1"
438 max="<?php echo esc_attr(min($seats_available, $max_travelers)); ?>"
439 readonly
440 data-price="<?php echo esc_attr($sale_price); ?>">
441 <button type="button" class="yatra-quantity-btn yatra-quantity-plus" data-target="num-travelers-<?php echo esc_attr($item_id); ?>" aria-label="<?php esc_attr_e('Increase travelers', 'yatra'); ?>">
442 <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
443 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
444 </svg>
445 </button>
446 </div>
447 <span class="yatra-travelers-label"><?php esc_html_e('travelers', 'yatra'); ?></span>
448 </div>
449 <?php endif; ?>
450
451 <div class="yatra-card-action-help"><?php esc_html_e('Select travelers to update the total, then click Book Now.', 'yatra'); ?></div>
452 </div>
453 </div>
454
455 <!-- Booking Row at Bottom -->
456 <div class="yatra-card-booking-row">
457 <div class="yatra-card-total-box">
458 <div class="yatra-card-total-label"><?php esc_html_e('Total', 'yatra'); ?></div>
459 <div class="yatra-card-total-note" data-item="<?php echo esc_attr($item_id); ?>"><?php esc_html_e('for 1 traveler', 'yatra'); ?></div>
460 <div class="yatra-card-total-amount" data-item="<?php echo esc_attr($item_id); ?>" data-base-price="<?php echo esc_attr($initial_total_price); ?>">
461 <?php
462 $formatted_total = yatra_format_price($initial_total_price);
463 echo esc_html($formatted_total);
464 ?>
465 </div>
466 </div>
467 <?php
468 // Prepare price_types JSON for JavaScript
469 $price_types_json = '';
470 if (!empty($normalized_price_types)) {
471 $price_types_for_js = array_map(function($pt) {
472 $pt = (object) $pt;
473 return [
474 'category_id' => $pt->category_id ?? null,
475 'category_label' => $pt->category_label ?? $pt->label ?? '',
476 'original_price' => $pt->original_price ?? 0,
477 'sale_price' => $pt->sale_price ?? null,
478 'discounted_price' => $pt->discounted_price ?? null,
479 'effective_price' => $pt->effective_price ?? $pt->sale_price ?? $pt->discounted_price ?? $pt->original_price ?? 0,
480 'age_min' => $pt->age_min ?? null,
481 'age_max' => $pt->age_max ?? null,
482 ];
483 }, $normalized_price_types);
484 $price_types_json = wp_json_encode($price_types_for_js);
485 }
486
487 // Get departure time - prefer card data, fallback to from_date if it looks like time
488 $card_departure_time = '';
489 if (!empty($card['departure_time'])) {
490 $card_departure_time = $card['departure_time'];
491 } elseif (!empty($card['from_date']) && preg_match('/^\d{1,2}:\d{2}\s*(AM|PM)?$/i', $card['from_date'])) {
492 $card_departure_time = $card['from_date'];
493 }
494
495 // Is this a day trip?
496 $is_card_day_trip = !empty($card['is_day_trip']) || !empty($card['date_display']);
497 ?>
498 <button type="button"
499 class="yatra-card-book-btn"
500 data-trip-id="<?php echo esc_attr($trip_id); ?>"
501 data-availability-id="<?php echo esc_attr($item_id); ?>"
502 data-date="<?php echo esc_attr($card['data_date'] ?? ''); ?>"
503 data-departure-time="<?php echo esc_attr($card_departure_time); ?>"
504 data-is-day-trip="<?php echo $is_card_day_trip ? '1' : '0'; ?>"
505 data-pricing-type="<?php echo esc_attr($card_pricing_type); ?>"
506 data-price-types="<?php echo esc_attr($price_types_json); ?>"
507 data-price="<?php echo esc_attr($sale_price); ?>"
508 data-item="<?php echo esc_attr($item_id); ?>">
509 <?php echo yatra_svg_icon('shopping-cart', 'yatra-icon-sm'); ?>
510 <span class="yatra-card-book-btn-text">
511 <span class="yatra-card-book-btn-title"><?php esc_html_e('Book Now', 'yatra'); ?></span>
512 <span class="yatra-card-book-btn-subtitle"><?php esc_html_e('Continue to booking', 'yatra'); ?></span>
513 </span>
514 </button>
515 </div>
516 </div>
517 </div>
518