round() public static method

Filter example: to return rounding to .5 cents you'd use: function euro_5cent_rounding( $in ) { return round( $in / 5, 2 ) * 5; } add_filter( 'woocommerce_tax_round', 'euro_5cent_rounding' );
public static round ( $in ) : double
return double
 /**
  * Gets order total - formatted for display.
  *
  * @return string
  */
 public function get_formatted_order_total($tax_display = '', $display_refunded = true)
 {
     $formatted_total = wc_price($this->get_total(), array('currency' => $this->get_order_currency()));
     $order_total = $this->get_total();
     $total_refunded = $this->get_total_refunded();
     $tax_string = '';
     // Tax for inclusive prices
     if (wc_tax_enabled() && 'incl' == $tax_display) {
         $tax_string_array = array();
         if ('itemized' == get_option('woocommerce_tax_total_display')) {
             foreach ($this->get_tax_totals() as $code => $tax) {
                 $tax_amount = $total_refunded && $display_refunded ? wc_price(WC_Tax::round($tax->amount - $this->get_total_tax_refunded_by_rate_id($tax->rate_id)), array('currency' => $this->get_order_currency())) : $tax->formatted_amount;
                 $tax_string_array[] = sprintf('%s %s', $tax_amount, $tax->label);
             }
         } else {
             $tax_amount = $total_refunded && $display_refunded ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax();
             $tax_string_array[] = sprintf('%s %s', wc_price($tax_amount, array('currency' => $this->get_order_currency())), WC()->countries->tax_or_vat());
         }
         if (!empty($tax_string_array)) {
             $tax_string = ' ' . sprintf(__('(Includes %s)', 'woocommerce'), implode(', ', $tax_string_array));
         }
     }
     if ($total_refunded && $display_refunded) {
         $formatted_total = '<del>' . strip_tags($formatted_total) . '</del> <ins>' . wc_price($order_total - $total_refunded, array('currency' => $this->get_order_currency())) . $tax_string . '</ins>';
     } else {
         $formatted_total .= $tax_string;
     }
     return apply_filters('woocommerce_get_formatted_order_total', $formatted_total, $this);
 }
 public static function woocommerce_get_price($price, $product)
 {
     global $post, $woocommerce;
     $baseprice = $price;
     $result = $baseprice;
     if ($post == null || !is_admin()) {
         if ($product->is_type('variation')) {
             $commission = WRP_Variations_Admin::get_commission($product, $product->variation_id);
         } else {
             $commission = self::get_commission($product);
         }
         if ($commission) {
             $baseprice = $product->get_regular_price();
             if ($product->get_sale_price() != $product->get_regular_price() && $product->get_sale_price() == $product->price) {
                 if (get_option("wrp-baseprice", "regular") == "sale") {
                     $baseprice = $product->get_sale_price();
                 }
             }
             $product_price = $baseprice;
             $type = get_option("wrp-method", "rate");
             $result = 0;
             if ($type == "rate") {
                 // if rate and price includes taxes
                 if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
                     $_tax = new WC_Tax();
                     $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
                     $taxes = $_tax->calc_tax($baseprice, $tax_rates, true);
                     $product_price = $_tax->round($baseprice - array_sum($taxes));
                 }
                 $result = self::bcmul($product_price, $commission, WOO_ROLE_PRICING_DECIMALS);
                 if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
                     $_tax = new WC_Tax();
                     $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
                     $taxes = $_tax->calc_tax($result, $tax_rates, false);
                     // important false
                     $result = $_tax->round($result + array_sum($taxes));
                 }
             } else {
                 $result = self::bcsub($product_price, $commission, WOO_ROLE_PRICING_DECIMALS);
             }
         }
     }
     return $result;
 }
 public static function woocommerce_get_price($price, $product)
 {
     global $post, $woocommerce;
     $baseprice = $price;
     $result = $baseprice;
     if ($post == null || !is_admin()) {
         $roleprice = self::get_role_price($product);
         if (empty($roleprice)) {
             $regularprice = $product->get_regular_price();
             if (!empty($regularprice)) {
                 $baseprice = $regularprice;
             }
             if ($product->get_sale_price() != $product->get_regular_price() && $product->get_sale_price() == $product->price) {
                 if (get_option("wrp-baseprice", "regular") == "sale") {
                     $baseprice = $product->get_sale_price();
                 }
             }
             $product_price = $baseprice;
         } else {
             $baseprice = $roleprice;
             $product_price = $roleprice;
         }
         $result = 0;
         if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
             $_tax = new WC_Tax();
             $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
             $taxes = $_tax->calc_tax($baseprice, $tax_rates, true);
             $product_price = $_tax->round($baseprice - array_sum($taxes));
         }
         $result = $product_price;
         if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
             $_tax = new WC_Tax();
             $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
             $taxes = $_tax->calc_tax($result, $tax_rates, false);
             // important false
             $result = $_tax->round($result + array_sum($taxes));
         }
     }
     return $result;
 }
/**
 * Calc line tax
 *
 * @access public
 * @return void
 */
