You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.2 KiB

1 month ago
<?php
namespace App\Services;
use App\Models\Reservation;
use Carbon\Carbon;
3 weeks ago
use Illuminate\Support\Collection;
1 month ago
class ReservationExpiryService
{
/**
2 weeks ago
* 将「活动日/入馆日历日已过当日 23:59:59、仍为待核销、未核销」的预约标记为 expired。
* 均以应用时区的**日历日**为准:活动日当天(含整日至 23:59:59仍可待核销自**次日 0:00** 起视为已过活动日。
* - 普通活动:以 activity_days.activity_date 对应日历日为准(不再按场次 session_end_at 提前过期)。
* - 抢票:以 entry_date 对应日历日为准。
1 month ago
*/
public function expireStalePendingReservations(): int
{
$tz = (string) config('app.timezone');
$today = Carbon::now($tz)->toDateString();
2 weeks ago
$ids = $this->stalePendingReservationIds($today);
1 month ago
if ($ids->isEmpty()) {
return 0;
}
return Reservation::query()->whereIn('id', $ids)->update([
'status' => 'expired',
'updated_at' => now(),
]);
}
3 weeks ago
/**
* @return Collection<int, int>
*/
2 weeks ago
private function stalePendingReservationIds(string $today): Collection
3 weeks ago
{
$idsActivity = Reservation::query()
->join('activity_days', 'activity_days.id', '=', 'reservations.activity_day_id')
->where('reservations.status', 'pending')
->whereNull('reservations.verified_at')
->whereNotNull('reservations.activity_day_id')
2 weeks ago
->whereDate('activity_days.activity_date', '<', $today)
3 weeks ago
->where(function ($q) {
$q->whereNull('reservations.reservation_kind')
->orWhere('reservations.reservation_kind', Reservation::KIND_ACTIVITY);
})
->pluck('reservations.id');
$idsTicketGrab = Reservation::query()
->where('reservation_kind', Reservation::KIND_TICKET_GRAB)
->where('status', 'pending')
->whereNull('verified_at')
->whereNotNull('entry_date')
->whereDate('entry_date', '<', $today)
->pluck('id');
return $idsActivity->merge($idsTicketGrab)->unique()->values();
}
1 month ago
}