/**
  * Calculates bundled product prices incl. or excl. tax depending on the 'woocommerce_tax_display_shop' setting.
  *
  * @param  WC_Product   $product    the product
  * @param  double       $price      the product price
  * @return double                   modified product price incl. or excl. tax
  */
 public static function get_product_display_price($product, $price)
 {
     if (!$price) {
         return $price;
     }
     if (get_option('woocommerce_tax_display_shop') === 'excl') {
         $product_price = $product->get_price_excluding_tax(1, $price);
     } else {
         $product_price = $product->get_price_including_tax(1, $price);
     }
     return $product_price;
 }
 /**
  * Returns the price including or excluding tax, based on the 'woocommerce_tax_display_shop' setting.
  * Should be safe to remove when we drop WC 2.2 compatibility
  *
  * @param  WC_Product $product the product object
  * @param  string     $price   to calculate, left blank to just use get_price()
  * @param  integer    $qty     passed on to get_price_including_tax() or get_price_excluding_tax()
  * @return string
  */
 public static function get_product_display_price($product, $price = '', $qty = 1)
 {
     if (SV_WC_Plugin_Compatibility::is_wc_version_gte_2_3()) {
         return $product->get_display_price($price, $qty);
     } else {
         if ($price === '') {
             $price = $product->get_price();
         }
         $tax_display_mode = get_option('woocommerce_tax_display_shop');
         $display_price = $tax_display_mode == 'incl' ? $product->get_price_including_tax($qty, $price) : $product->get_price_excluding_tax($qty, $price);
         return $display_price;
     }
 }
Example #3
1
function woocs_product($ID, $attr, $currency = true)
{
    if (class_exists('WC_Product')) {
        $product = new WC_Product($ID);
        if ($attr == 'price_tax_inc') {
            $p = round($product->get_price_including_tax(), 2);
        } elseif ($attr == 'get_price_excluding_tax') {
            $p = round($product->get_price_excluding_tax(), 2);
        } elseif ($attr == 'get_price') {
            $p = round($product->get_price(), 2);
        } elseif ($attr == 'get_sale_price') {
            $p = round($product->get_sale_price(), 2);
        } elseif ($attr == 'get_regular_price') {
            $p = round($product->get_regular_price(), 2);
        } elseif ($attr == 'get_price_html') {
            $p = strip_tags($product->get_price_html());
        } elseif ($attr == 'is_in_stock') {
            $p = $product->is_in_stock();
        }
    }
    return $p;
}
Example #4
1
 /**
  * Get the product row subtotal.
  *
  * Gets the tax etc to avoid rounding issues.
  *
  * When on the checkout (review order), this will get the subtotal based on the customer's tax rate rather than the base rate.
  *
  * @param WC_Product $_product
  * @param int $quantity
  * @return string formatted price
  */
 public function get_product_subtotal($_product, $quantity)
 {
     $price = $_product->get_price();
     $taxable = $_product->is_taxable();
     // Taxable
     if ($taxable) {
         if ($this->tax_display_cart == 'excl') {
             $row_price = $_product->get_price_excluding_tax($quantity);
             $product_subtotal = wc_price($row_price);
             if ($this->prices_include_tax && $this->tax_total > 0) {
                 $product_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
             }
         } else {
             $row_price = $_product->get_price_including_tax($quantity);
             $product_subtotal = wc_price($row_price);
             if (!$this->prices_include_tax && $this->tax_total > 0) {
                 $product_subtotal .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
             }
         }
         // Non-taxable
     } else {
         $row_price = $price * $quantity;
         $product_subtotal = wc_price($row_price);
     }
     return apply_filters('woocommerce_cart_product_subtotal', $product_subtotal, $_product, $quantity, $this);
 }
 /**
  * Get min/max composite price excluding tax.
  *
  * @return double
  */
 public function get_composite_price_excluding_tax($min_or_max = 'min')
 {
     if ($this->is_priced_per_product()) {
         if (!$this->is_synced()) {
             $this->sync_composite();
         }
         $property = $min_or_max . '_composite_price_excl_tax';
         if ($this->{$property} !== false) {
             return $this->{$property};
         }
         $price = $min_or_max === 'min' ? $this->min_composite_price : $this->max_composite_price;
         if ($price) {
             $this->{$property} = $this->get_price_excluding_tax(1, $this->get_base_price());
             foreach ($this->price_index['price'][$min_or_max] as $component_id => $product_id) {
                 $component_data = $this->get_component_data($component_id);
                 $item_qty = $component_data['optional'] === 'yes' && $min_or_max === 'min' ? 0 : $component_data['quantity_' . $min_or_max];
                 if ($item_qty) {
                     $composited_product = $this->get_composited_product($component_id, $product_id);
                     $this->{$property} += $item_qty * $composited_product->get_price_excluding_tax($min_or_max);
                 }
             }
             $price = $this->{$property};
         }
     } else {
         $price = parent::get_price_excluding_tax(1, parent::get_price());
     }
     return $price;
 }
 /**
  * Calculates bundled product prices incl. or excl. tax depending on the 'woocommerce_tax_display_shop' setting.
  *
  * @param  WC_Product   $product    the product
  * @param  double       $price      the product price
  * @return double                   modified product price incl. or excl. tax
  */
 function get_product_price_incl_or_excl_tax($product, $price)
 {
     if ($price == 0) {
         return $price;
     }
     if ($this->wc_option_tax_display_shop == 'excl') {
         $product_price = $product->get_price_excluding_tax(1, $price);
     } else {
         $product_price = $product->get_price_including_tax(1, $price);
     }
     return $product_price;
 }