function woocommerce_calc_line_taxes()
{
    global $woocommerce, $wpdb;
    check_ajax_referer('calc-totals', 'security');
    header('Content-Type: application/json; charset=utf-8');
    $tax = new WC_Tax();
    $taxes = $tax_rows = $item_taxes = $shipping_taxes = array();
    $order_id = absint($_POST['order_id']);
    $country = strtoupper(esc_attr($_POST['country']));
    $state = strtoupper(esc_attr($_POST['state']));
    $postcode = strtoupper(esc_attr($_POST['postcode']));
    $city = sanitize_title(esc_attr($_POST['city']));
    $items = $_POST['items'];
    $shipping = $_POST['shipping'];
    $item_tax = 0;
    // Calculate sales tax first
    if (sizeof($items) > 0) {
        foreach ($items as $item_id => $item) {
            $item_id = absint($item_id);
            $line_subtotal = isset($item['line_subtotal']) ? esc_attr($item['line_subtotal']) : '';
            $line_total = esc_attr($item['line_total']);
            $tax_class = esc_attr($item['tax_class']);
            if (!$item_id || $tax_class == '0') {
                continue;
            }
            // Get product details
            if (get_post_type($item_id) == 'product') {
                $_product = get_product($item_id);
                $item_tax_status = $_product->get_tax_status();
            } else {
                $item_tax_status = 'taxable';
            }
            // Only calc if taxable
            if ($item_tax_status == 'taxable') {
                $tax_rates = $tax->find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class));
                $line_subtotal_taxes = $tax->calc_tax($line_subtotal, $tax_rates, false);
                $line_taxes = $tax->calc_tax($line_total, $tax_rates, false);
                $line_subtotal_tax = $tax->round(array_sum($line_subtotal_taxes));
                $line_tax = $tax->round(array_sum($line_taxes));
                //$line_subtotal_tax = rtrim( rtrim( number_format( array_sum( $line_subtotal_taxes ), 4, '.', '' ), '0' ), '.' );
                //$line_tax = rtrim( rtrim( number_format( array_sum( $line_taxes ), 4, '.', '' ), '0' ), '.' );
                if ($line_subtotal_tax < 0) {
                    $line_subtotal_tax = 0;
                }
                if ($line_tax < 0) {
                    $line_tax = 0;
                }
                $item_taxes[$item_id] = array('line_subtotal_tax' => $line_subtotal_tax, 'line_tax' => $line_tax);
                $item_tax += $line_tax;
                // Sum the item taxes
                foreach (array_keys($taxes + $line_taxes) as $key) {
                    $taxes[$key] = (isset($line_taxes[$key]) ? $line_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
                }
            }
        }
    }
    // Now calculate shipping tax
    $matched_tax_rates = array();
    $tax_rates = $tax->find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => ''));
    if ($tax_rates) {
        foreach ($tax_rates as $key => $rate) {
            if (isset($rate['shipping']) && $rate['shipping'] == 'yes') {
                $matched_tax_rates[$key] = $rate;
            }
        }
    }
    $shipping_taxes = $tax->calc_shipping_tax($shipping, $matched_tax_rates);
    //$shipping_tax = rtrim( rtrim( number_format( array_sum( $shipping_taxes ), 2, '.', '' ), '0' ), '.' );
    $shipping_tax = $tax->round(array_sum($shipping_taxes));
    // Remove old tax rows
    $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'tax' )", $order_id));
    $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'tax'", $order_id));
    // Get tax rates
    $rates = $wpdb->get_results("SELECT tax_rate_id, tax_rate_country, tax_rate_state, tax_rate_name, tax_rate_priority FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name");
    $tax_codes = array();
    foreach ($rates as $rate) {
        $code = array();
        $code[] = $rate->tax_rate_country;
        $code[] = $rate->tax_rate_state;
        $code[] = $rate->tax_rate_name ? sanitize_title($rate->tax_rate_name) : 'TAX';
        $code[] = absint($rate->tax_rate_priority);
        $tax_codes[$rate->tax_rate_id] = strtoupper(implode('-', array_filter($code)));
    }
    // Now merge to keep tax rows
    ob_start();
    foreach (array_keys($taxes + $shipping_taxes) as $key) {
        $item = array();
        $item['rate_id'] = $key;
        $item['name'] = $tax_codes[$key];
        $item['label'] = $tax->get_rate_label($key);
        $item['compound'] = $tax->is_compound($key) ? 1 : 0;
        $item['tax_amount'] = $tax->round(isset($taxes[$key]) ? $taxes[$key] : 0);
        $item['shipping_tax_amount'] = $tax->round(isset($shipping_taxes[$key]) ? $shipping_taxes[$key] : 0);
        if (!$item['label']) {
            $item['label'] = $woocommerce->countries->tax_or_vat();
        }
        // Add line item
        $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $item['name'], 'order_item_type' => 'tax'));
        // Add line item meta
        if ($item_id) {
            woocommerce_add_order_item_meta($item_id, 'rate_id', $item['rate_id']);
            woocommerce_add_order_item_meta($item_id, 'label', $item['label']);
            woocommerce_add_order_item_meta($item_id, 'compound', $item['compound']);
            woocommerce_add_order_item_meta($item_id, 'tax_amount', $item['tax_amount']);
            woocommerce_add_order_item_meta($item_id, 'shipping_tax_amount', $item['shipping_tax_amount']);
        }
        include 'admin/post-types/writepanels/order-tax-html.php';
    }
    $tax_row_html = ob_get_clean();
    // Return
    echo json_encode(array('item_tax' => $item_tax, 'item_taxes' => $item_taxes, 'shipping_tax' => $shipping_tax, 'tax_row_html' => $tax_row_html));
    // Quit out
    die;
}
 public static function calculate_shipping_tax($shipping_amount, $order)
 {
     $tax_based_on = get_option('woocommerce_tax_based_on');
     $wc_tax_enabled = get_option('woocommerce_calc_taxes');
     // if taxes aren't enabled don't calculate them
     if ('no' === $wc_tax_enabled) {
         return 0;
     }
     if ('base' === $tax_based_on) {
         $default = wc_get_base_location();
         $country = $default['country'];
         $state = $default['state'];
         $postcode = '';
         $city = '';
     } elseif ('billing' === $tax_based_on) {
         $country = $order->billing_country;
         $state = $order->billing_state;
         $postcode = $order->billing_postcode;
         $city = $order->billing_city;
     } else {
         $country = $order->shipping_country;
         $state = $order->shipping_state;
         $postcode = $order->shipping_postcode;
         $city = $order->shipping_city;
     }
     // Now calculate shipping tax
     $matched_tax_rates = array();
     $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => ''));
     if ($tax_rates) {
         foreach ($tax_rates as $key => $rate) {
             if (isset($rate['shipping']) && 'yes' === $rate['shipping']) {
                 $matched_tax_rates[$key] = $rate;
             }
         }
     }
     $shipping_taxes = WC_Tax::calc_shipping_tax($shipping_amount, $matched_tax_rates);
     $shipping_tax_total = WC_Tax::round(array_sum($shipping_taxes));
     return $shipping_tax_total;
 }
 /**
  * Get totals for display on pages and in emails.
  *
  * @return array
  */
 public function get_order_item_totals($tax_display = '')
 {
     if (!$tax_display) {
         $tax_display = $this->tax_display_cart;
     }
     $total_rows = array();
     if ($subtotal = $this->get_subtotal_to_display(false, $tax_display)) {
         $total_rows['cart_subtotal'] = array('label' => __('Subtotal:', 'woocommerce'), 'value' => $subtotal);
     }
     if ($this->get_total_discount() > 0) {
         $total_rows['discount'] = array('label' => __('Discount:', 'woocommerce'), 'value' => '-' . $this->get_discount_to_display());
     }
     if ($this->get_shipping_method()) {
         $total_rows['shipping'] = array('label' => __('Shipping:', 'woocommerce'), 'value' => $this->get_shipping_to_display());
     }
     if ($fees = $this->get_fees()) {
         foreach ($fees as $id => $fee) {
             if (apply_filters('woocommerce_get_order_item_totals_excl_free_fees', $fee['line_total'] + $fee['line_tax'] == 0, $id)) {
                 continue;
             }
             if ('excl' == $tax_display) {
                 $total_rows['fee_' . $id] = array('label' => $fee['name'] . ':', 'value' => wc_price($fee['line_total'], array('currency' => $this->get_order_currency())));
             } else {
                 $total_rows['fee_' . $id] = array('label' => $fee['name'] . ':', 'value' => wc_price($fee['line_total'] + $fee['line_tax'], array('currency' => $this->get_order_currency())));
             }
         }
     }
     // Tax for tax exclusive prices
     if ('excl' == $tax_display) {
         if (get_option('woocommerce_tax_total_display') == 'itemized') {
             foreach ($this->get_tax_totals() as $code => $tax) {
                 $total_rows[sanitize_title($code)] = array('label' => $tax->label . ':', 'value' => $tax->formatted_amount);
             }
         } else {
             $total_rows['tax'] = array('label' => WC()->countries->tax_or_vat() . ':', 'value' => wc_price($this->get_total_tax(), array('currency' => $this->get_order_currency())));
         }
     }
     if ($this->get_total() > 0 && $this->payment_method_title) {
         $total_rows['payment_method'] = array('label' => __('Payment Method:', 'woocommerce'), 'value' => $this->payment_method_title);
     }
     // Order total display
     $order_total = $this->get_total();
     $total_refunded = $this->get_total_refunded();
     $total_string = '';
     $tax_string = '';
     // Tax for inclusive prices
     if (wc_tax_enabled() && 'incl' == $tax_display) {
         $tax_string_array = array();
         if ('itemized' == get_option('woocommerce_tax_total_display')) {
             foreach ($this->get_tax_totals() as $code => $tax) {
                 $tax_amount = $total_refunded ? wc_price(WC_Tax::round($tax->amount - $this->get_total_tax_refunded_by_rate_id($tax->rate_id)), array('currency' => $this->get_order_currency())) : $tax->formatted_amount;
                 $tax_string_array[] = sprintf('%s %s', $tax_amount, $tax->label);
             }
         } else {
             $tax_string_array[] = sprintf('%s %s', wc_price($this->get_total_tax() - $this->get_total_tax_refunded(), array('currency' => $this->get_order_currency())), WC()->countries->tax_or_vat());
         }
         if (!empty($tax_string_array)) {
             $tax_string = ' ' . sprintf(__('(Includes %s)', 'woocommerce'), implode(', ', $tax_string_array));
         }
     }
     if ($total_refunded) {
         $total_string = '<del>' . strip_tags($this->get_formatted_order_total()) . '</del> <ins>';
         $total_string .= wc_price($order_total - $total_refunded, array('currency' => $this->get_order_currency()));
         $total_string .= $tax_string;
         $total_string .= '</ins>';
     } else {
         $total_string = $this->get_formatted_order_total() . $tax_string;
     }
     $total_rows['order_total'] = array('label' => __('Total:', 'woocommerce'), 'value' => $total_string);
     return apply_filters('woocommerce_get_order_item_totals', $total_rows, $this);
 }
Beispiel #7
0
?>

		<?php 
if (wc_tax_enabled()) {
    ?>
			<?php 
    foreach ($order->get_tax_totals() as $code => $tax) {
        ?>
				<tr>
					<td class="label"><?php 
        echo $tax->label;
        ?>
:</td>
					<td class="total"><?php 
        if (($refunded = $order->get_total_tax_refunded_by_rate_id($tax->rate_id)) > 0) {
            echo '<del>' . strip_tags($tax->formatted_amount) . '</del> <ins>' . wc_price(WC_Tax::round($tax->amount, wc_get_price_decimals()) - WC_Tax::round($refunded, wc_get_price_decimals()), array('currency' => $order->get_order_currency())) . '</ins>';
        } else {
            echo $tax->formatted_amount;
        }
        ?>
</td>
					<td width="1%"></td>
				</tr>
			<?php 
    }
    ?>
		<?php 
}
?>

		<?php 
