/**
  * Checks booking data is correctly set, and that the chosen blocks are indeed available.
  *
  * @param  array $data
  * @return WP_Error on failure, true on success
  */
 public function is_bookable($data)
 {
     // Validate resources are set
     if ($this->product->has_resources() && $this->product->is_resource_assignment_type('customer')) {
         if (empty($data['_resource_id'])) {
             return new WP_Error('Error', __('Please choose a resource type', 'woocommerce-bookings'));
         }
     } elseif ($this->product->has_resources() && $this->product->is_resource_assignment_type('automatic')) {
         $data['_resource_id'] = 0;
     } else {
         $data['_resource_id'] = '';
     }
     // Validate customer set durations
     if ($this->product->is_duration_type('customer')) {
         if (empty($data['_duration'])) {
             return new WP_Error('Error', __('Duration is required - please enter a duration greater than zero above', 'woocommerce-bookings'));
         }
         if ($data['_duration'] > $this->product->get_max_duration()) {
             return new WP_Error('Error', sprintf(__('The maximum duration is %d', 'woocommerce-bookings'), $this->product->wc_booking_max_duration));
         }
         if ($data['_duration'] < $this->product->get_min_duration()) {
             return new WP_Error('Error', sprintf(__('The minimum duration is %d', 'woocommerce-bookings'), $this->product->wc_booking_min_duration));
         }
     }
     // Validate date and time
     if (empty($data['date'])) {
         return new WP_Error('Error', __('Date is required - please choose one above', 'woocommerce-bookings'));
     }
     if (in_array($this->product->get_duration_unit(), array('minute', 'hour')) && empty($data['time'])) {
         return new WP_Error('Error', __('Time is required - please choose one above', 'woocommerce-bookings'));
     }
     if ($data['_date'] && date('Ymd', strtotime($data['_date'])) < date('Ymd', current_time('timestamp'))) {
         return new WP_Error('Error', __('You must choose a future date and time.', 'woocommerce-bookings'));
     }
     if ($data['_date'] && !empty($data['_time']) && date('YmdHi', strtotime($data['_date'] . ' ' . $data['_time'])) < date('YmdHi', current_time('timestamp'))) {
         return new WP_Error('Error', __('You must choose a future date and time.', 'woocommerce-bookings'));
     }
     // Validate min date and max date
     if (in_array($this->product->get_duration_unit(), array('minute', 'hour'))) {
         $now = current_time('timestamp');
     } elseif ('month' === $this->product->get_duration_unit()) {
         $now = strtotime('midnight first day of this month', current_time('timestamp'));
     } else {
         $now = strtotime('midnight', current_time('timestamp'));
     }
     if ($min = $this->product->get_min_date()) {
         $min_date = $this->product->get_min_timestamp_for_date(strtotime($data['date']));
         if (strtotime($data['_date'] . ' ' . $data['_time']) < $min_date) {
             return new WP_Error('Error', sprintf(__('The earliest booking possible is currently %s.', 'woocommerce-bookings'), date_i18n(wc_date_format() . ' ' . get_option('time_format'), $min_date)));
         }
     }
     if ($max = $this->product->get_max_date()) {
         $max_date = strtotime("+{$max['value']} {$max['unit']}", $now);
         if (strtotime($data['_date'] . ' ' . $data['_time']) > $max_date) {
             return new WP_Error('Error', sprintf(__('The latest booking possible is currently %s.', 'woocommerce-bookings'), date_i18n(wc_date_format() . ' ' . get_option('time_format'), $max_date)));
         }
     }
     // Validate persons
     if ($this->product->has_persons()) {
         $persons = array_sum($data['_persons']);
         if (empty($persons)) {
             return new WP_Error('Error', __('Persons are required - please enter the number of persons above', 'woocommerce-bookings'));
         }
         if ($this->product->get_max_persons() && $persons > $this->product->get_max_persons()) {
             return new WP_Error('Error', sprintf(__('The maximum persons per group is %d', 'woocommerce-bookings'), $this->product->wc_booking_max_persons_group));
         }
         if ($persons < $this->product->get_min_persons()) {
             return new WP_Error('Error', sprintf(__('The minimum persons per group is %d', 'woocommerce-bookings'), $this->product->wc_booking_min_persons_group));
         }
         if ($this->product->has_person_types()) {
             $person_types = $this->product->get_person_types();
             foreach ($person_types as $person) {
                 $person_max = get_post_meta($person->ID, 'max', true);
                 if (is_numeric($person_max) && isset($data['_persons'][$person->ID]) && $data['_persons'][$person->ID] > $person_max) {
                     return new WP_Error('Error', sprintf(__('The maximum %s per group is %d', 'woocommerce-bookings'), $person->post_title, $person_max));
                 }
                 $person_min = get_post_meta($person->ID, 'min', true);
                 if (is_numeric($person_min) && isset($data['_persons'][$person->ID]) && $data['_persons'][$person->ID] < $person_min) {
                     return new WP_Error('Error', sprintf(__('The minimum %s per group is %d', 'woocommerce-bookings'), $person->post_title, $person_min));
                 }
             }
         }
     }
     // Get availability for the dates
     $available_bookings = $this->product->get_available_bookings($data['_start_date'], $data['_end_date'], $data['_resource_id'], $data['_qty']);
     if (is_array($available_bookings)) {
         $this->auto_assigned_resource_id = current(array_keys($available_bookings));
     }
     if (is_wp_error($available_bookings)) {
         return $available_bookings;
     } elseif (!$available_bookings) {
         return new WP_Error('Error', __('Sorry, the selected block is not available', 'woocommerce-bookings'));
     }
     return true;
 }