/**
* Get the product row price per item.
*
* @param WC_Product $_product
* @return string formatted price
*/
function get_quotelist_product_price($_product)
{
    if (get_option('woocommerce_display_cart_prices_excluding_tax') == 'yes') {
        $product_price = $_product->get_price_excluding_tax();
    } else {
        $product_price = $_product->get_price_including_tax();
    }
    //return array($product_price,apply_filters( 'woocommerce_cart_product_price', wc_price( $product_price ), $_product ));
    return (double) $product_price;
}
 /**
  * Get the shop price of a product incl or excl tax, depending on the 'woocommerce_tax_display_shop' setting.
  *
  * @param  WC_Product $product
  * @param  double $price
  * @return double
  */
 public function get_composited_product_price($product, $price = '')
 {
     if (!$price) {
         return $price;
     }
     if (wc_cp_tax_display_shop() === 'excl') {
         $product_price = $product->get_price_excluding_tax(1, $price);
     } else {
         $product_price = $product->get_price_including_tax(1, $price);
     }
     return $product_price;
 }
Example #9
0
 /**
  * Getter for min_bundle_price_excl_tax.
  *
  * @return double
  */
 public function get_min_bundle_price_excl_tax()
 {
     if ($this->is_priced_per_product()) {
         if (!$this->is_synced()) {
             $this->sync_bundle();
         }
         $price = $this->min_bundle_price_incl_tax;
     } else {
         $price = parent::get_price_excluding_tax(1, parent::get_price());
     }
     return $price;
 }
 /**
  * Min/max bundle price excl tax.
  *
  * @return double
  */
 public function get_bundle_price_excluding_tax($min_or_max = 'min')
 {
     if ($this->is_priced_per_product()) {
         if (!$this->is_synced()) {
             $this->sync_bundle();
         }
         $property = $min_or_max . '_bundle_price_excl_tax';
         if ($this->{$property} !== false) {
             return $this->{$property};
         }
         $price = $min_or_max === 'min' ? $this->min_bundle_price : $this->max_bundle_price;
         if ($price) {
             $this->{$property} = $this->get_price_excluding_tax(1, $this->get_base_price());
             foreach ($this->bundled_items as $bundled_item) {
                 $bundled_item_qty = $this->bundled_quantities_index[$min_or_max][$bundled_item->item_id];
                 if ($bundled_item_qty) {
                     $this->{$property} = $this->{$property} + $bundled_item_qty * $bundled_item->get_bundled_item_price_excluding_tax($min_or_max);
                 }
             }
             $price = $this->{$property};
         }
     } else {
         $price = parent::get_price_excluding_tax(1, parent::get_price());
     }
     return $price;
 }
 /**
  *
  * Gets custom price on the order page
  *
  * @param WC_Product $product
  * @param int $item_id
  * @param str $start - Start date
  * @param str $end - End date
  * @param array $order_item
  * @param array $coupons
  * @return array $item_prices - Item prices (subtotal, total, tax subtotal and tax total)
  *
  **/
 public function easy_booking_get_booking_price($product, $item_id, $start, $end, $order_item, $coupons)
 {
     if (!$product) {
         return false;
     }
     $calc_mode = $this->options['easy_booking_calc_mode'];
     // Calculation mode (Days or Nights)
     // Get booking duration
     $start_diff = strtotime($start);
     $end_diff = strtotime($end);
     $diff = absint($start_diff - $end_diff) * 1000;
     $days = $diff / 86400000;
     if ($days === 0) {
         $days = 1;
     }
     // If calculation mode is set to "Days", add one day
     if ($calc_mode === 'days' && $start != $end) {
         $duration = absint($days + 1);
     } elseif ($calc_mode === 'days' && $start === $end) {
         $duration = absint($days);
     } else {
         $duration = absint($days);
     }
     if ($product->is_taxable()) {
         $price = $product->get_price_excluding_tax();
         // Product price excluding tax
     } else {
         $price = $product->get_price();
         // Product price
     }
     // Price for x days
     $new_price = apply_filters('easy_booking_get_order_item_price', $price * $duration, $product, $item_id, $duration);
     if ($product->is_taxable()) {
         $item_tax_class = $order_item['tax_class'];
         $product_taxes = $this->easy_booking_get_product_taxes($new_price, $item_tax_class);
         // Product taxes without potential discounts
         foreach ($product_taxes as $_tax_id => $_tax_value) {
             $tax_subtotal[$_tax_id] = $_tax_value;
         }
         $tax_amount = WC_Tax::get_tax_total($product_taxes);
     }
     if ($coupons) {
         foreach ($coupons as $code) {
             $coupon = new WC_Coupon($code);
             if ($coupon->is_valid_for_product($product)) {
                 $coupon_amount = $coupon->get_discount_amount($new_price, $order_item, true);
                 // Discounted amount for item price
                 $total = $new_price - $coupon_amount;
                 // New price with discount
                 if (!empty($product_taxes)) {
                     foreach ($product_taxes as $_tax_id => $_tax_value) {
                         $tax_discount[$_tax_id] = $coupon->get_discount_amount($_tax_value, $order_item, true);
                         // Discounted amount for item taxes
                         $tax_total[$_tax_id] = $_tax_value - $tax_discount[$_tax_id];
                         //  Product taxes with discount
                     }
                 }
             } else {
                 if (!empty($product_taxes)) {
                     foreach ($product_taxes as $_tax_id => $_tax_value) {
                         $tax_total[$_tax_id] = $_tax_value;
                         // No valid coupon - Product taxes unchanged
                     }
                 }
                 $total = $new_price;
                 // No valid coupon - Product  price unchanged
             }
         }
     } else {
         if (!empty($product_taxes)) {
             foreach ($product_taxes as $_tax_id => $_tax_value) {
                 $tax_total[$_tax_id] = $_tax_value;
                 // No coupon - Product taxes unchanged
             }
         }
         $total = $new_price;
         // No coupon - Product  price unchanged
     }
     $new_price = $new_price * $order_item['quantity'];
     // Multiply subtotal by item quantity
     $total = $total * $order_item['quantity'];
     // Multiply total by item quantity
     if (!empty($product_taxes)) {
         foreach ($tax_subtotal as $tax_subtotal_id => $tax_subtotal_amount) {
             $tax_subtotal[$tax_subtotal_id] = $tax_subtotal_amount * $order_item['quantity'];
         }
         // Multiply tax subtotal by item quantity
         foreach ($tax_total as $tax_total_id => $tax_total_amount) {
             $tax_total[$tax_total_id] = $tax_total_amount * $order_item['quantity'];
         }
         // Multiply tax total by item quantity
         // Format taxes
         $line_taxes = array_map('wc_format_decimal', $tax_total);
         $line_subtotal_taxes = array_map('wc_format_decimal', $tax_subtotal);
         $item_prices['tax_subtotal'] = $line_subtotal_taxes;
         $item_prices['tax_total'] = $line_taxes;
     }
     $item_prices['subtotal'] = floatval(wc_format_decimal($new_price, 0));
     $item_prices['total'] = floatval(wc_format_decimal($total, 0));
     return $item_prices;
 }
 /**
  * Update a line item for the order.
  *
  * Note this does not update order totals.
  *
  * @param object|int $item order item ID or item object.
  * @param WC_Product $product
  * @param array $args data to update.
  * @return int updated order item ID
  */
 public function update_product($item, $product, $args)
 {
     _deprecated_function('WC_Order::update_product', '2.7', 'Interact with WC_Order_Item_Product class');
     if (is_numeric($item)) {
         $item = $this->get_item($item);
     }
     if (!is_object($item) || !$item->is_type('line_item')) {
         return false;
     }
     if (!$this->get_id()) {
         $this->save();
         // Order must exist
     }
     // BW compatibility with old args
     if (isset($args['totals'])) {
         foreach ($args['totals'] as $key => $value) {
             if ('tax' === $key) {
                 $args['total_tax'] = $value;
             } elseif ('tax_data' === $key) {
                 $args['taxes'] = $value;
             } else {
                 $args[$key] = $value;
             }
         }
     }
     // Handly qty if set
     if (isset($args['qty'])) {
         if ($product->backorders_require_notification() && $product->is_on_backorder($args['qty'])) {
             $item->add_meta_data(apply_filters('woocommerce_backordered_item_meta_name', __('Backordered', 'woocommerce')), $args['qty'] - max(0, $product->get_total_stock()), true);
         }
         $args['subtotal'] = $args['subtotal'] ? $args['subtotal'] : $product->get_price_excluding_tax($args['qty']);
         $args['total'] = $args['total'] ? $args['total'] : $product->get_price_excluding_tax($args['qty']);
     }
     $item->set_order_id($this->get_id());
     $item->set_all($args);
     $item->save();
     do_action('woocommerce_order_edit_product', $this->get_id(), $item->get_id(), $args, $product);
     return $item->get_id();
 }
 /**
  * function slider, creates slider
  * @param $atts Array - an associative array of attributes (preferences)
  * @param $content  String -  the enclosed content
  * @param $code String -  the shortcode name
  * @code
  * @static
  */
 static function slider($atts, $content = null, $code = "")
 {
     global $wpdb, $zdev_wcps_obj;
     //wpdb var
     static $id = 0;
     $id++;
     //attributes
     extract(shortcode_atts(array('prod_ids' => '', 'prod_tags' => '', 'width' => '100', 'height' => '100', 'animation' => 'fade', 'animation_duration' => 600, 'slide_show' => "true", 'slide_direction' => 'horizontal', 'speed' => '4000', 'direction_nav' => "false", 'pause_play' => "false", 'animation_loop' => "true", 'pause_on_action' => "true", 'pause_on_hover' => "true", 'limits' => '', 'navigation' => 'true', 'cat_ids' => '', 'num_of_prods' => 3, 'template' => 'default.css', 'show_price' => "true", 'show_title' => "true", 'image_source' => "thumbnail"), $atts));
     //get all the output in $out variable
     //enque styles and print scripts
     $out = self::flexslider_scripts($height, $speed, $width, $id, $navigation, $animation, $animation_duration, $slide_show, $slide_direction, $direction_nav, $pause_play, $animation_loop, $pause_on_action, $pause_on_hover);
     wp_print_scripts('jquery_flex');
     wp_enqueue_style('flexslider-style');
     wp_enqueue_style('woocommerce-product-slider-style', plugin_dir_url(__FILE__) . 'templates/' . $template);
     //vertical orientation css
     $vert_css = '';
     if ($slide_direction == "vertical") {
         $vert_css = ' psc-vertical';
     }
     //prepare html
     $out .= '<div class="flexslider' . $id . ' flexslider' . $vert_css . '">';
     $out .= '<ul class="slides">';
     //if categories are selected or entered
     if ($cat_ids != '') {
         if ($cat_ids != '') {
             //get the products based on the cat IDs
             $loop = new WP_Query(array('nopaging' => true, 'posts_per_page' => -1, 'post_type' => 'product', 'tax_query' => array(array('nopaging' => true, 'posts_per_page' => -1, 'taxonomy' => 'product_cat', 'field' => 'id', 'terms' => explode(',', $cat_ids)))));
         }
     } elseif ($prod_ids != '') {
         $prod_arr = array();
         //stores the product ids
         if ($prod_ids != '') {
             $prod_arr = explode(',', $prod_ids);
         }
         $loop = new WP_Query(array('post_type' => 'product', 'post__in' => $prod_arr));
     } elseif ($prod_tags != '') {
         //for product tags
         $prod_arr = array();
         //stores the product tags
         if ($prod_tags != '') {
             $prod_arr = explode(',', $prod_tags);
         }
         $loop = new WP_Query(array('nopaging' => true, 'posts_per_page' => -1, 'post_type' => 'product', 'tax_query' => array(array('nopaging' => true, 'posts_per_page' => -1, 'taxonomy' => 'product_tag', 'field' => 'slug', 'terms' => $prod_arr, 'operator' => 'IN'))));
     } else {
         //all products
         $loop = new WP_Query(array('post_type' => 'product', 'nopaging' => true, 'posts_per_page' => -1));
     }
     //determine div width / class based on number of products to display
     $divclass = '';
     switch ($num_of_prods) {
         case 1:
             $divclass = "one-slide";
             break;
         case 2:
             $divclass = "two-slides";
             break;
         case 3:
             $divclass = "three-slides";
             break;
         case 4:
             $divclass = "four-slides";
             break;
         case 5:
             $divclass = "five-slides";
             break;
         case 6:
             $divclass = "six-slides";
             break;
     }
     //loop through the posts or products
     $index = 0;
     //loop index
     while ($loop->have_posts()) {
         $loop->the_post();
         global $post;
         if (version_compare(WOOCOMMERCE_VERSION, "2.0.0") >= 0) {
             // WC 2.0
             $product_obj = !empty($values['variation_id']) ? get_product($values['variation_id'], array('parent_id' => $values['prod_id'])) : get_product($values['prod_id']);
         } else {
             if ($values['variation_id'] > 0) {
                 $product_obj = new WC_Product_Variation($values['variation_id'], $values['prod_id']);
             } else {
                 $product_obj = new WC_product($values['prod_id']);
             }
         }
         //initialize or create product object
         if (version_compare(WOOCOMMERCE_VERSION, "2.0.0") >= 0) {
             $product_obj = get_product($post->ID);
         } else {
             $product_obj = new WC_Product($post->ID);
         }
         $price = $title = '';
         //null value to price and title
         //show price
         if ($show_price == "true") {
             //price
             if (get_option('woocommerce_display_cart_prices_excluding_tax') == 'yes') {
                 $price = apply_filters('woocommerce_cart_item_price_html', woocommerce_price($product_obj->get_price_excluding_tax()));
             } else {
                 $price = apply_filters('woocommerce_cart_item_price_html', woocommerce_price($product_obj->get_price()));
             }
             //add from keyword if the product type is variable
             if ($product_obj->product_type == 'variable') {
                 $price = '<span class="amount">' . __('From', 'zippydev') . '</span> ' . $price;
             }
         }
         //show title
         if ($show_title == "true") {
             $title = $post->post_title;
         }
         //start list based on number of products
         if ($index % $num_of_prods == 0) {
             $out .= '<li>';
         }
         $prod_url = esc_url(get_permalink(apply_filters('woocommerce_in_cart_product', $product_obj->id)));
         $featured_img = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), $image_source);
         //if no featured image for the product, display the placeholder image
         if ($featured_img[0] == '' || $featured_img[0] == '/') {
             $featured_img[0] = plugin_dir_url(__FILE__) . 'images/placeholder.png';
         }
         $out .= '<div class="' . $divclass . '"><div class="psc-prod-container"><div class="img-wrap" style="width:' . $width . '%;height:' . $height . '%"><a href="' . $prod_url . '"><img src="' . $featured_img[0] . '" alt="' . $title . '" ></a></div><div class="psc-prod-details"><span class="title"><a href="' . $prod_url . '">' . $title . '</a></span>' . $price . '</div></div></div>';
         $index++;
         //close list based on number of products
         if ($index % $num_of_prods == 0) {
             $out .= '</li>';
         }
     }
     $out .= '</ul></div>';
     return $out;
 }
 /**
  * Adjust discounted product price HTML
  *
  * @since 1.3.0
  * @param string $html
  * @param WC_Product $product
  * @return float|string
  */
 public function on_price_html($html, $product)
 {
     /**
      * Controls whether or not member prices should use discount format when displayed
      *
      * @since 1.3.0
      * @param bool $use_discount_format Defaults to true
      */
     if (!apply_filters('wc_memberships_member_prices_use_discount_format', true)) {
         return $html;
     }
     $tax_display_mode = get_option('woocommerce_tax_display_shop');
     $this->disable_price_adjustments();
     $base_price = 'incl' == $tax_display_mode ? $product->get_price_including_tax() : $product->get_price_excluding_tax();
     $product_id = $product->is_type('variation') ? $product->variation_id : $product->id;
     $this->enable_price_adjustments();
     if (!$this->has_discounted_price($base_price, $product_id)) {
         return $html;
     }
     /**
      * Controls whether or not member prices should display sale prices as well
      *
      * @since 1.3.0
      * @param bool $display_sale_price Defaults to false
      */
     $display_sale_price = apply_filters('wc_memberships_member_prices_display_sale_price', false);
     add_filter('woocommerce_get_variation_prices_hash', array($this, 'nonmember_variation_prices_hash'), 10, 3);
     if (!$display_sale_price) {
         add_filter('woocommerce_product_is_on_sale', array($this, 'disable_sale_price'));
     }
     $this->disable_price_adjustments();
     $this->disable_price_html_adjustments();
     $_html = $product->get_price_html();
     $this->enable_price_adjustments();
     $this->enable_price_html_adjustments();
     remove_filter('woocommerce_get_variation_prices_hash', array($this, 'nonmember_variation_prices_hash'));
     if (!$display_sale_price) {
         remove_filter('woocommerce_product_is_on_sale', array($this, 'disable_sale_price'));
     }
     if ($html != $_html) {
         $html = '<del>' . $_html . '</del> <ins> ' . $html . '</ins>';
     }
     return $html;
 }
 /**
  * Add a product line item to the order. This is the only line item type with
  * it's own method because it saves looking up order amounts (costs are added up for you).
  * @param  \WC_Product $product
  * @param  int $qty
  * @param  array $args
  * @return int order item ID
  * @throws WC_Data_Exception
  */
 public function add_product($product, $qty = 1, $args = array())
 {
     if ($product) {
         $default_args = array('name' => $product->get_title(), 'tax_class' => $product->get_tax_class(), 'product_id' => $product->get_id(), 'variation_id' => isset($product->variation_id) ? $product->variation_id : 0, 'variation' => isset($product->variation_id) ? $product->get_variation_attributes() : array(), 'subtotal' => $product->get_price_excluding_tax($qty), 'total' => $product->get_price_excluding_tax($qty), 'quantity' => $qty);
     } else {
         $default_args = array('quantity' => $qty);
     }
     $args = wp_parse_args($args, $default_args);
     // BW compatibility with old args
     if (isset($args['totals'])) {
         foreach ($args['totals'] as $key => $value) {
             if ('tax' === $key) {
                 $args['total_tax'] = $value;
             } elseif ('tax_data' === $key) {
                 $args['taxes'] = $value;
             } else {
                 $args[$key] = $value;
             }
         }
     }
     $item = new WC_Order_Item_Product($args);
     $item->set_backorder_meta();
     $item->set_order_id($this->get_id());
     $item->save();
     $this->add_item($item);
     wc_do_deprecated_action('woocommerce_order_add_product', array($this->get_id(), $item->get_id(), $product, $qty, $args), '2.7', 'Use woocommerce_new_order_item action instead.');
     return $item->get_id();
 }
 /**
  * Add a product line item to the order
  *
  * @since 2.2
  * @param \WC_Product $product
  * @param int $qty Line item quantity
  * @param array $args
  * @return int|bool Item ID or false
  */
 public function add_product($product, $qty = 1, $args = array())
 {
     $default_args = array('variation' => array(), 'totals' => array());
     $args = wp_parse_args($args, $default_args);
     $item_id = wc_add_order_item($this->id, array('order_item_name' => $product->get_title(), 'order_item_type' => 'line_item'));
     if (!$item_id) {
         return false;
     }
     wc_add_order_item_meta($item_id, '_qty', wc_stock_amount($qty));
     wc_add_order_item_meta($item_id, '_tax_class', $product->get_tax_class());
     wc_add_order_item_meta($item_id, '_product_id', $product->id);
     wc_add_order_item_meta($item_id, '_variation_id', isset($product->variation_id) ? $product->variation_id : 0);
     // Set line item totals, either passed in or from the product
     wc_add_order_item_meta($item_id, '_line_subtotal', wc_format_decimal(isset($args['totals']['subtotal']) ? $args['totals']['subtotal'] : $product->get_price_excluding_tax($qty)));
     wc_add_order_item_meta($item_id, '_line_total', wc_format_decimal(isset($args['totals']['total']) ? $args['totals']['total'] : $product->get_price_excluding_tax($qty)));
     wc_add_order_item_meta($item_id, '_line_subtotal_tax', wc_format_decimal(isset($args['totals']['subtotal_tax']) ? $args['totals']['subtotal_tax'] : 0));
     wc_add_order_item_meta($item_id, '_line_tax', wc_format_decimal(isset($args['totals']['tax']) ? $args['totals']['tax'] : 0));
     // Save tax data - Since 2.2
     if (isset($args['totals']['tax_data'])) {
         $tax_data = array();
         $tax_data['total'] = array_map('wc_format_decimal', $args['totals']['tax_data']['total']);
         $tax_data['subtotal'] = array_map('wc_format_decimal', $args['totals']['tax_data']['subtotal']);
         wc_add_order_item_meta($item_id, '_line_tax_data', $tax_data);
     } else {
         wc_add_order_item_meta($item_id, '_line_tax_data', array('total' => array(), 'subtotal' => array()));
     }
     // Add variation meta
     if (!empty($args['variation'])) {
         foreach ($args['variation'] as $key => $value) {
             wc_add_order_item_meta($item_id, str_replace('attribute_', '', $key), $value);
         }
     }
     // Backorders
     if ($product->backorders_require_notification() && $product->is_on_backorder($qty)) {
         wc_add_order_item_meta($item_id, apply_filters('woocommerce_backordered_item_meta_name', __('Backordered', 'woocommerce')), $qty - max(0, $product->get_total_stock()));
     }
     do_action('woocommerce_order_add_product', $this->id, $item_id, $product, $qty, $args);
     return $item_id;
 }
 /**
  * Get the shop price of a product incl or excl tax, depending on the 'woocommerce_tax_display_shop' setting.
  *
  * @param  WC_Product $product
  * @param  double $price
  * @return double
  */
 public function get_composited_product_price($product, $price = '')
 {
     if ($price === '') {
         $price = $product->get_price();
     }
     if ($this->wc_option_tax_display_shop === 'excl') {
         $product_price = $product->get_price_excluding_tax(1, $price);
     } else {
         $product_price = $product->get_price_including_tax(1, $price);
     }
     return $product_price;
 }