PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.5
Yatra – Travel Booking & Tour Operator Software v3.0.5
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
yatra / app / Services / WaitlistService.php

WaitlistService.php in Yatra – Travel Booking & Tour Operator Software 3.0.5, at app/Services/WaitlistService.php

128 lines 3.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Services;
6
7 use Yatra\Repositories\AvailabilityRepository;
8 use Yatra\Repositories\BookingRepository;
9
10 /**
11 * Global + per-trip waitlist rules for checkout (free + Pro via filters).
12 */
13 final class WaitlistService
14 {
15 /**
16 * Site-wide waitlist toggle (Settings → Booking).
17 */
18 public static function isGloballyEnabled(): bool
19 {
20 return SettingsService::isEnabled('allow_waitlist');
21 }
22
23 /**
24 * Global toggle plus filters (Pro or custom code may require per-trip flags).
25 *
26 * @param object $trip Trip model from repository
27 */
28 public static function isAllowedForTrip(object $trip): bool
29 {
30 if (!self::isGloballyEnabled()) {
31 return false;
32 }
33
34 return (bool) apply_filters('yatra_trip_allows_waitlist', true, $trip);
35 }
36
37 /**
38 * True when this availability row cannot fit the party but waitlist may be offered.
39 *
40 * @param object|null $availability Resolved availability model or null (no strict cap)
41 */
42 public static function isInsufficientSeats(?object $availability, int $travelersCount): bool
43 {
44 if ($availability === null || $travelersCount < 1) {
45 return false;
46 }
47
48 $available = (int) ($availability->seats_available ?? 0);
49
50 return $available < $travelersCount;
51 }
52
53 /**
54 * Optional per-trip max waitlist travelers (same departure) — 0 or null = unlimited.
55 */
56 public static function hasWaitlistCapacity(object $trip, int $availabilityId, int $additionalTravelers): bool
57 {
58 $cap = isset($trip->waitlist_capacity) ? (int) $trip->waitlist_capacity : 0;
59 if ($cap <= 0) {
60 return true;
61 }
62
63 $repo = new BookingRepository();
64 $current = $repo->getTotalWaitlistTravelersForAvailability($availabilityId);
65
66 return ($current + $additionalTravelers) <= $cap;
67 }
68
69 /**
70 * Persist waitlist counter on the availability row (display / admin).
71 */
72 public static function incrementAvailabilityWaitlistCount(int $availabilityId, int $travelers): void
73 {
74 if ($availabilityId <= 0 || $travelers < 1) {
75 return;
76 }
77
78 $repo = new AvailabilityRepository();
79 $repo->incrementSeatsWaitlist($availabilityId, $travelers);
80 }
81
82 /**
83 * Decrement seats_waitlist when a waitlisted booking is removed (cancel, refund, delete).
84 *
85 * @param object $booking Row as returned by BookingRepository::find (must reflect waitlist state).
86 */
87 public static function releaseWaitlistHolding(object $booking): void
88 {
89 if (($booking->status ?? '') !== 'waitlist') {
90 return;
91 }
92
93 $availabilityId = (int) ($booking->availability_id ?? 0);
94 $travelers = max(1, (int) ($booking->travelers_count ?? 1));
95
96 if ($availabilityId <= 0) {
97 return;
98 }
99
100 $repo = new AvailabilityRepository();
101 $repo->incrementSeatsWaitlist($availabilityId, -$travelers);
102 }
103
104 /**
105 * @param object|null $availability
106 */
107 public static function canJoinWaitlist(object $trip, $availability, int $travelersCount): bool
108 {
109 if (!self::isAllowedForTrip($trip)) {
110 return false;
111 }
112
113 if ($availability === null) {
114 return false;
115 }
116
117 if (!self::isInsufficientSeats($availability, $travelersCount)) {
118 return false;
119 }
120
121 if (!self::hasWaitlistCapacity($trip, (int) $availability->id, $travelersCount)) {
122 return false;
123 }
124
125 return (bool) apply_filters('yatra_can_join_waitlist', true, $trip, $availability, $travelersCount);
126 }
127 }
128