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/partials/pricing-summary.php +87 -100 3.0.2.6 → 3.0.16 View file →
@@ -67,11 +67,67 @@
67 67 <span id="summary-travelers"><?php echo (int) $checkout->getTotalTravelers(); ?></span>
68 68 </div>
69 69 <?php endif; ?>
70 70
71 -<!-- Gross Total (base trip cost before services/discounts/taxes) -->
71 +<?php
72 +// Pull dynamic-pricing breakdown — either from the explicit `$dynamic_pricing`
73 +// template var (used by the AJAX summary refresh + initial page render) or, as
74 +// a fallback, from the Checkout model. Both paths point at the same data; the
75 +// fallback covers any future render context that forgets to pass the variable.
76 +if (!isset($dynamic_pricing) || !is_array($dynamic_pricing)) {
77 + $dynamic_pricing = $checkout->getDynamicPricing();
78 +}
79 +$dp_total_adjustment = (float) $checkout->getDynamicPricingTotalAdjustment();
80 +$has_dp = !empty($dynamic_pricing) && !empty($dynamic_pricing['rules']);
81 +?>
82 +
83 +<?php
84 +// Additional Services are picked above the Pricing Summary in their own card
85 +// (see booking-content.php). When the user toggles a checkbox, booking.js
86 +// POSTs to /booking/session then refreshes this partial via /booking/summary —
87 +// the selected-services iteration further down then renders them inline as
88 +// compact price rows so the customer sees what's contributing to the total.
89 +?>
90 +
91 +<?php
92 +// Dynamic-pricing caption removed per UX request — the customer can see the
93 +// effective per-unit price in the traveler row itself; an extra "X pricing
94 +// rule applied" line just adds noise. The DP impact is implicit in the
95 +// post-DP price now displayed in the category row above.
96 +?>
97 +
98 +<?php if ($checkout->hasAdditionalServices()) : ?>
99 +<!-- Selected Additional Services — rendered ABOVE Trip Subtotal so the
100 + subtotal reads as the natural sum of (traveler categories + services).
101 + The Pro AdditionalServicesModule already folds these into the gross
102 + total, so we only render the rows here for transparency — not for
103 + summing again. -->
104 +<?php foreach ($checkout->getAdditionalServices() as $service) : ?>
105 + <?php if (!empty($service['selected'])) :
106 + $service_price = $service['calculated_price'] ?? $service['price'] ?? 0;
107 + $is_included = !empty($service['is_included']);
108 + $is_required = !empty($service['is_required']);
109 + ?>
110 + <div class="yatra-price-row yatra-price-service<?php echo $is_included ? ' yatra-service-included' : ''; ?>">
111 + <span>
112 + <?php echo esc_html($service['name']); ?>
113 + <?php if ($is_required && !$is_included) : ?>
114 + <span class="yatra-service-badge yatra-badge-required"><?php esc_html_e('Required', 'yatra'); ?></span>
115 + <?php endif; ?>
116 + </span>
117 + <?php if ($is_included) : ?>
118 + <span class="yatra-service-included-badge"><?php esc_html_e('Included', 'yatra'); ?></span>
119 + <?php else : ?>
120 + <span><?php echo esc_html($checkout->formatPrice($service_price)); ?></span>
121 + <?php endif; ?>
122 + </div>
123 + <?php endif; ?>
124 +<?php endforeach; ?>
125 +<?php endif; ?>
126 +
127 +<!-- Trip Subtotal (categories + services, before discounts/taxes) -->
72 128 <div class="yatra-price-row yatra-price-subtotal">
73 - <span><strong><?php esc_html_e('Gross Total', 'yatra'); ?></strong></span>
129 + <span><strong><?php esc_html_e('Trip Subtotal', 'yatra'); ?></strong></span>
74 130 <span id="summary-gross-total"><strong><?php echo esc_html($checkout->getFormattedGrossTotal()); ?></strong></span>
75 131 </div>
76 132
77 133 <?php if ($checkout->hasCoupon()) : ?>
@@ -168,18 +224,19 @@
168 224 $unit_price = $cost['price'] ?? 0;
169 225 $total_cost = $unit_price * $quantity;
170 226 ?>
171 227 <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
228 + // Tooltip: unit price × travelers = line total. Formatted
229 + // through the canonical formatter so decimals, separators
230 + // and currency symbol match the rest of the site (single
231 + // source of truth). zero_is_unknown=false so a 0 line
232 + // renders as a number, not "Contact for pricing".
233 + $tooltip_text = sprintf(
234 + /* translators: 1: formatted unit price, 2: number of travelers, 3: formatted line total */
235 + __('%1$s × %2$d travelers = %3$s', 'yatra'),
236 + yatra_format_price($unit_price, null, false),
237 + (int) $quantity,
238 + yatra_format_price($total_cost, null, false)
182 239 );
183 240 echo esc_attr($tooltip_text);
184 241 ?>">
185 242 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="opacity: 0.6; cursor: help;">
@@ -211,94 +268,23 @@
211 268 <?php endforeach; ?>
212 269 </div>
213 270 <?php endif; ?>
214 271
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; ?>
272 +<?php
273 +// (Selected Additional Services moved above the Trip Subtotal line for the
274 +// correct visual order: categories → services → subtotal. Old position
275 +// rendered them after the subtotal, which is what made the "double-count
276 +// looking" sidebar — visually it seemed like services were added on top of
277 +// an already-services-inclusive subtotal.)
278 +?>
240 279
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; ?>
280 +<?php
281 +// (Old "Dynamic Pricing" section with Original Price strike-through, savings
282 +// badge, and urgency banner removed — the compact line item at the top of
283 +// this template is now the single source of truth for DP in the sidebar.
284 +// Admins who want the strike-through / badge / urgency styling can re-add it
285 +// in a custom template override; keeping the default summary clean.)
286 +?>
301 287
302 288 <!-- Taxable Amount (SubTotal - amount that tax is calculated on) -->
303 289 <?php
304 290 $has_discount = $checkout->hasCoupon() || $checkout->getGroupDiscountAmount() > 0;
@@ -315,11 +301,12 @@
315 301 <?php if ($checkout->hasTaxes()) : ?>
316 302 <!-- Tax Breakdown -->
317 303 <div class="yatra-price-section yatra-tax-section">
318 304 <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>
305 + <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
306 + <line x1="19" y1="5" x2="5" y2="19"></line>
307 + <circle cx="6.5" cy="6.5" r="2.5"></circle>
308 + <circle cx="17.5" cy="17.5" r="2.5"></circle>
322 309 </svg>
323 310 <?php esc_html_e('Tax', 'yatra'); ?>
324 311 </div>
325 312 <?php foreach ($checkout->getTaxBreakdown() as $tax) : ?>