on_booking_created( $event ); return; } if ( $event instanceof BookingRescheduled ) { $this->on_booking_rescheduled( $event ); return; } if ( $event instanceof BookingCancelled ) { $this->on_booking_cancelled( $event ); return; } if ( $event instanceof BookingStatusChanged ) { $this->on_booking_status( $event ); return; } if ( $event instanceof ReviewRequested ) { $this->on_review_requested( $event ); return; } if ( $event instanceof IntentAbandoned ) { $this->on_intent_abandoned( $event ); return; } if ( $event instanceof IntentRecovered ) { $this->on_intent_recovered( $event ); return; } if ( $event instanceof CustomerCreated ) { $this->on_customer_created( $event ); } } /** * Booking created. * * @param BookingCreated $event Event. */ private function on_booking_created( BookingCreated $event ): void { $booking = $this->bookings->find_by_id( $event->booking_id ); if ( null === $booking ) { return; } $customer = $this->customers->find_by_id( $booking->customer_id() ); $this->cancel->handle( 'booking.created', SubjectType::Booking, $event->booking_id, $booking->customer_id() ); $ctx = $this->factory->for_booking( 'booking.created', 'booking:' . $event->booking_id . ':created', $booking, $customer ); $this->matcher->handle( $ctx ); if ( in_array( $booking->status(), [ BookingStatus::Confirmed, BookingStatus::Approved ], true ) ) { $confirmed = $this->factory->for_booking( 'booking.confirmed', 'booking:' . $event->booking_id . ':confirmed', $booking, $customer ); $this->matcher->handle( $confirmed ); } $this->relative->schedule_for_booking( $booking ); } /** * Booking rescheduled. * * @param BookingRescheduled $event Event. */ private function on_booking_rescheduled( BookingRescheduled $event ): void { $booking = $this->bookings->find_by_id( $event->booking_id ); if ( null === $booking ) { return; } $customer = $this->customers->find_by_id( $booking->customer_id() ); $this->cancel->handle( 'booking.rescheduled', SubjectType::Booking, $event->booking_id, $booking->customer_id() ); $ctx = $this->factory->for_booking( 'booking.rescheduled', 'booking:' . $event->booking_id . ':rescheduled:' . $event->occurred_at->format( 'YmdHis' ), $booking, $customer ); $this->matcher->handle( $ctx ); $this->relative->schedule_for_booking( $booking ); } /** * Booking cancelled. * * @param BookingCancelled $event Event. */ private function on_booking_cancelled( BookingCancelled $event ): void { $booking = $this->bookings->find_by_id( $event->booking_id ); $cid = $booking instanceof \Bookline\Domain\Booking\Booking ? $booking->customer_id() : null; $this->cancel->handle( 'booking.cancelled', SubjectType::Booking, $event->booking_id, $cid ); $this->relative->cancel_for_booking( $event->booking_id ); if ( null === $booking ) { return; } $customer = $this->customers->find_by_id( $booking->customer_id() ); $ctx = $this->factory->for_booking( 'booking.cancelled', 'booking:' . $event->booking_id . ':cancelled', $booking, $customer ); $this->matcher->handle( $ctx ); } /** * Status changed → confirmed / completed / no_show. * * @param BookingStatusChanged $event Event. */ private function on_booking_status( BookingStatusChanged $event ): void { $name = match ( $event->to ) { BookingStatus::Confirmed => 'booking.confirmed', BookingStatus::Completed => 'booking.completed', BookingStatus::NoShow => 'booking.no_show', default => null, }; if ( null === $name ) { return; } $booking = $this->bookings->find_by_id( $event->booking_id ); if ( null === $booking ) { return; } $this->cancel->handle( $name, SubjectType::Booking, $event->booking_id, $booking->customer_id() ); $customer = $this->customers->find_by_id( $booking->customer_id() ); $ctx = $this->factory->for_booking( $name, 'booking:' . $event->booking_id . ':' . $event->to->value . ':' . $event->occurred_at->format( 'YmdHis' ), $booking, $customer ); $this->matcher->handle( $ctx ); } /** * Review requested. * * @param ReviewRequested $event Event. */ private function on_review_requested( ReviewRequested $event ): void { $booking = $this->bookings->find_by_id( $event->booking_id ); if ( null === $booking ) { return; } $customer = $this->customers->find_by_id( $booking->customer_id() ); $ctx = $this->factory->for_booking( 'review.requested', 'booking:' . $event->booking_id . ':review', $booking, $customer ); $this->matcher->handle( $ctx ); } /** * Intent abandoned. * * @param IntentAbandoned $event Event. */ private function on_intent_abandoned( IntentAbandoned $event ): void { $intent = $this->intents->find_by_id( $event->intent_id ); if ( null === $intent ) { return; } $this->cancel->handle( 'intent.abandoned', SubjectType::Intent, $event->intent_id, $event->customer_id ); $ctx = $this->factory->for_intent( 'intent.abandoned', 'intent:' . $event->intent_id . ':abandoned', $intent ); $this->matcher->handle( $ctx ); $this->relative->schedule_for_intent( $intent ); } /** * Intent recovered. * * @param IntentRecovered $event Event. */ private function on_intent_recovered( IntentRecovered $event ): void { $this->cancel->handle( 'intent.recovered', SubjectType::Intent, $event->intent_id, $event->customer_id ); $intent = $this->intents->find_by_id( $event->intent_id ); if ( null === $intent ) { return; } $ctx = $this->factory->for_intent( 'intent.recovered', 'intent:' . $event->intent_id . ':recovered', $intent ); $this->matcher->handle( $ctx ); } /** * Customer created. * * @param CustomerCreated $event Event. */ private function on_customer_created( CustomerCreated $event ): void { $customer = $this->customers->find_by_id( $event->customer_id ); if ( null === $customer ) { return; } $ctx = $this->factory->for_customer( 'customer.created', 'customer:' . $event->customer_id . ':created', $customer ); $this->matcher->handle( $ctx ); } }