*/ private array $cancelled_for = []; /** * Constructor. * * @param ReminderRuleRepository $rules Rules. * @param ReminderScheduler $scheduler Offset calculator. * @param NotificationDispatcher $dispatcher Dispatcher. * @param NotificationLogRepository $logs Logs. * @param JobScheduler $jobs Job scheduler. * @param Clock $clock Clock. */ public function __construct( private readonly ReminderRuleRepository $rules, private readonly ReminderScheduler $scheduler, private readonly NotificationDispatcher $dispatcher, private readonly NotificationLogRepository $logs, private readonly JobScheduler $jobs, private readonly Clock $clock, ) {} /** * Schedule matching reminders for a booking. * * @param Booking $booking Booking. * * @since 0.1.0 */ public function schedule_for_booking( Booking $booking ): void { $now = $this->clock->now(); foreach ( $this->rules->all_enabled() as $rule ) { if ( ! $rule->matches( $booking->status()->value, $booking->service_id(), $booking->agent_id(), $booking->location_id() ) ) { continue; } $fire_at = $this->scheduler->fire_at( $booking->start_utc(), $rule->offset_minutes(), $now ); if ( null === $fire_at ) { continue; } $this->dispatcher->queue_template( $booking, $rule->template_key(), $rule->id(), $fire_at, $rule->channel() ); } } /** * Cancel pending reminders then re-schedule. * * @param Booking $booking Booking. * * @since 0.1.0 */ public function reschedule_for_booking( Booking $booking ): void { $this->cancel_for_booking( (int) $booking->id() ); $this->schedule_for_booking( $booking ); } /** * Cancel pending reminders for a booking. * * @param int $booking_id Booking id. * * @since 0.1.0 */ public function cancel_for_booking( int $booking_id ): void { $this->cancelled_for[] = $booking_id; $cancelled = $this->logs->cancel_pending_for_booking( $booking_id ); foreach ( $cancelled as $entry ) { if ( null !== $entry->action_scheduler_id() ) { $this->jobs->cancel( NotificationDispatcher::SEND_HOOK, [ 'log_id' => (int) $entry->id() ], 'bookline' ); } } } /** * Booking ids touched by cancel_for_booking (stub parity). * * @return list * * @since 0.1.0 */ public function cancelled_booking_ids(): array { return $this->cancelled_for; } /** * Whether reminders were cancelled for a booking (stub parity). * * @param int $booking_id Booking id. * * @since 0.1.0 */ public function was_cancelled_for( int $booking_id ): bool { return in_array( $booking_id, $this->cancelled_for, true ); } }