/** * Add posted data to the cart item * * @param mixed $cart_item_meta * @param mixed $product_id * @return void */ public function add_cart_item_data($cart_item_meta, $product_id) { $product = get_product($product_id); if ('booking' !== $product->product_type) { return $cart_item_meta; } $booking_form = new WC_Booking_Form($product); $cart_item_meta['booking'] = $booking_form->get_posted_data($_POST); $cart_item_meta['booking']['_cost'] = $booking_form->calculate_booking_cost($_POST); // Create the new booking $new_booking = $this->create_booking_from_cart_data($cart_item_meta, $product_id); // Store in cart $cart_item_meta['booking']['_booking_id'] = $new_booking->id; // Schedule this item to be removed from the cart if the user is inactive $this->schedule_cart_removal($new_booking->id); return $cart_item_meta; }
/** * Calculate costs * * Take posted booking form values and then use these to quote a price for what has been chosen. * Returns a string which is appended to the booking form. */ public function calculate_costs() { $posted = array(); parse_str($_POST['form'], $posted); $booking_id = $posted['add-to-cart']; $product = get_product($booking_id); if (!$product) { die(json_encode(array('result' => 'ERROR', 'html' => '<span class="booking-error">' . __('This booking is unavailable.', 'woocommerce-bookings') . '</span>'))); } $booking_form = new WC_Booking_Form($product); $cost = $booking_form->calculate_booking_cost($posted); if (is_wp_error($cost)) { die(json_encode(array('result' => 'ERROR', 'html' => '<span class="booking-error">' . $cost->get_error_message() . '</span>'))); } $tax_display_mode = get_option('woocommerce_tax_display_shop'); $display_price = $tax_display_mode == 'incl' ? $product->get_price_including_tax(1, $cost) : $product->get_price_excluding_tax(1, $cost); die(json_encode(array('result' => 'SUCCESS', 'html' => __('Booking cost', 'woocommerce-bookings') . ': <strong>' . woocommerce_price($display_price) . $product->get_price_suffix() . '</strong>'))); }
/** * Output the form */ public function output() { $this->errors = array(); $step = 1; try { if (!empty($_POST) && !check_admin_referer('create_booking_notification')) { throw new Exception(__('Error - please try again', 'woocommerce-bookings')); } if (!empty($_POST['create_booking'])) { $customer_id = absint($_POST['customer_id']); $bookable_product_id = absint($_POST['bookable_product_id']); $booking_order = wc_clean($_POST['booking_order']); if (!$bookable_product_id) { throw new Exception(__('Please choose a bookable product', 'woocommerce-bookings')); } if ($booking_order === 'existing') { $order_id = absint($_POST['booking_order_id']); $booking_order = $order_id; if (!$booking_order || get_post_type($booking_order) !== 'shop_order') { throw new Exception(__('Invalid order ID provided', 'woocommerce-bookings')); } } $step++; $product = get_product($bookable_product_id); $booking_form = new WC_Booking_Form($product); } elseif (!empty($_POST['create_booking_2'])) { $customer_id = absint($_POST['customer_id']); $bookable_product_id = absint($_POST['bookable_product_id']); $booking_order = wc_clean($_POST['booking_order']); $product = get_product($bookable_product_id); $booking_form = new WC_Booking_Form($product); $booking_data = $booking_form->get_posted_data($_POST); $booking_cost = ($cost = $booking_form->calculate_booking_cost($_POST)) && !is_wp_error($cost) ? number_format($cost, 2, '.', '') : 0; $create_order = false; if ('yes' === get_option('woocommerce_prices_include_tax')) { if (version_compare(WOOCOMMERCE_VERSION, '2.3', '<')) { $base_tax_rates = WC_Tax::get_shop_base_rate($product->tax_class); } else { $base_tax_rates = WC_Tax::get_base_tax_rates($product->tax_class); } $base_taxes = WC_Tax::calc_tax($booking_cost, $base_tax_rates, true); $booking_cost = round($booking_cost - array_sum($base_taxes), absint(get_option('woocommerce_price_num_decimals'))); } // Data to go into the booking $new_booking_data = array('user_id' => $customer_id, 'product_id' => $product->id, 'resource_id' => isset($booking_data['_resource_id']) ? $booking_data['_resource_id'] : '', 'persons' => $booking_data['_persons'], 'cost' => $booking_cost, 'start_date' => $booking_data['_start_date'], 'end_date' => $booking_data['_end_date'], 'all_day' => $booking_data['_all_day'] ? 1 : 0); // Create order if ($booking_order === 'new') { $create_order = true; $order_id = $this->create_order($booking_cost, $customer_id); if (!$order_id) { throw new Exception(__('Error: Could not create order', 'woocommerce-bookings')); } } elseif ($booking_order > 0) { $order_id = absint($booking_order); if (!$order_id || get_post_type($order_id) !== 'shop_order') { throw new Exception(__('Invalid order ID provided', 'woocommerce-bookings')); } $order = new WC_Order($order_id); update_post_meta($order_id, '_order_total', $order->get_total() + $booking_cost); update_post_meta($order_id, '_booking_order', '1'); } else { $order_id = 0; } if ($order_id) { $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $product->get_title(), 'order_item_type' => 'line_item')); if (!$item_id) { throw new Exception(__('Error: Could not create item', 'woocommerce-bookings')); } // Add line item meta woocommerce_add_order_item_meta($item_id, '_qty', 1); woocommerce_add_order_item_meta($item_id, '_tax_class', $product->get_tax_class()); woocommerce_add_order_item_meta($item_id, '_product_id', $product->id); woocommerce_add_order_item_meta($item_id, '_variation_id', ''); woocommerce_add_order_item_meta($item_id, '_line_subtotal', $booking_cost); woocommerce_add_order_item_meta($item_id, '_line_total', $booking_cost); woocommerce_add_order_item_meta($item_id, '_line_tax', 0); woocommerce_add_order_item_meta($item_id, '_line_subtotal_tax', 0); // We have an item id $new_booking_data['order_item_id'] = $item_id; // Add line item data foreach ($booking_data as $key => $value) { if (strpos($key, '_') !== 0) { woocommerce_add_order_item_meta($item_id, get_wc_booking_data_label($key, $product), $value); } } } // Create the booking itself $new_booking = get_wc_booking($new_booking_data); $new_booking->create($create_order ? 'unpaid' : 'pending-confirmation'); wp_safe_redirect(admin_url('post.php?post=' . ($create_order ? $order_id : $new_booking->id) . '&action=edit')); exit; } } catch (Exception $e) { $this->errors[] = $e->getMessage(); } switch ($step) { case 1: include 'views/html-create-booking-page.php'; break; case 2: include 'views/html-create-booking-page-2.php'; break; } }
/** * Get all available booking products * * @param string $start_date YYYY-MM-DD format * @param string $end_date YYYY-MM-DD format * @param int $quantity Number of people to book * @return array Available post IDs */ function get_available_bookings($start_date, $end_date, $quantity = 1) { $matches = array(); $start_date = explode(' ', $start_date); $end_date = explode(' ', $end_date); $start = explode('-', $start_date[0]); $end = explode('-', $end_date[0]); $args = array('wc_bookings_field_persons' => $quantity, 'wc_bookings_field_duration' => 1, 'wc_bookings_field_start_date_year' => $start[0], 'wc_bookings_field_start_date_month' => $start[1], 'wc_bookings_field_start_date_day' => $start[2], 'wc_bookings_field_start_date_to_year' => $end[0], 'wc_bookings_field_start_date_to_month' => $end[1], 'wc_bookings_field_start_date_to_day' => $end[2]); // Loop through all posts foreach ($this->product_ids as $post_id) { if ('product' == get_post_type($post_id)) { $product = wc_get_product($post_id); if (is_wc_booking_product($product)) { // Support time if ('hour' == $product->get_duration_unit()) { if (!empty($start_date[1])) { $args['wc_bookings_field_start_date_time'] = $start_date[1]; } } // Support WooCommerce Accomodation Bookings plugin // @src woocommerce-bookings/includes/booking-form/class-wc-booking-form.php $unit = 'accommodation-booking' == $product->product_type ? 'night' : 'day'; $duration = $this->calculate_duration($start_date[0], $end_date[0], $unit); $args['wc_bookings_field_duration'] = $duration; $booking_form = new WC_Booking_Form($product); $posted_data = $booking_form->get_posted_data($args); // Returns WP_Error on fail if (true === $booking_form->is_bookable($posted_data)) { $matches[] = $post_id; } } } } return $matches; }
/** * Add posted data to the cart item * * @access public * @param mixed $cart_item_meta * @param mixed $product_id * @return void */ public function add_cart_item_data($cart_item_meta, $product_id) { $product = get_product($product_id); if ('booking' !== $product->product_type) { return $cart_item_meta; } $booking_form = new WC_Booking_Form($product); $cart_item_meta['booking'] = $booking_form->get_posted_data($_POST); $cart_item_meta['booking']['_cost'] = $booking_form->calculate_booking_cost($_POST); return $cart_item_meta; }
/** * Output the form */ public function output() { global $woocommerce; $this->errors = array(); $step = 1; try { if (!empty($_POST) && !check_admin_referer('create_booking_notification')) { throw new Exception(__('Error - please try again', 'woocommerce-bookings')); } if (!empty($_POST['create_booking'])) { $customer_id = absint($_POST['customer_id']); $bookable_product_id = absint($_POST['bookable_product_id']); $create_order = isset($_POST['create_order']) ? 1 : 0; if (!$bookable_product_id) { throw new Exception(__('Please choose a bookable product', 'woocommerce-bookings')); } $step++; $product = get_product($bookable_product_id); $booking_form = new WC_Booking_Form($product); } elseif (!empty($_POST['create_booking_2'])) { $customer_id = absint($_POST['customer_id']); $bookable_product_id = absint($_POST['bookable_product_id']); $create_order = absint($_POST['create_order']); $product = get_product($bookable_product_id); $booking_form = new WC_Booking_Form($product); $booking_data = $booking_form->get_posted_data($_POST); $booking_cost = number_format($booking_form->calculate_booking_cost($_POST), 2, '.', ''); // Data to go into the booking $new_booking_data = array('product_id' => $product->id, 'resource_id' => isset($booking_data['_resource_id']) ? $booking_data['_resource_id'] : '', 'persons' => $booking_data['_persons'], 'cost' => $booking_cost, 'start_date' => $booking_data['_start_date'], 'end_date' => $booking_data['_end_date'], 'all_day' => $booking_data['_all_day'] ? 1 : 0); // Create order if ($create_order) { $order_id = $this->create_order($booking_cost, $customer_id); if (!$order_id) { throw new Exception(__('Error: Could not create order', 'woocommerce-bookings')); } $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $product->get_title(), 'order_item_type' => 'line_item')); if (!$item_id) { throw new Exception(__('Error: Could not create item', 'woocommerce-bookings')); } // Add line item meta woocommerce_add_order_item_meta($item_id, '_qty', 1); woocommerce_add_order_item_meta($item_id, '_tax_class', $product->get_tax_class()); woocommerce_add_order_item_meta($item_id, '_product_id', $product->id); woocommerce_add_order_item_meta($item_id, '_variation_id', ''); woocommerce_add_order_item_meta($item_id, '_line_subtotal', $booking_cost); woocommerce_add_order_item_meta($item_id, '_line_total', $booking_cost); woocommerce_add_order_item_meta($item_id, '_line_tax', 0); woocommerce_add_order_item_meta($item_id, '_line_subtotal_tax', 0); // We have an item id $new_booking_data['order_item_id'] = $item_id; // Add line item data foreach ($booking_data as $key => $value) { if (strpos($key, '_') !== 0) { woocommerce_add_order_item_meta($item_id, get_wc_booking_data_label($key, $product), $value); } } } // Create the booking itself $new_booking = get_wc_booking($new_booking_data); $new_booking->create($create_order ? 'unpaid' : 'pending'); wp_safe_redirect(admin_url('post.php?post=' . ($create_order ? $order_id : $new_booking->id) . '&action=edit')); exit; } } catch (Exception $e) { $this->errors[] = $e->getMessage(); } switch ($step) { case 1: include 'views/html-create-booking-page.php'; break; case 2: include 'views/html-create-booking-page-2.php'; break; } }
function filter_bundled_product_in_cart_contents($cart_item, $key, $current_language) { if ($cart_item['data'] instanceof WC_Product_Booking) { global $woocommerce_wpml; $current_id = apply_filters('translate_object_id', $cart_item['data']->id, 'product', true, $current_language); $cart_product_id = $cart_item['data']->id; if ($current_id != $cart_product_id) { $cart_item['data'] = new WC_Product_Booking($current_id); } if ($woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT || $current_id != $cart_product_id) { $booking_info = array('wc_bookings_field_start_date_year' => $cart_item['booking']['_year'], 'wc_bookings_field_start_date_month' => $cart_item['booking']['_month'], 'wc_bookings_field_start_date_day' => $cart_item['booking']['_day'], 'add-to-cart' => $current_id, '_persons' => isset($cart_item['booking']['_persons']) ? isset($cart_item['booking']['_persons']) : array()); if (isset($cart_item['booking']['_resource_id'])) { $booking_info['wc_bookings_field_resource'] = $cart_item['booking']['_resource_id']; } if (isset($cart_item['booking']['_duration'])) { $booking_info['wc_bookings_field_duration'] = $cart_item['booking']['_duration']; } if (isset($cart_item['booking']['_time'])) { $booking_info['wc_bookings_field_start_date_time'] = $cart_item['booking']['_time']; } $booking_form = new WC_Booking_Form(wc_get_product($current_id)); $prod_qty = get_post_meta($current_id, '_wc_booking_qty', true); update_post_meta($current_id, '_wc_booking_qty', intval($prod_qty + $cart_item['booking']['_qty'])); $cost = $booking_form->calculate_booking_cost($booking_info); update_post_meta($current_id, '_wc_booking_qty', $prod_qty); if (!is_wp_error($cost)) { $cart_item['data']->set_price($cost); } } } return $cart_item; }
/** * Change addon price based on settings * @return float */ public function addon_price($cart_item_data, $addon, $product_id, $post_data) { $product = get_product($product_id); if ($product->is_type('booking')) { $booking_form = new WC_Booking_Form($product); $booking_data = $booking_form->get_posted_data($post_data); foreach ($cart_item_data as $key => $data) { if (!empty($addon['wc_booking_person_qty_multiplier']) && !empty($booking_data['_persons']) && array_sum($booking_data['_persons'])) { $cart_item_data[$key]['price'] = $data['price'] * array_sum($booking_data['_persons']); } if (!empty($addon['wc_booking_block_qty_multiplier']) && !empty($booking_data['_duration'])) { $cart_item_data[$key]['price'] = $data['price'] * $booking_data['_duration']; } } } return $cart_item_data; }