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/Repositories/BookingRepository.php +52 -11 3.0.14.2trunk View file →
@@ -264,8 +264,14 @@
264 264 t.duration_days, t.duration_nights, t.difficulty_level,
265 265 t.starting_location, t.ending_location"
266 266 ];
267 267
268 + // Hour-based day tours (3.0.14+ column) — guarded so an install whose
269 + // upgrade ALTER has not run yet keeps rendering the confirmation page.
270 + if ($tripRepository->hasTripColumn('duration_hours')) {
271 + $selectParts[] = 't.duration_hours';
272 + }
273 +
268 274 $joins[] = "LEFT JOIN {$tripClassificationTable} tc ON tc.trip_id = t.id";
269 275 $joins[] = "LEFT JOIN {$classificationTable} cls ON cls.id = tc.classification_id";
270 276 $selectParts[] = "GROUP_CONCAT(DISTINCT cls.name ORDER BY tc.`sort_order` SEPARATOR ',') as trip_classifications";
271 277
@@ -747,13 +753,24 @@
747 753 // Use TripRepository for trips table
748 754 $tripRepository = new \Yatra\Repositories\TripRepository();
749 755 $tripsTable = $tripRepository->getTableName();
750 756
757 + // Confirmed bookings, plus PENDING bookings that have paid something
758 + // (a deposit). Under the Auto-Confirm `online` mode a deposit booking
759 + // legitimately stays pending until the balance is paid; those customers
760 + // are real travellers and must still get the pre-trip reminder — which
761 + // already carries the "outstanding balance, please pay before travel"
762 + // block for exactly this case. Unpaid pending bookings stay excluded.
763 + //
764 + // No `t.currency`: the trips table has never had that column, so the
765 + // previous SELECT threw "Unknown column" — get_results() then returned
766 + // nothing and the reminder cron silently sent zero emails. The booking's
767 + // own currency arrives via b.* (and is no longer clobbered by the join).
751 768 return $this->wpdb->get_results($this->wpdb->prepare(
752 - "SELECT b.*, t.title as trip_title, t.currency
769 + "SELECT b.*, t.title as trip_title
753 770 FROM {$table} b
754 771 LEFT JOIN {$tripsTable} t ON b.trip_id = t.id
755 - WHERE b.status = 'confirmed'
772 + WHERE (b.status = 'confirmed' OR (b.status = 'pending' AND b.amount_paid > 0))
756 773 AND b.travel_date = %s
757 774 AND b.reminder_sent = 0",
758 775 $travelDate
759 776 ));
@@ -832,20 +849,44 @@
832 849 *
833 850 * @param string $expiryThreshold Datetime threshold
834 851 * @return array
835 852 */
836 - public function getExpiredPendingBookings(string $expiryThreshold): array
853 + /**
854 + * Unpaid bookings past the expiry threshold.
855 + *
856 + * @param string $expiryThreshold Bookings created before this are expired.
857 + * @param string $createdSince Activation floor: when set, bookings created
858 + * before it are never expired. Keeps a site
859 + * that switches the feature on from
860 + * retroactively cancelling (and emailing about)
861 + * its historical pending bookings.
862 + * @param int $limit Batch size. The sweep emails each customer,
863 + * so an unbounded run could try to send
864 + * hundreds of emails in one cron request and
865 + * time out half-way. It runs hourly, so a
866 + * backlog simply drains over the next runs.
867 + * @return array<int, object>
868 + */
869 + public function getExpiredPendingBookings(string $expiryThreshold, string $createdSince = '', int $limit = 200): array
837 870 {
838 871 $table = $this->getTableName();
839 872
840 - return $this->wpdb->get_results($this->wpdb->prepare(
841 - "SELECT id, reference, contact_email, contact_first_name, contact_last_name, trip_id
842 - FROM {$table}
843 - WHERE status = 'pending'
844 - AND payment_status = 'pending'
845 - AND created_at < %s",
846 - $expiryThreshold
847 - ));
873 + $sql = "SELECT id, reference, contact_email, contact_first_name, contact_last_name, trip_id
874 + FROM {$table}
875 + WHERE status = 'pending'
876 + AND payment_status = 'pending'
877 + AND created_at < %s";
878 + $params = [$expiryThreshold];
879 +
880 + if ($createdSince !== '') {
881 + $sql .= ' AND created_at >= %s';
882 + $params[] = $createdSince;
883 + }
884 +
885 + $sql .= ' ORDER BY created_at ASC LIMIT %d';
886 + $params[] = max(1, $limit);
887 +
888 + return $this->wpdb->get_results($this->wpdb->prepare($sql, $params));
848 889 }
849 890
850 891 /**
851 892 * Expire a booking