getInputs(); $id = (int) ( $inputs['booking_id'] ?? 0 ); $reason = trim( (string) ( $inputs['cancel_reason'] ?? '' ) ); $descriptor = $this->describe_booking( $id ); $summary = '' !== $descriptor ? "Cancel booking #{$id} — {$descriptor}" : "Cancel booking #{$id}"; if ( '' !== $reason ) { $summary .= " (reason: {$reason})"; } return $summary; } public function get_approval_inputs(): array { $inputs = $this->getInputs(); $descriptor = $this->describe_booking( (int) ( $inputs['booking_id'] ?? 0 ) ); if ( '' !== $descriptor ) { $inputs['booking'] = $descriptor; } return $inputs; } public function __invoke( int $booking_id, ?string $cancel_reason = null ): array { $check = $this->guard_admin(); if ( $check ) { return $check; } if ( $booking_id <= 0 ) { return [ 'error' => 'A valid booking_id is required.' ]; } $state = $this->load_booking_state( $booking_id ); if ( null === $state ) { return [ 'error' => "Booking #{$booking_id} was not found." ]; } if ( 'cancel' === $state['status'] ) { return [ 'error' => "Booking #{$booking_id} is already cancelled." ]; } try { // Resend the full record with only the status flipped to cancelled. $body = $state; $body['status'] = 'cancel'; if ( null !== $cancel_reason && '' !== trim( $cancel_reason ) ) { $body['cancel_reason'] = sanitize_text_field( $cancel_reason ); } $request = $this->build_request( 'PUT', '/timetics/v1/bookings/' . $booking_id, [], $body, [ 'booking_id' => $booking_id ] ); if ( is_array( $request ) ) { return $request; } $controller = \Timetics\Core\Bookings\Api_Booking::instance(); $data = $this->extract_response( $controller->update_item( $request ), "Failed to cancel booking #{$booking_id}." ); if ( isset( $data['error'] ) ) { return $data; } return [ 'success' => true, 'booking_id' => $booking_id, 'message' => "Booking #{$booking_id} cancelled successfully.", ]; } catch ( \Throwable $e ) { Log::error( 'Timetics_Cancel_Booking_Tool error', [ 'error' => $e->getMessage() ] ); return [ 'error' => 'Failed to cancel booking: ' . $e->getMessage() ]; } } }