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 / pricing-summary.php

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

347 lines 15.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Pricing Summary Template
4 *
5 * Displays the pricing breakdown in the booking summary.
6 * This template is loaded via AJAX when pricing needs to be updated.
7 *
8 * @package Yatra
9 * @since 3.0.0
10 *
11 * Variables available:
12 * @var \Yatra\Models\Checkout $checkout Checkout model with all pricing data
13 */
14
15 defined('ABSPATH') || exit;
16
17 // Fallback: if $checkout is not available, try to get it from $booking
18 if (!isset($checkout) && isset($booking) && isset($booking->checkout)) {
19 $checkout = $booking->checkout;
20 }
21
22 // If still no checkout model, we can't display anything
23 if (!isset($checkout) || !($checkout instanceof \Yatra\Models\Checkout)) {
24 echo '<p>' . esc_html__('Pricing information not available.', 'yatra') . '</p>';
25 return;
26 }
27 ?>
28
29 <?php if ($checkout->isTravelerBased() && !empty($checkout->getCategoryBreakdown())) : ?>
30 <!-- Traveler-based pricing breakdown -->
31 <div class="yatra-price-breakdown-categories" id="price-breakdown-categories">
32 <?php foreach ($checkout->getCategoryBreakdown() as $cat) : ?>
33 <?php
34 // Get pricing mode from category data
35 $pricing_mode = $cat['pricing_mode'] ?? 'per_person';
36 $is_per_group = ($pricing_mode === 'per_group');
37
38 // Calculate per-unit price for display
39 $per_unit_price = $cat['count'] > 0 ? $cat['subtotal'] / $cat['count'] : 0;
40 $per_unit_formatted = $checkout->formatPrice($per_unit_price);
41 ?>
42 <div class="yatra-price-row yatra-category-subtotal" data-category-id="<?php echo esc_attr($cat['category_id']); ?>">
43 <span>
44 <?php echo esc_html($cat['label']); ?> x <span class="category-count"><?php echo (int) $cat['count']; ?></span>
45 <?php if ($cat['count'] > 0) : ?>
46 <span class="yatra-price-calculation" style="color: #6b7280; font-size: 0.9em; font-weight: normal;">
47 <?php if ($is_per_group) : ?>
48 (<?php echo esc_html($checkout->formatPrice($cat['subtotal'])); ?> <?php esc_html_e('per group', 'yatra'); ?>)
49 <?php else : ?>
50 (<?php echo esc_html($per_unit_formatted); ?> x <?php echo (int) $cat['count']; ?>)
51 <?php endif; ?>
52 </span>
53 <?php endif; ?>
54 </span>
55 <span class="category-subtotal"><?php echo esc_html($checkout->formatPrice($cat['subtotal'])); ?></span>
56 </div>
57 <?php endforeach; ?>
58 </div>
59 <?php else : ?>
60 <!-- Regular pricing -->
61 <div class="yatra-price-row">
62 <span><?php esc_html_e('Price per person', 'yatra'); ?></span>
63 <span><?php echo esc_html($checkout->getFormattedPricePerPerson()); ?></span>
64 </div>
65 <div class="yatra-price-row">
66 <span><?php esc_html_e('Number of travelers', 'yatra'); ?></span>
67 <span id="summary-travelers"><?php echo (int) $checkout->getTotalTravelers(); ?></span>
68 </div>
69 <?php endif; ?>
70
71 <!-- Gross Total (base trip cost before services/discounts/taxes) -->
72 <div class="yatra-price-row yatra-price-subtotal">
73 <span><strong><?php esc_html_e('Gross Total', 'yatra'); ?></strong></span>
74 <span id="summary-gross-total"><strong><?php echo esc_html($checkout->getFormattedGrossTotal()); ?></strong></span>
75 </div>
76
77 <?php if ($checkout->hasCoupon()) : ?>
78 <!-- Coupon Discount -->
79 <div class="yatra-price-row yatra-price-discount" id="yatra-discount-row">
80 <span class="yatra-discount-label">
81 <?php echo esc_html($checkout->getCouponDiscountLabel()); ?>
82 <span class="yatra-discount-code">(<?php echo esc_html($checkout->getCouponCode()); ?>)</span>
83 </span>
84 <span class="yatra-discount-amount" style="color: #059669;">-<?php echo esc_html($checkout->getFormattedCouponDiscount()); ?></span>
85 </div>
86 <?php endif; ?>
87
88 <?php if ($checkout->getGroupDiscountAmount() > 0) : ?>
89 <!-- Group Discount -->
90 <div class="yatra-price-row yatra-price-discount yatra-group-discount-row" id="yatra-group-discount-row">
91 <span class="yatra-discount-label">
92 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline-block; vertical-align: middle; margin-right: 4px;">
93 <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
94 <circle cx="9" cy="7" r="4"></circle>
95 <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
96 <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
97 </svg>
98 <?php echo esc_html($checkout->getGroupDiscountLabel()); ?>
99 </span>
100 <span class="yatra-discount-amount" style="color: #059669; font-weight: 500;">-<?php echo esc_html($checkout->getFormattedGroupDiscount()); ?></span>
101 </div>
102 <?php endif; ?>
103
104 <?php if ($checkout->hasItineraryCosts()) : ?>
105 <style>
106 .yatra-price-tooltip {
107 position: relative;
108 display: inline-block;
109 margin-left: 4px;
110 vertical-align: middle;
111 }
112
113 .yatra-price-tooltip:hover::after {
114 content: attr(title);
115 position: absolute;
116 bottom: 125%;
117 left: 50%;
118 transform: translateX(-50%);
119 background: #1f2937;
120 color: white;
121 padding: 6px 10px;
122 border-radius: 6px;
123 font-size: 12px;
124 white-space: nowrap;
125 z-index: 1000;
126 pointer-events: none;
127 opacity: 0;
128 transition: opacity 0.3s;
129 }
130
131 .yatra-price-tooltip:hover::before {
132 content: '';
133 position: absolute;
134 bottom: 120%;
135 left: 50%;
136 transform: translateX(-50%);
137 border: 5px solid transparent;
138 border-top-color: #1f2937;
139 z-index: 1000;
140 pointer-events: none;
141 opacity: 0;
142 transition: opacity 0.3s;
143 }
144
145 .yatra-price-tooltip:hover::after,
146 .yatra-price-tooltip:hover::before {
147 opacity: 1;
148 }
149 </style>
150 <!-- Itinerary Costs -->
151 <div class="yatra-price-section">
152 <div class="yatra-price-section-title">
153 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
154 <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
155 <polyline points="9 22 9 12 15 12 15 22"></polyline>
156 </svg>
157 <?php esc_html_e('Itinerary Costs', 'yatra'); ?>
158 </div>
159 <?php foreach ($checkout->getItineraryCosts() as $cost) : ?>
160 <div class="yatra-price-row yatra-price-itinerary">
161 <span>
162 <?php
163 echo esc_html($cost['name']);
164 if (!empty($cost['price_per'])) {
165 if ($cost['price_per'] === 'person') {
166 echo ' ' . esc_html_x('(per person)', 'pricing type', 'yatra');
167 $quantity = $checkout->getTotalTravelers();
168 $unit_price = $cost['price'] ?? 0;
169 $total_cost = $unit_price * $quantity;
170 ?>
171 <span class="yatra-price-tooltip" title="<?php
172 // Build tooltip data with proper escaping and currency symbol
173 $currency_symbol = $checkout->getCurrencySymbol();
174 $unit_price_formatted = number_format($unit_price, 2);
175 $total_cost_formatted = number_format($total_cost, 2);
176 $tooltip_text = sprintf('%s%s × %d travelers = %s%s',
177 $currency_symbol,
178 $unit_price_formatted,
179 (int) $quantity,
180 $currency_symbol,
181 $total_cost_formatted
182 );
183 echo esc_attr($tooltip_text);
184 ?>">
185 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="opacity: 0.6; cursor: help;">
186 <circle cx="12" cy="12" r="10"></circle>
187 <line x1="12" y1="16" x2="12" y2="12"></line>
188 <line x1="12" y1="8" x2="12.01" y2="8"></line>
189 </svg>
190 </span>
191 <?php
192 } elseif ($cost['price_per'] === 'group') {
193 echo ' ' . esc_html_x('(per booking)', 'pricing type', 'yatra');
194 } else {
195 echo ' ' . esc_html_x('(flat rate)', 'pricing type', 'yatra');
196 }
197 }
198 ?>
199 </span>
200 <span><?php
201 if (!empty($cost['price_per']) && $cost['price_per'] === 'person') {
202 $quantity = $checkout->getTotalTravelers();
203 $unit_price = $cost['price'] ?? 0;
204 $total_cost = $unit_price * $quantity;
205 echo esc_html($checkout->formatPrice($total_cost));
206 } else {
207 echo esc_html($checkout->formatPrice($cost['price'] ?? 0));
208 }
209 ?></span>
210 </div>
211 <?php endforeach; ?>
212 </div>
213 <?php endif; ?>
214
215 <?php if ($checkout->hasAdditionalServices()) : ?>
216 <!-- Additional Services -->
217 <?php foreach ($checkout->getAdditionalServices() as $service) : ?>
218 <?php if (!empty($service['selected'])) : ?>
219 <?php
220 $service_price = $service['calculated_price'] ?? $service['price'] ?? 0;
221 $is_included = !empty($service['is_included']);
222 $is_required = !empty($service['is_required']);
223 ?>
224 <div class="yatra-price-row yatra-price-service<?php echo $is_included ? ' yatra-service-included' : ''; ?>">
225 <span>
226 <?php echo esc_html($service['name']); ?>
227 <?php if ($is_required && !$is_included) : ?>
228 <span class="yatra-service-badge yatra-badge-required"><?php esc_html_e('Required', 'yatra'); ?></span>
229 <?php endif; ?>
230 </span>
231 <?php if ($is_included) : ?>
232 <span class="yatra-service-included-badge"><?php esc_html_e('Included', 'yatra'); ?></span>
233 <?php else : ?>
234 <span><?php echo esc_html($checkout->formatPrice($service_price)); ?></span>
235 <?php endif; ?>
236 </div>
237 <?php endif; ?>
238 <?php endforeach; ?>
239 <?php endif; ?>
240
241 <?php if (!empty($dynamic_pricing) && !empty($dynamic_pricing['rules'])) : ?>
242 <!-- Dynamic Pricing Information -->
243 <div class="yatra-price-section yatra-dynamic-pricing-section">
244 <div class="yatra-price-section-title">
245 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
246 <path d="M12 2v20m8-10H4"></path>
247 <circle cx="12" cy="12" r="3"></circle>
248 </svg>
249 <?php echo esc_html($dynamic_pricing['label']); ?>
250 </div>
251
252 <?php if (!empty($dynamic_pricing['show_original_price']) && $dynamic_pricing['original_price'] > 0 && $dynamic_pricing['original_price'] != $dynamic_pricing['final_price']) : ?>
253 <div class="yatra-price-row yatra-original-price">
254 <span><?php esc_html_e('Original Price', 'yatra'); ?></span>
255 <span class="yatra-original-price-amount" style="text-decoration: line-through; color: #6b7280;">
256 <?php echo esc_html(yatra_format_price($dynamic_pricing['original_price'], $currency ?? null)); ?>
257 </span>
258 </div>
259 <?php endif; ?>
260
261 <?php if (!empty($dynamic_pricing['show_savings_badge']) && $dynamic_pricing['savings'] > 0) : ?>
262 <div class="yatra-price-row yatra-savings-badge" style="background-color: #dcfce7; color: #166534; padding: 8px 12px; border-radius: 6px; margin: 8px 0;">
263 <span style="font-weight: 600;">
264 <?php
265 printf(
266 /* translators: %s: savings percentage */
267 esc_html__('You save %s', 'yatra'),
268 '<span style="color: #16a34a; font-weight: 700;">' . number_format($dynamic_pricing['savings_percent'], 1) . '%</span>'
269 );
270 ?>
271 </span>
272 <span style="font-weight: 600; color: #16a34a;">
273 <?php echo esc_html(yatra_format_price($dynamic_pricing['savings'], $currency ?? null)); ?>
274 </span>
275 </div>
276 <?php endif; ?>
277
278 <?php if (!empty($dynamic_pricing['show_urgency_messages']) && !empty($dynamic_pricing['rules'])) : ?>
279 <div class="yatra-price-row yatra-urgency-message" style="background-color: #fef3c7; color: #92400e; padding: 8px 12px; border-radius: 6px; margin: 8px 0; font-size: 14px;">
280 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline-block; vertical-align: middle; margin-right: 6px;">
281 <circle cx="12" cy="12" r="10"></circle>
282 <line x1="12" y1="8" x2="12" y2="12"></line>
283 <line x1="12" y1="16" x2="12.01" y2="16"></line>
284 </svg>
285 <?php
286 $ruleCount = count($dynamic_pricing['rules']);
287 if ($ruleCount === 1) {
288 esc_html_e('Limited time offer! Dynamic pricing applied.', 'yatra');
289 } else {
290 printf(
291 /* translators: %d: number of rules */
292 esc_html(_n('%d dynamic pricing rule applied!', '%d dynamic pricing rules applied!', $ruleCount, 'yatra')),
293 (int) $ruleCount
294 );
295 }
296 ?>
297 </div>
298 <?php endif; ?>
299 </div>
300 <?php endif; ?>
301
302 <!-- Taxable Amount (SubTotal - amount that tax is calculated on) -->
303 <?php
304 $has_discount = $checkout->hasCoupon() || $checkout->getGroupDiscountAmount() > 0;
305 // Only show taxable amount if there are taxes AND if there's a discount
306 if ($checkout->hasTaxes() && $has_discount) :
307 $taxable_amount = $checkout->getTaxableAmount();
308 ?>
309 <div class="yatra-price-row yatra-price-subtotal" style="border-top: 1px dashed #e5e7eb; margin-top: 8px; padding-top: 8px;">
310 <span><strong><?php esc_html_e('Subtotal (Taxable Amount)', 'yatra'); ?></strong></span>
311 <span id="summary-taxable-amount"><strong><?php echo esc_html($checkout->formatPrice($taxable_amount)); ?></strong></span>
312 </div>
313 <?php endif; ?>
314
315 <?php if ($checkout->hasTaxes()) : ?>
316 <!-- Tax Breakdown -->
317 <div class="yatra-price-section yatra-tax-section">
318 <div class="yatra-price-section-title">
319 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
320 <path d="M9 14l2 2 4-4"></path>
321 <path d="M21 12c.552 0 1-.448 1-1V8c0-.552-.448-1-1-1h-1V6a2 2 0 00-2-2H4a2 2 0 00-2 2v1c0 .552.448 1 1 1h1v1c0 .552.448 1 1 1h1M3 15a1 1 0 011-1h2.5a1 1 0 011 1v1.5"></path>
322 </svg>
323 <?php esc_html_e('Tax', 'yatra'); ?>
324 </div>
325 <?php foreach ($checkout->getTaxBreakdown() as $tax) : ?>
326 <div class="yatra-price-row yatra-price-tax">
327 <span><?php echo esc_html($tax['name']); ?> (<?php echo esc_html($tax['rate']); ?>%)</span>
328 <span><?php echo esc_html($checkout->formatPrice($tax['amount'])); ?></span>
329 </div>
330 <?php endforeach; ?>
331 </div>
332 <?php endif; ?>
333
334 <!-- Net Amount -->
335 <div class="yatra-price-row yatra-price-total">
336 <span><strong><?php esc_html_e('Net Amount', 'yatra'); ?></strong></span>
337 <span id="summary-total"><strong><?php echo esc_html($checkout->getFormattedNetTotal()); ?></strong></span>
338 </div>
339
340 <?php if ($checkout->getPaymentMethod() !== 'full') : ?>
341 <!-- Due Now -->
342 <div class="yatra-price-row yatra-price-due">
343 <span><?php esc_html_e('Due Now', 'yatra'); ?></span>
344 <span id="summary-due"><strong><?php echo esc_html($checkout->getFormattedAmountDue()); ?></strong></span>
345 </div>
346 <?php endif; ?>
347