Beispiel #8
0
 /**
  * 
  * @param object $_this
  * @return number
  */
 function this_get_tax($_this)
 {
     $cart = $_this->get_cart();
     $tax = $tax_rates = array();
     foreach ($cart as $cart_item_key => $values) {
         $_product = $values['data'];
         // Prices
         $base_price = $_product->get_price();
         $line_price = $_product->get_price() * $values['quantity'];
         // Tax data
         $taxes = array();
         $discounted_taxes = array();
         /**
          * No tax to calculate
          */
         if (!$_product->is_taxable()) {
             // Discounted Price (price with any pre-tax discounts applied)
             $discounted_price = 0;
             $line_subtotal_tax = 0;
             $line_subtotal = $line_price;
             $line_tax = 0;
             $line_total = WC_Tax::round($discounted_price * $values['quantity']);
             /**
              * Prices include tax
              */
         } elseif ($_this->prices_include_tax) {
             $base_tax_rates = $shop_tax_rates[$_product->tax_class];
             $item_tax_rates = $tax_rates[$_product->get_tax_class()];
             /**
              * ADJUST TAX - Calculations when base tax is not equal to the item tax
              *
              * The woocommerce_adjust_non_base_location_prices filter can stop base taxes being taken off when dealing with out of base locations.
              * e.g. If a product costs 10 including tax, all users will pay 10 regardless of location and taxes.
              * This feature is experimental @since 2.4.7 and may change in the future. Use at your risk.
              */
             if ($item_tax_rates !== $base_tax_rates && apply_filters('woocommerce_adjust_non_base_location_prices', true)) {
                 // Work out a new base price without the shop's base tax
                 $taxes = WC_Tax::calc_tax($line_price, $base_tax_rates, true, true);
                 // Now we have a new item price (excluding TAX)
                 $line_subtotal = round($line_price - array_sum($taxes), WC_ROUNDING_PRECISION);
                 $taxes = WC_Tax::calc_tax($line_subtotal, $item_tax_rates);
                 $line_subtotal_tax = array_sum($taxes);
                 // Adjusted price (this is the price including the new tax rate)
                 $adjusted_price = ($line_subtotal + $line_subtotal_tax) / $values['quantity'];
                 // Apply discounts
                 $discounted_price = $_this->get_discounted_price($values, $adjusted_price, true);
                 $discounted_taxes = WC_Tax::calc_tax($discounted_price * $values['quantity'], $item_tax_rates, true);
                 $line_tax = array_sum($discounted_taxes);
                 $line_total = $discounted_price * $values['quantity'] - $line_tax;
                 /**
                  * Regular tax calculation (customer inside base and the tax class is unmodified
                  */
             } else {
                 // Work out a new base price without the item tax
                 $taxes = WC_Tax::calc_tax($line_price, $item_tax_rates, true);
                 // Now we have a new item price (excluding TAX)
                 $line_subtotal = $line_price - array_sum($taxes);
                 $line_subtotal_tax = array_sum($taxes);
                 // Calc prices and tax (discounted)
                 $discounted_price = 0;
                 $discounted_taxes = WC_Tax::calc_tax($discounted_price * $values['quantity'], $item_tax_rates, true);
                 $line_tax = array_sum($discounted_taxes);
                 $line_total = $discounted_price * $values['quantity'] - $line_tax;
             }
             // Tax rows - merge the totals we just got
             foreach (array_keys($_this->taxes + $discounted_taxes) as $key) {
                 $tax[$key] = (isset($discounted_taxes[$key]) ? $discounted_taxes[$key] : 0) + (isset($_this->taxes[$key]) ? $_this->taxes[$key] : 0);
             }
             /**
              * Prices exclude tax
              */
         } else {
             $item_tax_rates = $tax_rates[$_product->get_tax_class()];
             // Work out a new base price without the shop's base tax
             $taxes = WC_Tax::calc_tax($line_price, $item_tax_rates);
             // Now we have the item price (excluding TAX)
             $line_subtotal = $line_price;
             $line_subtotal_tax = array_sum($taxes);
             // Now calc product rates
             $discounted_price = 0;
             $discounted_taxes = WC_Tax::calc_tax($discounted_price * $values['quantity'], $item_tax_rates);
             $discounted_tax_amount = array_sum($discounted_taxes);
             $line_tax = $discounted_tax_amount;
             $line_total = $discounted_price * $values['quantity'];
             // Tax rows - merge the totals we just got
             foreach (array_keys($_this->taxes + $discounted_taxes) as $key) {
                 $tax[$key] = (isset($discounted_taxes[$key]) ? $discounted_taxes[$key] : 0) + (isset($_this->taxes[$key]) ? $_this->taxes[$key] : 0);
             }
         }
         $tax = array_map(array('WC_Tax', 'round'), $tax);
         $tax = array_sum($tax);
         $shipping_total = WC()->shipping->shipping_total;
         $shipping_taxes = WC()->shipping->shipping_taxes;
         if ($_this->round_at_subtotal) {
             $shipping_tax_total = WC_Tax::get_tax_total($shipping_taxes);
             $shipping_taxes = array_map(array('WC_Tax', 'round'), $shipping_taxes);
         } else {
             $shipping_tax_total = array_sum($shipping_taxes);
         }
         $array = array('tax' => $tax, 'shipping' => $shipping_total, 'shipping_tax' => $shipping_tax_total);
     }
     return $array;
 }
 /**
  * Update tax lines at order level by looking at the line item taxes themselves.
  *
  * @return bool success or fail
  */
 public function update_taxes()
 {
     $order_taxes = array();
     $order_shipping_taxes = array();
     foreach ($this->get_items(array('line_item', 'fee')) as $item_id => $item) {
         $line_tax_data = maybe_unserialize($item['line_tax_data']);
         if (isset($line_tax_data['total'])) {
             foreach ($line_tax_data['total'] as $tax_rate_id => $tax) {
                 if (!isset($order_taxes[$tax_rate_id])) {
                     $order_taxes[$tax_rate_id] = 0;
                 }
                 $order_taxes[$tax_rate_id] += $tax;
             }
         }
     }
     foreach ($this->get_items(array('shipping')) as $item_id => $item) {
         $line_tax_data = maybe_unserialize($item['taxes']);
         if (isset($line_tax_data)) {
             foreach ($line_tax_data as $tax_rate_id => $tax) {
                 if (!isset($order_shipping_taxes[$tax_rate_id])) {
                     $order_shipping_taxes[$tax_rate_id] = 0;
                 }
                 $order_shipping_taxes[$tax_rate_id] += $tax;
             }
         }
     }
     // Remove old existing tax rows
     $this->remove_order_items('tax');
     // Now merge to keep tax rows
     foreach (array_keys($order_taxes + $order_shipping_taxes) as $tax_rate_id) {
         $this->add_tax($tax_rate_id, isset($order_taxes[$tax_rate_id]) ? $order_taxes[$tax_rate_id] : 0, isset($order_shipping_taxes[$tax_rate_id]) ? $order_shipping_taxes[$tax_rate_id] : 0);
     }
     // Save tax totals
     $this->set_total(WC_Tax::round(array_sum($order_shipping_taxes)), 'shipping_tax');
     $this->set_total(WC_Tax::round(array_sum($order_taxes)), 'tax');
     return true;
 }
