| @@ -189,11 +189,20 @@ | ||
| 189 | 189 | if (!$departure) { |
| 190 | 190 | return; |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | + // booked_count is sourced from the actual bookings table — it | |
| 194 | + // is the truth. Reflect it to the departure row WITHOUT | |
| 195 | + // clamping to max_capacity. Clamping previously hid oversells | |
| 196 | + // from operators: if direct + OTA bookings legitimately | |
| 197 | + // exceeded capacity (always an OTA-side acceptance — Yatra's | |
| 198 | + // direct checkout enforces capacity), the departure showed | |
| 199 | + // "full" instead of "oversold by N", and operators had no way | |
| 200 | + // to spot the situation needing reconciliation. Allowing the | |
| 201 | + // overshow makes the problem visible so it can be addressed. | |
| 193 | 202 | $updated = [ |
| 194 | 203 | 'max_capacity' => $seatsTotal, |
| 195 | - 'booked_count' => min($seatsTotal, max(0, $bookedCount)), | |
| 204 | + 'booked_count' => max(0, $bookedCount), | |
| 196 | 205 | ]; |
| 197 | 206 | |
| 198 | 207 | $departureRepo->update((int) $departure->id, $updated); |
| 199 | 208 | } |
| @@ -230,9 +239,9 @@ | ||
| 230 | 239 | $date = $departure->start_date ?: $departure->date; |
| 231 | 240 | |
| 232 | 241 | // Get capacity from availability |
| 233 | 242 | $capacityService = new CapacityService(); |
| 234 | - $correctCapacity = $capacityService->getCapacityForDate($departure->trip_id, $date); | |
| 243 | + $correctCapacity = $capacityService->getCapacityForDate($departure->trip_id, $date, $departure->time ?? null); | |
| 235 | 244 | |
| 236 | 245 | if ($correctCapacity > 0 && $departure->max_capacity !== $correctCapacity) { |
| 237 | 246 | // Remove hook temporarily to prevent infinite loop |
| 238 | 247 | remove_action('yatra_departure_saved', [self::class, 'onDepartureSave'], 10); |
| @@ -249,9 +258,9 @@ | ||
| 249 | 258 | unset($processing[$departureId]); |
| 250 | 259 | } |
| 251 | 260 | |
| 252 | 261 | /** |
| 253 | - * Infer yatra_new_trip_availability_dates.id when the booking row missed availability_id | |
| 262 | + * Infer yatra_trip_availability_dates.id when the booking row missed availability_id | |
| 254 | 263 | * (common when checkout omits it). Uses booking→departure time to disambiguate multiple slots per day. |
| 255 | 264 | */ |
| 256 | 265 | private static function resolveAvailabilityIdForBooking(int $bookingId, int $tripId, string $travelDate): int |
| 257 | 266 | { |