PluginProbe
Yatra – Travel Booking & Tour Operator Software / trunk
Yatra – Travel Booking & Tour Operator Software vtrunk
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 2.0.10 All 83 releases
← All changes | app/Controllers/BookingSessionController.php +43 -19 3.0.14.2trunk View file →
@@ -351,11 +351,19 @@
351 351 $total_paid = $paymentRepository->getTotalPaidForBooking($booking_id);
352 352 $total_amount = (float) $booking->total_amount;
353 353
354 354 if ($total_paid >= $total_amount) {
355 + // Fully paid. Respect the Auto-Confirm mode (same as every
356 + // other payment-completion path) — only confirm when the
357 + // mode is 'online' or 'all'; otherwise record the payment
358 + // and leave the booking pending for manual confirmation.
355 359 $prevStatus = (string) ($booking->status ?? 'pending');
356 - $bookingRepository->update($booking_id, ['status' => 'confirmed', 'payment_status' => 'paid']);
357 - \yatra_trigger_booking_confirmed((int) $booking_id, $prevStatus);
360 + if (\yatra_should_confirm_booking_on_payment(true, (int) $booking_id)) {
361 + $bookingRepository->update($booking_id, ['status' => 'confirmed', 'payment_status' => 'paid']);
362 + \yatra_trigger_booking_confirmed((int) $booking_id, $prevStatus, true);
363 + } else {
364 + $bookingRepository->update($booking_id, ['payment_status' => 'paid']);
365 + }
358 366 } else {
359 367 $bookingRepository->update($booking_id, ['payment_status' => 'partial']);
360 368 }
361 369 }
@@ -888,8 +896,11 @@
888 896 'slug' => $trip->slug,
889 897 'featured_image' => $trip->featured_image,
890 898 'duration_days' => (int) $trip->duration_days,
891 899 'duration_nights' => (int) $trip->duration_nights,
900 + // Hour-based day tours (0 on every day-based trip). Additive field:
901 + // existing consumers keep reading duration_days/duration_nights.
902 + 'duration_hours' => (int) ($trip->duration_hours ?? 0),
892 903 'difficulty_level' => $trip->difficulty_level,
893 904 'min_travelers' => (int) ($trip->min_travelers ?: 1),
894 905 'max_travelers' => (int) ($trip->max_travelers ?: 20),
895 906 'original_price' => (float) $trip->original_price,
@@ -1279,9 +1290,9 @@
1279 1290 // GET BOOKING SETTINGS
1280 1291 // ========================================
1281 1292 $settings = [
1282 1293 'booking_confirmation' => \Yatra\Services\SettingsService::get('booking_confirmation', true),
1283 - 'auto_confirm_bookings' => \Yatra\Services\SettingsService::get('auto_confirm_bookings', false),
1294 + 'auto_confirm_mode' => \yatra_get_auto_confirm_mode(),
1284 1295 'require_login' => \Yatra\Services\SettingsService::get('require_login', false),
1285 1296 'allow_guest_checkout' => \Yatra\Services\SettingsService::get('allow_guest_checkout', true),
1286 1297 'booking_expiry_hours' => (int) \Yatra\Services\SettingsService::get('booking_expiry_hours', 24),
1287 1298 'auto_confirm_pay_later' => \Yatra\Services\SettingsService::get('auto_confirm_pay_later', true),
@@ -1364,9 +1375,13 @@
1364 1375 // Which booking-form sections are enabled (Pro Dynamic Form module).
1365 1376 // The default config has every section enabled, so on existing/un-customised
1366 1377 // sites $contact_enabled and $traveler_enabled are both true and the logic
1367 1378 // below behaves exactly as before — only disabled sections change anything.
1368 - $form_config = function_exists('yatra_get_booking_form_config') ? yatra_get_booking_form_config() : [];
1379 + // Scoped to the trip being booked — the same config the checkout
1380 + // rendered, so a field hidden for this trip is never treated as required.
1381 + $form_config = function_exists('yatra_get_booking_form_config')
1382 + ? yatra_get_booking_form_config($trip_id > 0 ? (int) $trip_id : null)
1383 + : [];
1369 1384 $contact_enabled = !isset($form_config['contact_form']['enabled']) || (bool) $form_config['contact_form']['enabled'];
1370 1385 $traveler_enabled = !isset($form_config['traveler_form']['enabled']) || (bool) $form_config['traveler_form']['enabled'];
1371 1386
1372 1387 // Get contact email - handle both flat and nested formats
@@ -2429,21 +2444,29 @@
2429 2444
2430 2445 // ========================================
2431 2446 // DETERMINE BOOKING STATUS
2432 2447 // ========================================
2433 - // Priority:
2434 - // 1. auto_confirm_bookings setting (confirms ALL bookings automatically)
2435 - // 2. For pay_later: auto_confirm_pay_later setting
2436 - // 3. For bank_transfer: always pending until verified
2437 -
2448 + // Priority (Auto-Confirm mode: none | online | all):
2449 + // - 'all' → confirm every booking here at checkout.
2450 + // - 'online' → confirm nothing at checkout; only a successful online
2451 + // gateway payment confirms later (offline stays pending).
2452 + // - 'none' → per-method: pay_later uses auto_confirm_pay_later,
2453 + // bank_transfer stays pending, everything else pending.
2454 +
2438 2455 $booking_status = 'pending';
2439 2456 $status_message = __('Booking received!', 'yatra');
2440 -
2441 - // Check if auto-confirm all bookings is enabled
2442 - if ($settings['auto_confirm_bookings']) {
2443 - // Auto-confirm is enabled - confirm immediately regardless of payment
2457 +
2458 + $auto_confirm_mode = $settings['auto_confirm_mode'] ?? 'none';
2459 + if ($auto_confirm_mode === 'all') {
2460 + // Confirm every booking immediately, regardless of payment.
2444 2461 $booking_status = 'confirmed';
2445 2462 $status_message = __('Booking confirmed!', 'yatra');
2463 + } elseif ($auto_confirm_mode === 'online') {
2464 + // Only successful online payments auto-confirm (at payment
2465 + // completion). Leave the booking pending at checkout; offline
2466 + // methods (bank transfer, pay-later) stay pending for the operator.
2467 + $booking_status = 'pending';
2468 + $status_message = __('Booking received!', 'yatra');
2446 2469 } elseif ($payment_gateway === 'pay_later') {
2447 2470 // Pay Later: Check the specific pay_later auto-confirm setting
2448 2471 if ($settings['auto_confirm_pay_later']) {
2449 2472 $booking_status = 'confirmed';
@@ -3072,17 +3095,18 @@
3072 3095 // (Square, Authorize.Net) reach this generic path but previously left
3073 3096 // the booking at pending/pending — only the payment row was written.
3074 3097 // This now matches handle_successful_payment(): accumulate amount_paid,
3075 3098 // recompute amount_due, set payment_status (paid vs partial), and
3076 - // confirm the booking (a deposit confirms too, consistent with Stripe).
3099 + // confirm the booking only when "Auto-Confirm Bookings" is on
3100 + // (consistent with every gateway).
3077 3101 $newAmountPaid = (float) ($booking->amount_paid ?? 0) + $amount;
3078 3102 $newAmountDue = max(0.0, (float) ($booking->total_amount ?? 0) - $newAmountPaid);
3079 3103 $paymentStatus = $newAmountDue > 0.0 ? 'partial' : 'paid';
3080 3104 $previousStatus = (string) ($booking->status ?? 'pending');
3081 3105
3082 - // Only auto-confirm when the operator allows it (or fully paid). A
3083 - // deposit / partial payment must not confirm when "Auto-Confirm
3084 - // Bookings" is off.
3106 + // Only auto-confirm when "Auto-Confirm Bookings" is on; otherwise the
3107 + // booking stays pending for the operator to confirm manually,
3108 + // regardless of a successful (full or partial) payment.
3085 3109 $shouldConfirm = \yatra_should_confirm_booking_on_payment($newAmountDue <= 0.0, $bookingId);
3086 3110
3087 3111 $bookingUpdate = [
3088 3112 'amount_paid' => $newAmountPaid,
@@ -3094,9 +3118,9 @@
3094 3118 }
3095 3119 $this->bookingRepository->update($bookingId, $bookingUpdate);
3096 3120
3097 3121 if ($shouldConfirm && function_exists('yatra_trigger_booking_confirmed')) {
3098 - \yatra_trigger_booking_confirmed($bookingId, $previousStatus);
3122 + \yatra_trigger_booking_confirmed($bookingId, $previousStatus, true);
3099 3123 }
3100 3124
3101 3125 // Fire payment completed action
3102 3126 do_action('yatra_payment_completed', [
@@ -3442,9 +3466,9 @@
3442 3466 <p style="margin:0 0 8px;"><strong><?php esc_html_e('Booking reference', 'yatra'); ?>:</strong> <?php echo esc_html($reference); ?></p>
3443 3467 <p style="margin:0 0 8px;"><strong><?php esc_html_e('Trip', 'yatra'); ?>:</strong> <?php echo esc_html($trip->title); ?></p>
3444 3468 <p style="margin:0 0 8px;"><strong><?php esc_html_e('Travel date', 'yatra'); ?>:</strong> <?php echo esc_html(date_i18n(get_option('date_format'), strtotime($travel_date))); ?></p>
3445 3469 <p style="margin:0 0 8px;"><strong><?php esc_html_e('Duration', 'yatra'); ?>:</strong> <?php /* translators: 1: number of days, 2: number of nights. */
3446 -echo esc_html(sprintf(__('%1$d days / %2$d nights', 'yatra'), (int) $trip->duration_days, (int) $trip->duration_nights)); ?></p>
3470 +echo esc_html(yatra_format_duration((int) $trip->duration_days, (int) $trip->duration_nights, (int) ($trip->duration_hours ?? 0))); ?></p>
3447 3471 <p style="margin:0;"><strong><?php esc_html_e('Travelers', 'yatra'); ?>:</strong> <?php echo esc_html((string) count($travelers)); ?></p>
3448 3472 </div>
3449 3473 <h3 style="font-size:16px;"><?php esc_html_e('Payment details', 'yatra'); ?></h3>
3450 3474 <p><?php /* translators: %s: total amount (formatted). */