Beispiel #10
0
 /**
  * Calculate totals for the items in the cart.
  *
  * @access public
  */
 public function calculate_totals()
 {
     global $woocommerce;
     $this->reset();
     do_action('woocommerce_before_calculate_totals', $this);
     // Get count of all items + weights + subtotal (we may need this for discounts)
     if (sizeof($this->cart_contents) > 0) {
         foreach ($this->cart_contents as $cart_item_key => $values) {
             $_product = $values['data'];
             $this->cart_contents_weight = $this->cart_contents_weight + $_product->get_weight() * $values['quantity'];
             $this->cart_contents_count = $this->cart_contents_count + $values['quantity'];
             // Base Price (inclusive of tax for now)
             $row_base_price = $_product->get_price() * $values['quantity'];
             $base_tax_rates = $this->tax->get_shop_base_rate($_product->tax_class);
             $tax_amount = 0;
             if ($this->prices_include_tax) {
                 if ($_product->is_taxable()) {
                     $tax_rates = $this->tax->get_rates($_product->get_tax_class());
                     // ADJUST BASE if tax rate is different (different region or modified tax class)
                     if ($tax_rates !== $base_tax_rates) {
                         $base_taxes = $this->tax->calc_tax($row_base_price, $base_tax_rates, true, true);
                         $modded_taxes = $this->tax->calc_tax($row_base_price - array_sum($base_taxes), $tax_rates, false);
                         $row_base_price = $row_base_price - array_sum($base_taxes) + array_sum($modded_taxes);
                     }
                     $taxes = $this->tax->calc_tax($row_base_price, $tax_rates, true);
                     $tax_amount = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->get_tax_total($taxes) : array_sum($taxes);
                 }
                 // Sub total is based on base prices (without discounts)
                 $this->subtotal = $this->subtotal + $row_base_price;
                 $this->subtotal_ex_tax = $this->subtotal_ex_tax + ($row_base_price - $tax_amount);
             } else {
                 if ($_product->is_taxable()) {
                     $tax_rates = $this->tax->get_rates($_product->get_tax_class());
                     $taxes = $this->tax->calc_tax($row_base_price, $tax_rates, false);
                     $tax_amount = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->get_tax_total($taxes) : array_sum($taxes);
                 }
                 // Sub total is based on base prices (without discounts)
                 $this->subtotal = $this->subtotal + $row_base_price + $tax_amount;
                 $this->subtotal_ex_tax = $this->subtotal_ex_tax + $row_base_price;
             }
         }
     }
     // Now calc the main totals, including discounts
     if ($this->prices_include_tax) {
         /**
          * Calculate totals for items
          */
         if (sizeof($this->cart_contents) > 0) {
             foreach ($this->cart_contents as $cart_item_key => $values) {
                 /**
                  * Prices include tax
                  *
                  * To prevent rounding issues we need to work with the inclusive price where possible
                  * otherwise we'll see errors such as when working with a 9.99 inc price, 20% VAT which would
                  * be 8.325 leading to totals being 1p off
                  *
                  * Pre tax coupons come off the price the customer thinks they are paying - tax is calculated
                  * afterwards.
                  *
                  * e.g. $100 bike with $10 coupon = customer pays $90 and tax worked backwards from that
                  *
                  * Used this excellent article for reference:
                  *	http://developer.practicalecommerce.com/articles/1473-Coding-for-Tax-Calculations-Everything-You-Never-Wanted-to-Know-Part-2
                  */
                 $_product = $values['data'];
                 // Base Price (inclusive of tax for now)
                 $base_price = $_product->get_price();
                 // Base Price Adjustment
                 if ($_product->is_taxable()) {
                     // Get rates
                     $tax_rates = $this->tax->get_rates($_product->get_tax_class());
                     $base_tax_rates = $this->tax->get_shop_base_rate($_product->tax_class);
                     /**
                      * ADJUST TAX - Calculations when base tax is not equal to the item tax
                      */
                     if ($tax_rates !== $base_tax_rates) {
                         $row_base_price = $base_price * $values['quantity'];
                         // Work out a new base price without the shop's base tax
                         $line_tax = array_sum($this->tax->calc_tax($row_base_price, $base_tax_rates, true));
                         // Now we have a new item price (excluding TAX)
                         $line_subtotal = $this->tax->round($row_base_price - $line_tax);
                         // Now add taxes for the users location
                         $line_subtotal_tax = array_sum($this->tax->calc_tax($line_subtotal, $tax_rates, false));
                         $line_subtotal_tax = get_option('woocommerce_tax_round_at_subtotal') == 'yes' ? $line_subtotal_tax : $this->tax->round($line_subtotal_tax);
                         // Adjusted price (this is the price including the new tax rate)
                         $adjusted_price = ($line_subtotal + $line_subtotal_tax) / $values['quantity'];
                         // Apply discounts
                         $discounted_price = $this->get_discounted_price($values, $adjusted_price, true);
                         $discounted_taxes = $this->tax->calc_tax($discounted_price * $values['quantity'], $tax_rates, true);
                         $discounted_tax_amount = array_sum($discounted_taxes);
                         // Sum taxes
                         /**
                          * Regular tax calculation (customer inside base and the tax class is unmodified
                          */
                     } else {
                         // Base tax for line before discount - we will store this in the order data
                         $tax_amount = array_sum($this->tax->calc_tax($base_price * $values['quantity'], $tax_rates, true));
                         // Line subtotal + tax
                         $line_subtotal_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->round($tax_amount) : $tax_amount;
                         $line_subtotal = $base_price * $values['quantity'] - $this->tax->round($line_subtotal_tax);
                         // Calc prices and tax (discounted)
                         $discounted_price = $this->get_discounted_price($values, $base_price, true);
                         $discounted_taxes = $this->tax->calc_tax($discounted_price * $values['quantity'], $tax_rates, true);
                         $discounted_tax_amount = array_sum($discounted_taxes);
                         // Sum taxes
                     }
                     // Tax rows - merge the totals we just got
                     foreach (array_keys($this->taxes + $discounted_taxes) as $key) {
                         $this->taxes[$key] = (isset($discounted_taxes[$key]) ? $discounted_taxes[$key] : 0) + (isset($this->taxes[$key]) ? $this->taxes[$key] : 0);
                     }
                 } else {
                     // Discounted Price (price with any pre-tax discounts applied)
                     $discounted_price = $this->get_discounted_price($values, $base_price, true);
                     $discounted_tax_amount = 0;
                     $tax_amount = 0;
                     $line_subtotal_tax = 0;
                     $line_subtotal = $base_price * $values['quantity'];
                 }
                 // Line prices
                 $line_tax = get_option('woocommerce_tax_round_at_subtotal') == 'no' ? $this->tax->round($discounted_tax_amount) : $discounted_tax_amount;
                 $line_total = $discounted_price * $values['quantity'] - $this->tax->round($line_tax);
                 // Add any product discounts (after tax)
                 $this->apply_product_discounts_after_tax($values, $line_total + $discounted_tax_amount);
                 // Cart contents total is based on discounted prices and is used for the final total calculation
                 $this->cart_contents_total = $this->cart_contents_total + $line_total;
                 // Store costs + taxes for lines
                 $this->cart_contents[$cart_item_key]['line_total'] = $line_total;
                 $this->cart_contents[$cart_item_key]['line_tax'] = $line_tax;
                 $this->cart_contents[$cart_item_key]['line_subtotal'] = $line_subtotal;
                 $this->cart_contents[$cart_item_key]['line_subtotal_tax'] = $line_subtotal_tax;
             }
         }
     } else {
         if (sizeof($this->cart_contents) > 0) {
             foreach ($this->cart_contents as $cart_item_key => $values) {
                 /**
                  * Prices exclude tax
                  *
                  * This calculation is simpler - work with the base, untaxed price.
                  */
                 $_product = $values['data'];
                 // Base Price (i.e. no tax, regardless of region)
                 $base_price = $_product->get_price();
                 // Discounted Price (base price with any pre-tax discounts applied
                 $discounted_price = $this->get_discounted_price($values, $base_price, true);
                 // Tax Amount (For the line, based on discounted, ex.tax price)
                 if ($_product->is_taxable()) {
                     // Get tax rates
                     $tax_rates = $this->tax->get_rates($_product->get_tax_class());
                     // Base tax for line before discount - we will store this in the order data
                     $tax_amount = array_sum($this->tax->calc_tax($base_price * $values['quantity'], $tax_rates, false));
                     // Now calc product rates
                     $discounted_taxes = $this->tax->calc_tax($discounted_price * $values['quantity'], $tax_rates, false);
                     $discounted_tax_amount = array_sum($discounted_taxes);
                     // Tax rows - merge the totals we just got
                     foreach (array_keys($this->taxes + $discounted_taxes) as $key) {
                         $this->taxes[$key] = (isset($discounted_taxes[$key]) ? $discounted_taxes[$key] : 0) + (isset($this->taxes[$key]) ? $this->taxes[$key] : 0);
                     }
                 } else {
                     $discounted_tax_amount = 0;
                     $tax_amount = 0;
                 }
                 // Line prices
                 $line_subtotal_tax = $tax_amount;
                 $line_tax = $discounted_tax_amount;
                 $line_subtotal = $base_price * $values['quantity'];
                 $line_total = $discounted_price * $values['quantity'];
                 // Add any product discounts (after tax)
                 $this->apply_product_discounts_after_tax($values, $line_total + $line_tax);
                 // Cart contents total is based on discounted prices and is used for the final total calculation
                 $this->cart_contents_total = $this->cart_contents_total + $line_total;
                 // Store costs + taxes for lines
                 $this->cart_contents[$cart_item_key]['line_total'] = $line_total;
                 $this->cart_contents[$cart_item_key]['line_tax'] = $line_tax;
                 $this->cart_contents[$cart_item_key]['line_subtotal'] = $line_subtotal;
                 $this->cart_contents[$cart_item_key]['line_subtotal_tax'] = $line_subtotal_tax;
             }
         }
     }
     // Only calculate the grand total + shipping if on the cart/checkout
     if (is_checkout() || is_cart() || defined('WOOCOMMERCE_CHECKOUT') || defined('WOOCOMMERCE_CART')) {
         // Calculate the Shipping
         $this->calculate_shipping();
         // Trigger the fees API where developers can add fees to the cart
         $this->calculate_fees();
         // Total up/round taxes
         if (get_option('woocommerce_tax_round_at_subtotal') == 'no') {
             $this->tax_total = $this->tax->get_tax_total($this->taxes);
             $this->taxes = array_map(array($this->tax, 'round'), $this->taxes);
         } else {
             $this->tax_total = array_sum($this->taxes);
         }
         // Total up/round taxes for shipping
         if (get_option('woocommerce_tax_round_at_subtotal') == 'no') {
             $this->shipping_tax_total = $this->tax->get_tax_total($this->shipping_taxes);
             $this->shipping_taxes = array_map(array($this->tax, 'round'), $this->shipping_taxes);
         } else {
             $this->shipping_tax_total = array_sum($this->shipping_taxes);
         }
         // VAT exemption done at this point - so all totals are correct before exemption
         if ($woocommerce->customer->is_vat_exempt()) {
             $this->remove_taxes();
         }
         // Cart Discounts (after tax)
         $this->apply_cart_discounts_after_tax();
         // Allow plugins to hook and alter totals before final total is calculated
         do_action('woocommerce_calculate_totals', $this);
         // Grand Total - Discounted product prices, discounted tax, shipping cost + tax, and any discounts to be added after tax (e.g. store credit)
         $this->total = max(0, apply_filters('woocommerce_calculated_total', number_format($this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total - $this->discount_total + $this->fee_total, $this->dp, '.', ''), $this));
     } else {
         // Set tax total to sum of all tax rows
         $this->tax_total = $this->tax->get_tax_total($this->taxes);
         // VAT exemption done at this point - so all totals are correct before exemption
         if ($woocommerce->customer->is_vat_exempt()) {
             $this->remove_taxes();
         }
         // Cart Discounts (after tax)
         $this->apply_cart_discounts_after_tax();
     }
     $this->set_session();
 }
/**
 * For a given product, and optionally price/qty, work out the price with tax excluded, based on store settings.
 * @since  2.7.0
 * @param  WC_Product $product
 * @param  array $args
 * @return float
 */
