created_at(); $start = $booking->start_utc(); $lead = (int) max( 0, ( $start->getTimestamp() - $created->getTimestamp() ) / 60 ); $zone = new DateTimeZone( $booking->timezone()->to_string() ); $local = $start->setTimezone( $zone ); $fields = [ 'service_id' => $booking->service_id(), 'agent_id' => $booking->agent_id() ?? 0, 'location_id' => $booking->location_id() ?? 0, 'booking_status' => $booking->status()->value, 'price_minor' => $booking->price()->amount_minor(), 'marketing_consent' => $customer instanceof Customer ? $customer->marketing_consent() : false, 'lead_time_minutes' => $lead, 'has_coupon' => false, 'payment_status' => '', 'day_of_week' => (int) $local->format( 'N' ), 'time_of_day_minutes' => ( (int) $local->format( 'G' ) * 60 ) + (int) $local->format( 'i' ), 'is_new_customer' => false, 'booking_count' => 0, 'no_show_count' => 0, 'details_step_reached' => false, ]; $ctx = new AutomationContext( $event_id, $event, SubjectType::Booking, (int) $booking->id(), $booking->customer_id(), $this->clock->now(), $fields, 0, [], $is_test ); unset( $fields ); return $ctx; } /** * Context for a customer subject. * * @param string $event Event. * @param string $event_id Delivery id. * @param Customer $customer Customer. * @param bool $is_test Test run. * * @since 0.1.0 */ public function for_customer( string $event, string $event_id, Customer $customer, bool $is_test = false ): AutomationContext { return new AutomationContext( $event_id, $event, SubjectType::Customer, (int) $customer->id(), $customer->id(), $this->clock->now(), [ 'marketing_consent' => $customer->marketing_consent(), 'is_new_customer' => true, 'booking_count' => 0, 'no_show_count' => 0, 'details_step_reached' => false, 'service_id' => 0, 'agent_id' => 0, 'price_minor' => 0, ], 0, [], $is_test ); } /** * Context for an order intent. * * @param string $event Event. * @param string $event_id Delivery id. * @param OrderIntent $intent Intent. * @param bool $is_test Test run. * * @since 0.1.0 */ public function for_intent( string $event, string $event_id, OrderIntent $intent, bool $is_test = false ): AutomationContext { $completed = $intent->completed_steps() ?? []; $details = in_array( 'details', $completed, true ) || 'details' === $intent->current_step(); $draft = $intent->customer_draft() ?? []; $consent = isset( $draft['marketing_consent'] ) && true === $draft['marketing_consent']; $totals = $intent->totals() ?? []; $service = isset( $totals['service_id'] ) ? (int) $totals['service_id'] : 0; $price = isset( $totals['total_minor'] ) ? (int) $totals['total_minor'] : 0; return new AutomationContext( $event_id, $event, SubjectType::Intent, (int) $intent->id(), null, $this->clock->now(), [ 'service_id' => $service, 'agent_id' => isset( $totals['agent_id'] ) ? (int) $totals['agent_id'] : 0, 'location_id' => isset( $totals['location_id'] ) ? (int) $totals['location_id'] : 0, 'price_minor' => $price, 'marketing_consent' => $consent, 'details_step_reached' => $details, 'has_coupon' => null !== $intent->coupon_code() && '' !== $intent->coupon_code(), 'lead_time_minutes' => 0, ], 0, [], $is_test ); } /** * Whether a booking is void for fresh-context execution. * * @param Booking $booking Booking. * * @since 0.1.0 */ public function booking_is_void( Booking $booking ): bool { if ( null !== $booking->deleted_at() ) { return true; } return in_array( $booking->status(), [ BookingStatus::Cancelled, BookingStatus::Rescheduled ], true ); } }