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 | app/Controllers/BookingsController.php +28 -7 3.0.7 → 3.0.16 View file →
@@ -259,8 +259,11 @@
259 259 'trip_id' => (int) $request->get_param('trip_id'),
260 260 'search' => $request->get_param('search') ?: '',
261 261 'date_from' => $request->get_param('date_from') ?: '',
262 262 'date_to' => $request->get_param('date_to') ?: '',
263 + // Column sorting from the table headers — whitelisted in the repository.
264 + 'orderby' => $request->get_param('orderby') ?: '',
265 + 'order' => $request->get_param('order') ?: '',
263 266 ];
264 267
265 268 // Delegate to service
266 269 $result = $this->bookingService->getBookings($filters);
@@ -359,9 +362,9 @@
359 362 return $this->error_response($result['message'] ?? 'Failed to update booking', 400);
360 363 }
361 364
362 365 Logger::info("Booking updated successfully", ['booking_id' => $id]);
363 - return $this->success_response($result['data']);
366 + return $this->success_response($result['data'] ?? null);
364 367
365 368 } catch (\Exception $e) {
366 369 Logger::error("Failed to update booking", ['booking_id' => $id ?? 0, 'data' => $data ?? [], 'error' => $e->getMessage()]);
367 370 return $this->handle_exception($e);
@@ -778,11 +781,21 @@
778 781 $bookingDate = !empty($createdAt) ? date_i18n(get_option('date_format'), strtotime((string) $createdAt)) : '';
779 782 $travelDateRaw = $booking['travel_date'] ?? '';
780 783 $travelDate = !empty($travelDateRaw) ? date_i18n(get_option('date_format'), strtotime((string) $travelDateRaw)) : '';
781 784
785 + // Return date. Prefer the booking's STORED end_date — the actual booked
786 + // return (accounts for a flexible window or a trip duration changed after
787 + // booking). Fall back to the trip duration only when no end is stored:
788 + // duration_days is INCLUSIVE, so the return is travel_date + (days - 1)
789 + // (matches BookingRepository::calculateEndDate; a bare "+ duration_days"
790 + // was one day too far and implied an extra night — see ItineraryPdfBuilder).
782 791 $returnDate = '';
783 - if (!empty($travelDateRaw) && $trip && !empty($trip->duration_days)) {
784 - $returnTimestamp = strtotime((string) $travelDateRaw . ' +' . (int) $trip->duration_days . ' days');
792 + $storedEnd = (string) ($booking['end_date'] ?? '');
793 + if ($storedEnd !== '' && ($travelDateRaw === '' || $storedEnd >= $travelDateRaw)) {
794 + $returnDate = date_i18n(get_option('date_format'), strtotime($storedEnd));
795 + } elseif (!empty($travelDateRaw) && $trip && !empty($trip->duration_days)) {
796 + $returnOffset = max(0, (int) $trip->duration_days - 1);
797 + $returnTimestamp = strtotime((string) $travelDateRaw . ' +' . $returnOffset . ' days');
785 798 $returnDate = date_i18n(get_option('date_format'), $returnTimestamp);
786 799 }
787 800
788 801 $statusRaw = (string) ($booking['booking_status'] ?? $booking['status'] ?? '');
@@ -795,12 +808,14 @@
795 808
796 809 $templateData = [
797 810 'company_name' => $companyName,
798 811 'company_address' => $companyAddress,
812 + 'company_address_lines' => \Yatra\Helpers\FormatHelper::companyAddressLines(),
799 813 'company_email' => $companyEmail,
800 814 'company_phone' => $companyPhone,
801 815 'customer_name' => $customerName,
802 816 'customer_email' => (string) ($booking['contact_email'] ?? $booking['customer_email'] ?? ''),
817 + 'customer_address_lines' => FormatHelper::customerAddressLines($booking),
803 818 'booking_ref' => $bookingRef,
804 819 'booking_date' => $bookingDate,
805 820 'booking_status' => ucfirst($statusRaw ?: 'pending'),
806 821 'status_class' => in_array(strtolower($statusRaw), ['confirmed', 'completed', 'success'], true) ? 'confirmed' :
@@ -808,9 +823,15 @@
808 823 'trip_title' => $trip ? ($trip->title ?? $booking['trip_title'] ?? __('Trip Booking', 'yatra')) : ($booking['trip_title'] ?? __('Trip Booking', 'yatra')),
809 824 // Trip duration comes from duration_days/duration_nights (there is no
810 825 // `duration` column — accessing it caused a blank value + PHP notice).
811 826 'trip_duration' => $trip
812 - ? yatra_format_duration((int) ($trip->duration_days ?? 0), isset($trip->duration_nights) ? (int) $trip->duration_nights : null)
827 + ? yatra_format_duration(
828 + (int) ($trip->duration_days ?? 0),
829 + isset($trip->duration_nights) ? (int) $trip->duration_nights : null,
830 + // Hour-based day tours: "8 hours" instead of "1 day". Absent
831 + // or NULL on every day-based trip, which keeps its wording.
832 + (int) ($trip->duration_hours ?? 0)
833 + )
813 834 : '',
814 835 'trip_difficulty' => $trip ? ($trip->difficulty_name ?? '') : '',
815 836 'departure_location' => $trip ? ($trip->departure_location ?? '') : '',
816 837 'destination' => $trip ? ($trip->destination ?? '') : '',
@@ -816,11 +837,11 @@
816 837 'destination' => $trip ? ($trip->destination ?? '') : '',
817 838 'travel_date' => $travelDate,
818 839 'return_date' => $returnDate,
819 840 'currency_symbol' => $currencySymbol,
820 - 'total_amount' => number_format((float) ($booking['total_amount'] ?? 0), 2),
821 - 'amount_paid' => number_format((float) ($booking['amount_paid'] ?? 0), 2),
822 - 'amount_due' => number_format((float) ($booking['amount_due'] ?? 0), 2),
841 + 'total_amount' => yatra_format_price((float) ($booking['total_amount'] ?? 0), $currency, false),
842 + 'amount_paid' => yatra_format_price((float) ($booking['amount_paid'] ?? 0), $currency, false),
843 + 'amount_due' => yatra_format_price((float) ($booking['amount_due'] ?? 0), $currency, false),
823 844 'traveler_count' => (int) ($booking['travelers_count'] ?? $booking['travelers'] ?? 1),
824 845 ];
825 846
826 847 $pdfService = new PdfService();