function wc_get_price_excluding_tax($product, $args = array())
{
    $args = wp_parse_args($args, array('qty' => '', 'price' => ''));
    $price = $args['price'] ? $args['price'] : $product->get_price();
    $qty = $args['qty'] ? $args['qty'] : 1;
    if ($product->is_taxable() && wc_prices_include_tax()) {
        $tax_rates = WC_Tax::get_base_tax_rates($product->get_tax_class(true));
        $taxes = WC_Tax::calc_tax($price * $qty, $tax_rates, true);
        $price = WC_Tax::round($price * $qty - array_sum($taxes));
    } else {
        $price = $price * $qty;
    }
    return apply_filters('woocommerce_get_price_excluding_tax', $price, $qty, $product);
}
 /**
  * Calculate recurring line taxes when a store manager clicks the "Calc Line Tax" button on the "Edit Order" page.
  *
  * Based on the @see woocommerce_calc_line_taxes() function.
  * @since 1.2.4
  * @return void
  */
 public static function calculate_recurring_line_taxes()
 {
     global $woocommerce, $wpdb;
     check_ajax_referer('woocommerce-subscriptions', 'security');
     $tax = new WC_Tax();
     $taxes = $tax_rows = $item_taxes = $shipping_taxes = $return = array();
     $item_tax = 0;
     $order_id = absint($_POST['order_id']);
     $country = strtoupper(esc_attr($_POST['country']));
     $state = strtoupper(esc_attr($_POST['state']));
     $postcode = strtoupper(esc_attr($_POST['postcode']));
     $tax_class = esc_attr($_POST['tax_class']);
     if (isset($_POST['city'])) {
         $city = sanitize_title(esc_attr($_POST['city']));
     }
     $shipping = $_POST['shipping'];
     $line_subtotal = isset($_POST['line_subtotal']) ? esc_attr($_POST['line_subtotal']) : 0;
     $line_total = isset($_POST['line_total']) ? esc_attr($_POST['line_total']) : 0;
     $product_id = '';
     if (isset($_POST['order_item_id'])) {
         $product_id = woocommerce_get_order_item_meta($_POST['order_item_id'], '_product_id');
     } elseif (isset($_POST['product_id'])) {
         $product_id = esc_attr($_POST['product_id']);
     }
     if (!empty($product_id) && WC_Subscriptions_Product::is_subscription($product_id)) {
         // Get product details
         $product = WC_Subscriptions::get_product($product_id);
         $item_tax_status = $product->get_tax_status();
         if ($item_tax_status == 'taxable') {
             $tax_rates = $tax->find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class));
             $line_subtotal_taxes = $tax->calc_tax($line_subtotal, $tax_rates, false);
             $line_taxes = $tax->calc_tax($line_total, $tax_rates, false);
             $line_subtotal_tax = $tax->round(array_sum($line_subtotal_taxes));
             $line_tax = $tax->round(array_sum($line_taxes));
             if ($line_subtotal_tax < 0) {
                 $line_subtotal_tax = 0;
             }
             if ($line_tax < 0) {
                 $line_tax = 0;
             }
             $return = array('recurring_line_subtotal_tax' => $line_subtotal_tax, 'recurring_line_tax' => $line_tax);
             // Sum the item taxes
             foreach (array_keys($taxes + $line_taxes) as $key) {
                 $taxes[$key] = (isset($line_taxes[$key]) ? $line_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
             }
         }
         // Now calculate shipping tax
         $matched_tax_rates = array();
         $tax_rates = $tax->find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => ''));
         if ($tax_rates) {
             foreach ($tax_rates as $key => $rate) {
                 if (isset($rate['shipping']) && $rate['shipping'] == 'yes') {
                     $matched_tax_rates[$key] = $rate;
                 }
             }
         }
         $shipping_taxes = $tax->calc_shipping_tax($shipping, $matched_tax_rates);
         $shipping_tax = $tax->round(array_sum($shipping_taxes));
         $return['recurring_shipping_tax'] = $shipping_tax;
         // Remove old tax rows
         $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'recurring_tax' )", $order_id));
         $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'recurring_tax'", $order_id));
         // Get tax rates
         $rates = $wpdb->get_results("SELECT tax_rate_id, tax_rate_country, tax_rate_state, tax_rate_name, tax_rate_priority FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name");
         $tax_codes = array();
         foreach ($rates as $rate) {
             $code = array();
             $code[] = $rate->tax_rate_country;
             $code[] = $rate->tax_rate_state;
             $code[] = $rate->tax_rate_name ? sanitize_title($rate->tax_rate_name) : 'TAX';
             $code[] = absint($rate->tax_rate_priority);
             $tax_codes[$rate->tax_rate_id] = strtoupper(implode('-', array_filter($code)));
         }
         // Now merge to keep tax rows
         ob_start();
         foreach (array_keys($taxes + $shipping_taxes) as $key) {
             $item = array();
             $item['rate_id'] = $key;
             $item['name'] = $tax_codes[$key];
             $item['label'] = $tax->get_rate_label($key);
             $item['compound'] = $tax->is_compound($key) ? 1 : 0;
             $item['tax_amount'] = $tax->round(isset($taxes[$key]) ? $taxes[$key] : 0);
             $item['shipping_tax_amount'] = $tax->round(isset($shipping_taxes[$key]) ? $shipping_taxes[$key] : 0);
             if (!$item['label']) {
                 $item['label'] = $woocommerce->countries->tax_or_vat();
             }
             // Add line item
             $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $item['name'], 'order_item_type' => 'recurring_tax'));
             // Add line item meta
             if ($item_id) {
                 woocommerce_add_order_item_meta($item_id, 'rate_id', $item['rate_id']);
                 woocommerce_add_order_item_meta($item_id, 'label', $item['label']);
                 woocommerce_add_order_item_meta($item_id, 'compound', $item['compound']);
                 woocommerce_add_order_item_meta($item_id, 'tax_amount', $item['tax_amount']);
                 woocommerce_add_order_item_meta($item_id, 'shipping_tax_amount', $item['shipping_tax_amount']);
             }
             include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/post-types/writepanels/order-tax-html.php';
         }
         $return['tax_row_html'] = ob_get_clean();
         echo json_encode($return);
     }
     die;
 }
Beispiel #13
0
function vtprd_get_price_excluding_tax_forced($product_id, $price, $product)
{
    global $post, $wpdb, $woocommerce, $vtprd_cart, $vtprd_cart_item, $vtprd_setup_options, $vtprd_info;
    //changed $this->  to  $product->
    //use $discount_price as basis
    $qty = 1;
    if ($product->is_taxable()) {
        //if ( $product->is_taxable() && get_option('woocommerce_prices_include_tax') === 'yes' ) {
        $_tax = new WC_Tax();
        $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
        $taxes = $_tax->calc_tax($price * $qty, $tax_rates, true);
        $price = $_tax->round($price * $qty - array_sum($taxes));
    }
    return $price;
}
Beispiel #14
0
 /**
  * Test the rounding method.
  */
 public function test_round()
 {
     $this->assertEquals(WC_Tax::round('2.1234567'), '2.1235');
 }
 protected function _import_line_items(&$order, $order_id, $index)
 {
     $is_product_founded = false;
     switch ($this->import->options['pmwi_order']['products_source']) {
         // Get data from existing products
         case 'existing':
             foreach ($this->data['pmwi_order']['products'][$index] as $productIndex => $productItem) {
                 if (empty($productItem['sku'])) {
                     continue;
                 }
                 $args = array('post_type' => 'product', 'meta_key' => '_sku', 'meta_value' => $productItem['sku'], 'meta_compare' => '=');
                 $product = false;
                 $query = new WP_Query($args);
                 while ($query->have_posts()) {
                     $query->the_post();
                     $product = WC()->product_factory->get_product($query->post->ID);
                     break;
                 }
                 wp_reset_postdata();
                 if (empty($product)) {
                     $args['post_type'] = 'product_variation';
                     $query = new WP_Query($args);
                     while ($query->have_posts()) {
                         $query->the_post();
                         $product = WC()->product_factory->get_product($query->post->ID);
                         break;
                     }
                     wp_reset_postdata();
                 }
                 if ($product) {
                     $is_product_founded = true;
                     $item_price = $product->get_price();
                     $item_qty = empty($productItem['qty']) ? 1 : $productItem['qty'];
                     $item_subtotal = $item_price * $item_qty;
                     $item_subtotal_tax = 0;
                     $line_taxes = array();
                     foreach ($productItem['tax_rates'] as $key => $tax_rate) {
                         if (empty($tax_rate['code'])) {
                             continue;
                         }
                         $tax_rate_codes = explode("|", $tax_rate['code']);
                         $percentage_value = explode("|", $tax_rate['percentage_value']);
                         $amount_per_unit = explode("|", $tax_rate['amount_per_unit']);
                         foreach ($tax_rate_codes as $rate_key => $tax_rate_code) {
                             if ($tax_rate_code == 'standard') {
                                 $tax_rate_code = '';
                             }
                             $line_tax = 0;
                             switch ($tax_rate['calculate_logic']) {
                                 case 'percentage':
                                     if (!empty($percentage_value[$rate_key]) and is_numeric($percentage_value[$rate_key])) {
                                         $line_tax = WC_Tax::round($item_subtotal / 100 * $percentage_value[$rate_key]);
                                         $item_subtotal_tax += $line_tax;
                                     }
                                     if (!empty($this->tax_rates)) {
                                         foreach ($this->tax_rates as $rate_id => $rate) {
                                             if ($rate->tax_rate_name == $tax_rate_code) {
                                                 $line_taxes[$rate->tax_rate_id] = $line_tax;
                                                 break;
                                             }
                                         }
                                     }
                                     break;
                                 case 'per_unit':
                                     if (!empty($amount_per_unit[$rate_key]) and is_numeric($amount_per_unit[$rate_key])) {
                                         $line_tax = WC_Tax::round($amount_per_unit[$rate_key] * $item_qty);
                                         $item_subtotal_tax += $line_tax;
                                     }
                                     if (!empty($this->tax_rates)) {
                                         foreach ($this->tax_rates as $rate_id => $rate) {
                                             if ($rate->tax_rate_name == $tax_rate_code) {
                                                 $line_taxes[$rate->tax_rate_id] = $line_tax;
                                                 break;
                                             }
                                         }
                                     }
                                     break;
                                     // Look up tax rate code
                                 // Look up tax rate code
                                 default:
                                     $found_rates = WC_Tax::get_rates_for_tax_class($tax_rate_code);
                                     if (!empty($found_rates)) {
                                         $found_priority = array();
                                         foreach ($found_rates as $found_rate) {
                                             $matched_tax_rates = array();
                                             if (in_array($found_rate->tax_rate_priority, $found_priority)) {
                                                 continue;
                                             }
                                             $matched_tax_rates[$found_rate->tax_rate_id] = array('rate' => $found_rate->tax_rate, 'label' => $found_rate->tax_rate_name, 'shipping' => $found_rate->tax_rate_shipping ? 'yes' : 'no', 'compound' => $found_rate->tax_rate_compound ? 'yes' : 'no');
                                             $line_tax = array_sum(WC_Tax::calc_tax($item_subtotal, $matched_tax_rates, $this->prices_include_tax));
                                             $item_subtotal_tax += $line_tax;
                                             $line_taxes[$found_rate->tax_rate_id] = $line_tax;
                                             $found_priority[] = $found_rate->tax_rate_priority;
                                         }
                                     }
                                     break;
                             }
                         }
                     }
                     $variation = array();
                     $variation_str = '';
                     if ($product instanceof WC_Product_Variation) {
                         $variation = $product->get_variation_attributes();
                         if (!empty($variation)) {
                             foreach ($variation as $key => $value) {
                                 $variation_str .= $key . '-' . $value;
                             }
                         }
                     }
                     $product_item = new PMXI_Post_Record();
                     $product_item->getBy(array('import_id' => $this->import->id, 'post_id' => $order_id, 'unique_key' => 'line-item-' . $product->id . '-' . $variation_str));
                     if ($product_item->isEmpty()) {
                         $item_id = false;
                         // in case when this is new order just add new line items
                         if (!$item_id) {
                             $item_id = $order->add_product($product, $item_qty, array('variation' => $variation, 'totals' => array('subtotal' => $item_subtotal, 'subtotal_tax' => $item_subtotal_tax, 'total' => $item_subtotal, 'tax' => $item_subtotal_tax, 'tax_data' => array('total' => $line_taxes, 'subtotal' => array()))));
                         }
                         if (!$item_id) {
                             $this->logger and call_user_func($this->logger, __('- <b>WARNING</b> Unable to create order line product.', 'wp_all_import_plugin'));
                         } else {
                             $product_item->set(array('import_id' => $this->import->id, 'post_id' => $order_id, 'unique_key' => 'line-item-' . $product->id . '-' . $variation_str, 'product_key' => 'line-item-' . $item_id, 'iteration' => $this->import->iteration))->save();
                         }
                     } else {
                         $item_id = str_replace('line-item-', '', $product_item->product_key);
                         $is_updated = $order->update_product($item_id, $product, array('qty' => $item_qty, 'tax_class' => $product->get_tax_class(), 'totals' => array('subtotal' => $item_subtotal, 'subtotal_tax' => $item_subtotal_tax, 'total' => $item_subtotal, 'tax' => $item_subtotal_tax, 'tax_data' => array('total' => $line_taxes, 'subtotal' => array())), 'variation' => $variation));
                         if ($is_updated) {
                             $product_item->set(array('iteration' => $this->import->iteration))->save();
                         }
                     }
                 }
             }
             break;
             // Manually import product order data and do not try to match to existing products
         // Manually import product order data and do not try to match to existing products
         default:
             $is_product_founded = true;
             foreach ($this->data['pmwi_order']['manual_products'][$index] as $productIndex => $productItem) {
                 $item_price = $productItem['price_per_unit'];
                 $item_qty = empty($productItem['qty']) ? 1 : $productItem['qty'];
                 $item_subtotal = $item_price * $item_qty;
                 $item_subtotal_tax = 0;
                 $line_taxes = array();
                 foreach ($productItem['tax_rates'] as $key => $tax_rate) {
                     if (empty($tax_rate['code'])) {
                         continue;
                     }
                     $line_tax = 0;
                     switch ($tax_rate['calculate_logic']) {
                         case 'percentage':
                             if (!empty($tax_rate['percentage_value']) and is_numeric($tax_rate['percentage_value'])) {
                                 $line_tax = WC_Tax::round($item_subtotal / 100 * $tax_rate['percentage_value']);
                                 $item_subtotal_tax += $line_tax;
                             }
                             break;
                         case 'per_unit':
                             if (!empty($tax_rate['amount_per_unit']) and is_numeric($tax_rate['amount_per_unit'])) {
                                 $line_tax = WC_Tax::round($tax_rate['amount_per_unit'] * $item_qty);
                                 $item_subtotal_tax += $line_tax;
                             }
                             break;
                             // Look up tax rate code
                         // Look up tax rate code
                         default:
                             $found_rates = WC_Tax::get_rates_for_tax_class($tax_rate['code']);
                             if (!empty($found_rates)) {
                                 $matched_tax_rates = array();
                                 $found_priority = array();
                                 foreach ($found_rates as $found_rate) {
                                     if (in_array($found_rate->tax_rate_priority, $found_priority)) {
                                         continue;
                                     }
                                     $matched_tax_rates[$found_rate->tax_rate_id] = array('rate' => $found_rate->tax_rate, 'label' => $found_rate->tax_rate_name, 'shipping' => $found_rate->tax_rate_shipping ? 'yes' : 'no', 'compound' => $found_rate->tax_rate_compound ? 'yes' : 'no');
                                     $found_priority[] = $found_rate->tax_rate_priority;
                                 }
                                 $line_tax = array_sum(WC_Tax::calc_tax($item_subtotal, $matched_tax_rates, true));
                                 $item_subtotal_tax += $line_tax;
                             }
                             break;
                     }
                     if (!empty($this->tax_rates)) {
                         foreach ($this->tax_rates as $rate_id => $rate) {
                             $line_taxes[$rate->tax_rate_id] = $line_tax;
                             break;
                         }
                     }
                 }
                 $variation = array();
                 $product_item = new PMXI_Post_Record();
                 $product_item->getBy(array('import_id' => $this->import->id, 'post_id' => $order_id, 'unique_key' => 'manual-line-item-' . $productIndex . '-' . $productItem['sku']));
                 if ($product_item->isEmpty()) {
                     $item_id = wc_add_order_item($order_id, array('order_item_name' => $productItem['sku'], 'order_item_type' => 'line_item'));
                     if (!$item_id) {
                         $this->logger and call_user_func($this->logger, __('- <b>WARNING</b> Unable to create order line product.', 'wp_all_import_plugin'));
                     } else {
                         wc_add_order_item_meta($item_id, '_qty', wc_stock_amount($item_qty));
                         wc_add_order_item_meta($item_id, '_tax_class', '');
                         wc_add_order_item_meta($item_id, '_line_subtotal', wc_format_decimal($item_subtotal));
                         wc_add_order_item_meta($item_id, '_line_total', wc_format_decimal($item_subtotal));
                         wc_add_order_item_meta($item_id, '_line_subtotal_tax', wc_format_decimal($item_subtotal_tax));
                         wc_add_order_item_meta($item_id, '_line_tax', wc_format_decimal($item_subtotal_tax));
                         wc_add_order_item_meta($item_id, '_line_tax_data', array('total' => $line_taxes, 'subtotal' => array()));
                         if (!empty($productItem['meta_name'])) {
                             foreach ($productItem['meta_name'] as $key => $meta_name) {
                                 wc_add_order_item_meta($item_id, $meta_name, isset($productItem['meta_value'][$key]) ? $productItem['meta_value'][$key] : '');
                             }
                         }
                         $product_item->set(array('import_id' => $this->import->id, 'post_id' => $order_id, 'unique_key' => 'manual-line-item-' . $productIndex . '-' . $productItem['sku'], 'product_key' => 'manual-line-item-' . $item_id, 'iteration' => $this->import->iteration))->save();
                     }
                 } else {
                     $item_id = str_replace('manual-line-item-', '', $product_item->product_key);
                     if (is_numeric($item_id)) {
                         wc_update_order_item($item_id, array('order_item_name' => $productItem['sku'], 'order_item_type' => 'line_item'));
                         wc_update_order_item_meta($item_id, '_qty', wc_stock_amount($item_qty));
                         wc_update_order_item_meta($item_id, '_tax_class', '');
                         wc_update_order_item_meta($item_id, '_line_subtotal', wc_format_decimal($item_subtotal));
                         wc_update_order_item_meta($item_id, '_line_total', wc_format_decimal($item_subtotal));
                         wc_update_order_item_meta($item_id, '_line_subtotal_tax', wc_format_decimal($item_subtotal_tax));
                         wc_update_order_item_meta($item_id, '_line_tax', wc_format_decimal($item_subtotal_tax));
                         wc_update_order_item_meta($item_id, '_line_tax_data', array('total' => $line_taxes, 'subtotal' => array()));
                         if (!empty($productItem['meta_name'])) {
                             foreach ($productItem['meta_name'] as $key => $meta_name) {
                                 wc_update_order_item_meta($item_id, $meta_name, isset($productItem['meta_value'][$key]) ? $productItem['meta_value'][$key] : '');
                             }
                         }
                         $product_item->set(array('iteration' => $this->import->iteration))->save();
                     }
                 }
             }
             break;
     }
     return $is_product_founded;
 }
Beispiel #16
0
 /**
  * Calculate totals for the items in the cart.
  */
 public function calculate_totals()
 {
     $this->reset();
     $this->coupons = $this->get_coupons();
     do_action('woocommerce_before_calculate_totals', $this);
     if ($this->is_empty()) {
         $this->set_session();
         return;
     }
     $tax_rates = array();
     $shop_tax_rates = array();
     /**
      * Calculate subtotals for items. This is done first so that discount logic can use the values.
      */
     foreach ($this->get_cart() as $cart_item_key => $values) {
         $_product = $values['data'];
         // Count items + weight
         $this->cart_contents_weight += $_product->get_weight() * $values['quantity'];
         $this->cart_contents_count += $values['quantity'];
         // Prices
         $line_price = $_product->get_price() * $values['quantity'];
         $line_subtotal = 0;
         $line_subtotal_tax = 0;
         /**
          * No tax to calculate
          */
         if (!$_product->is_taxable()) {
             // Subtotal is the undiscounted price
             $this->subtotal += $line_price;
             $this->subtotal_ex_tax += $line_price;
             /**
              * Prices include tax
              *
              * To prevent rounding issues we need to work with the inclusive price where possible
              * otherwise we'll see errors such as when working with a 9.99 inc price, 20% VAT which would
              * be 8.325 leading to totals being 1p off
              *
              * Pre tax coupons come off the price the customer thinks they are paying - tax is calculated
              * afterwards.
              *
              * e.g. $100 bike with $10 coupon = customer pays $90 and tax worked backwards from that
              */
         } elseif ($this->prices_include_tax) {
             // Get base tax rates
             if (empty($shop_tax_rates[$_product->tax_class])) {
                 $shop_tax_rates[$_product->tax_class] = WC_Tax::get_base_tax_rates($_product->tax_class);
             }
             // Get item tax rates
             if (empty($tax_rates[$_product->get_tax_class()])) {
                 $tax_rates[$_product->get_tax_class()] = WC_Tax::get_rates($_product->get_tax_class());
             }
             $base_tax_rates = $shop_tax_rates[$_product->tax_class];
             $item_tax_rates = $tax_rates[$_product->get_tax_class()];
             /**
              * ADJUST TAX - Calculations when base tax is not equal to the item tax
              */
             if ($item_tax_rates !== $base_tax_rates) {
                 // Work out a new base price without the shop's base tax
                 $taxes = WC_Tax::calc_tax($line_price, $base_tax_rates, true, true);
                 // Now we have a new item price (excluding TAX)
                 $line_subtotal = $line_price - array_sum($taxes);
                 // Now add modified taxes
                 $tax_result = WC_Tax::calc_tax($line_subtotal, $item_tax_rates);
                 $line_subtotal_tax = array_sum($tax_result);
                 /**
                  * Regular tax calculation (customer inside base and the tax class is unmodified
                  */
             } else {
                 // Calc tax normally
                 $taxes = WC_Tax::calc_tax($line_price, $item_tax_rates, true);
                 $line_subtotal_tax = array_sum($taxes);
                 $line_subtotal = $line_price - array_sum($taxes);
             }
             /**
              * Prices exclude tax
              *
              * This calculation is simpler - work with the base, untaxed price.
              */
         } else {
             // Get item tax rates
             if (empty($tax_rates[$_product->get_tax_class()])) {
                 $tax_rates[$_product->get_tax_class()] = WC_Tax::get_rates($_product->get_tax_class());
             }
             $item_tax_rates = $tax_rates[$_product->get_tax_class()];
             // Base tax for line before discount - we will store this in the order data
             $taxes = WC_Tax::calc_tax($line_price, $item_tax_rates);
             $line_subtotal_tax = array_sum($taxes);
             $line_subtotal = $line_price;
         }
         // Add to main subtotal
         $this->subtotal += $line_subtotal + $line_subtotal_tax;
         $this->subtotal_ex_tax += $line_subtotal;
     }
     /**
      * Calculate totals for items
      */
     foreach ($this->get_cart() as $cart_item_key => $values) {
         $_product = $values['data'];
         // Prices
         $base_price = $_product->get_price();
         $line_price = $_product->get_price() * $values['quantity'];
         // Tax data
         $taxes = array();
         $discounted_taxes = array();
         /**
          * No tax to calculate
          */
         if (!$_product->is_taxable()) {
             // Discounted Price (price with any pre-tax discounts applied)
             $discounted_price = $this->get_discounted_price($values, $base_price, true);
             $line_subtotal_tax = 0;
             $line_subtotal = $line_price;
             $line_tax = 0;
             $line_total = WC_Tax::round($discounted_price * $values['quantity']);
             /**
              * Prices include tax
              */
         } elseif ($this->prices_include_tax) {
             $base_tax_rates = $shop_tax_rates[$_product->tax_class];
             $item_tax_rates = $tax_rates[$_product->get_tax_class()];
             /**
              * ADJUST TAX - Calculations when base tax is not equal to the item tax
              */
             if ($item_tax_rates !== $base_tax_rates) {
                 // Work out a new base price without the shop's base tax
                 $taxes = WC_Tax::calc_tax($line_price, $base_tax_rates, true, true);
                 // Now we have a new item price (excluding TAX)
                 $line_subtotal = round($line_price - array_sum($taxes), WC_ROUNDING_PRECISION);
                 $taxes = WC_Tax::calc_tax($line_subtotal, $item_tax_rates);
                 $line_subtotal_tax = array_sum($taxes);
                 // Adjusted price (this is the price including the new tax rate)
                 $adjusted_price = ($line_subtotal + $line_subtotal_tax) / $values['quantity'];
                 // Apply discounts
                 $discounted_price = $this->get_discounted_price($values, $adjusted_price, true);
                 $discounted_taxes = WC_Tax::calc_tax($discounted_price * $values['quantity'], $item_tax_rates, true);
                 $line_tax = array_sum($discounted_taxes);
                 $line_total = $discounted_price * $values['quantity'] - $line_tax;
                 /**
                  * Regular tax calculation (customer inside base and the tax class is unmodified
                  */
             } else {
                 // Work out a new base price without the item tax
                 $taxes = WC_Tax::calc_tax($line_price, $item_tax_rates, true);
                 // Now we have a new item price (excluding TAX)
                 $line_subtotal = $line_price - array_sum($taxes);
                 $line_subtotal_tax = array_sum($taxes);
                 // Calc prices and tax (discounted)
                 $discounted_price = $this->get_discounted_price($values, $base_price, true);
                 $discounted_taxes = WC_Tax::calc_tax($discounted_price * $values['quantity'], $item_tax_rates, true);
                 $line_tax = array_sum($discounted_taxes);
                 $line_total = $discounted_price * $values['quantity'] - $line_tax;
             }
             // Tax rows - merge the totals we just got
             foreach (array_keys($this->taxes + $discounted_taxes) as $key) {
                 $this->taxes[$key] = (isset($discounted_taxes[$key]) ? $discounted_taxes[$key] : 0) + (isset($this->taxes[$key]) ? $this->taxes[$key] : 0);
             }
             /**
              * Prices exclude tax
              */
         } else {
             $item_tax_rates = $tax_rates[$_product->get_tax_class()];
             // Work out a new base price without the shop's base tax
             $taxes = WC_Tax::calc_tax($line_price, $item_tax_rates);
             // Now we have the item price (excluding TAX)
             $line_subtotal = $line_price;
             $line_subtotal_tax = array_sum($taxes);
             // Now calc product rates
             $discounted_price = $this->get_discounted_price($values, $base_price, true);
             $discounted_taxes = WC_Tax::calc_tax($discounted_price * $values['quantity'], $item_tax_rates);
             $discounted_tax_amount = array_sum($discounted_taxes);
             $line_tax = $discounted_tax_amount;
             $line_total = $discounted_price * $values['quantity'];
             // Tax rows - merge the totals we just got
             foreach (array_keys($this->taxes + $discounted_taxes) as $key) {
                 $this->taxes[$key] = (isset($discounted_taxes[$key]) ? $discounted_taxes[$key] : 0) + (isset($this->taxes[$key]) ? $this->taxes[$key] : 0);
             }
         }
         // Cart contents total is based on discounted prices and is used for the final total calculation
         $this->cart_contents_total += $line_total;
         // Store costs + taxes for lines
         $this->cart_contents[$cart_item_key]['line_total'] = $line_total;
         $this->cart_contents[$cart_item_key]['line_tax'] = $line_tax;
         $this->cart_contents[$cart_item_key]['line_subtotal'] = $line_subtotal;
         $this->cart_contents[$cart_item_key]['line_subtotal_tax'] = $line_subtotal_tax;
         // Store rates ID and costs - Since 2.2
         $this->cart_contents[$cart_item_key]['line_tax_data'] = array('total' => $discounted_taxes, 'subtotal' => $taxes);
     }
     // Round cart contents
     $this->cart_contents_total = round($this->cart_contents_total, $this->dp);
     // Only calculate the grand total + shipping if on the cart/checkout
     if (is_checkout() || is_cart() || defined('WOOCOMMERCE_CHECKOUT') || defined('WOOCOMMERCE_CART')) {
         // Calculate the Shipping
         $this->calculate_shipping();
         // Trigger the fees API where developers can add fees to the cart
         $this->calculate_fees();
         // Total up/round taxes and shipping taxes
         if ($this->round_at_subtotal) {
             $this->tax_total = WC_Tax::get_tax_total($this->taxes);
             $this->shipping_tax_total = WC_Tax::get_tax_total($this->shipping_taxes);
             $this->taxes = array_map(array('WC_Tax', 'round'), $this->taxes);
             $this->shipping_taxes = array_map(array('WC_Tax', 'round'), $this->shipping_taxes);
         } else {
             $this->tax_total = array_sum($this->taxes);
             $this->shipping_tax_total = array_sum($this->shipping_taxes);
         }
         // VAT exemption done at this point - so all totals are correct before exemption
         if (WC()->customer->is_vat_exempt()) {
             $this->remove_taxes();
         }
         // Allow plugins to hook and alter totals before final total is calculated
         do_action('woocommerce_calculate_totals', $this);
         // Grand Total - Discounted product prices, discounted tax, shipping cost + tax
         $this->total = max(0, apply_filters('woocommerce_calculated_total', round($this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total + $this->fee_total, $this->dp), $this));
     } else {
         // Set tax total to sum of all tax rows
         $this->tax_total = WC_Tax::get_tax_total($this->taxes);
         // VAT exemption done at this point - so all totals are correct before exemption
         if (WC()->customer->is_vat_exempt()) {
             $this->remove_taxes();
         }
     }
     do_action('woocommerce_after_calculate_totals', $this);
     $this->set_session();
 }
 /**
  * Update tax lines for the order based on the line item taxes themselves.
  */
 public function update_taxes()
 {
     $cart_taxes = array();
     $shipping_taxes = array();
     foreach ($this->get_items(array('line_item', 'fee')) as $item_id => $item) {
         $taxes = $item->get_taxes();
         foreach ($taxes['total'] as $tax_rate_id => $tax) {
             $cart_taxes[$tax_rate_id] = isset($cart_taxes[$tax_rate_id]) ? $cart_taxes[$tax_rate_id] + $tax : $tax;
         }
     }
     foreach ($this->get_shipping_methods() as $item_id => $item) {
         $taxes = $item->get_taxes();
         foreach ($taxes['total'] as $tax_rate_id => $tax) {
             $shipping_taxes[$tax_rate_id] = isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] + $tax : $tax;
         }
     }
     // Remove old existing tax rows.
     $this->remove_order_items('tax');
     // Now merge to keep tax rows.
     foreach (array_keys($cart_taxes + $shipping_taxes) as $tax_rate_id) {
         $item = new WC_Order_Item_Tax();
         $item->set_rate($tax_rate_id);
         $item->set_tax_total(isset($cart_taxes[$tax_rate_id]) ? $cart_taxes[$tax_rate_id] : 0);
         $item->set_shipping_tax_total(isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] : 0);
         $this->add_item($item);
     }
     // Save tax totals
     $this->set_shipping_tax(WC_Tax::round(array_sum($shipping_taxes)));
     $this->set_cart_tax(WC_Tax::round(array_sum($cart_taxes)));
     $this->save();
 }
 /**
  * Calculate wcmp vendor shipping tax
  *
  * @param double $shipping_amount
  * @param object $order
  */
 public function calculate_shipping_tax($shipping_amount, $order)
 {
     global $WCMp, $woocommerce;
     $wc_tax_enabled = get_option('woocommerce_calc_taxes');
     if ('no' === $wc_tax_enabled) {
         return 0;
     }
     $tax_based_on = get_option('woocommerce_tax_based_on');
     $WC_Tax = new WC_Tax();
     if ('base' === $tax_based_on) {
         $default = wc_get_base_location();
         $country = $default['country'];
         $state = $default['state'];
         $postcode = '';
         $city = '';
     } elseif ('billing' === $tax_based_on) {
         $country = $order->billing_country;
         $state = $order->billing_state;
         $postcode = $order->billing_postcode;
         $city = $order->billing_city;
     } else {
         $country = $order->shipping_country;
         $state = $order->shipping_state;
         $postcode = $order->shipping_postcode;
         $city = $order->shipping_city;
     }
     $matched_tax_rates = array();
     $tax_rates = $WC_Tax->find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => ''));
     if ($tax_rates) {
         foreach ($tax_rates as $key => $rate) {
             if (isset($rate['shipping']) && 'yes' === $rate['shipping']) {
                 $matched_tax_rates[$key] = $rate;
             }
         }
     }
     $vendor_shipping_taxes = $WC_Tax->calc_shipping_tax($shipping_amount, $matched_tax_rates);
     $vendor_shipping_tax_total = $WC_Tax->round(array_sum($vendor_shipping_taxes));
     return $vendor_shipping_tax_total;
 }
 /**
  * Returns the price (excluding tax) - ignores tax_class filters since the price may *include* tax and thus needs subtracting.
  * Uses store base tax rates. Can work for a specific $qty for more accurate taxes.
  *
  * @param  string $price to calculate, left blank to just use get_price()
  * @return string
  */
 public function get_price_excluding_tax($qty = 1, $price = '')
 {
     if ($price === '') {
         $price = $this->get_price();
     }
     if ($this->is_taxable() && get_option('woocommerce_prices_include_tax') === 'yes') {
         $tax_rates = WC_Tax::get_base_tax_rates($this->tax_class);
         $taxes = WC_Tax::calc_tax($price * $qty, $tax_rates, true);
         $price = WC_Tax::round($price * $qty - array_sum($taxes));
     } else {
         $price = $price * $qty;
     }
     return apply_filters('woocommerce_get_price_excluding_tax', $price, $qty, $this);
 }
 public static function woocommerce_get_variation_price($price, $product, $min_or_max, $display)
 {
     global $post, $woocommerce;
     $baseprice = $price;
     $result = $baseprice;
     if ($post == null || !is_admin()) {
         $variation_id = get_post_meta($product->id, '_' . $min_or_max . '_price_variation_id', true);
         if (!$variation_id) {
             return false;
         }
         $price = get_post_meta($variation_id, '_price', true);
         $result = $price;
         if ($display) {
             $variation = $product->get_child($variation_id);
             $commission = self::get_commission($product, $variation_id);
             if ($commission) {
                 $baseprice = $variation->get_regular_price();
                 if ($variation->get_sale_price() != $variation->get_regular_price() && $variation->get_sale_price() == $variation->price) {
                     if (get_option("wrp-baseprice", "regular") == "sale") {
                         $baseprice = $variation->get_sale_price();
                     }
                 }
                 $product_price = $baseprice;
                 $type = get_option("wrp-method", "rate");
                 $result = 0;
                 if ($type == "rate") {
                     // if rate and price includes taxes
                     if ($variation->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
                         $_tax = new WC_Tax();
                         $tax_rates = $_tax->get_shop_base_rate($variation->tax_class);
                         $taxes = $_tax->calc_tax($baseprice, $tax_rates, true);
                         $product_price = $_tax->round($baseprice - array_sum($taxes));
                     }
                     $result = WooRolePricing::bcmul($product_price, $commission, WOO_ROLE_PRICING_DECIMALS);
                     if ($variation->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
                         $_tax = new WC_Tax();
                         $tax_rates = $_tax->get_shop_base_rate($variation->tax_class);
                         $taxes = $_tax->calc_tax($result, $tax_rates, false);
                         // important false
                         $result = $_tax->round($result + array_sum($taxes));
                     }
                 } else {
                     $result = WooRolePricing::bcsub($product_price, $commission, WOO_ROLE_PRICING_DECIMALS);
                 }
             }
         }
     }
     return $result;
 }