/** * Create a order. * * @since 2.4 * * @return WC_Order Order object. */ public static function create_order() { // Create product $product = WC_Helper_Product::create_simple_product(); WC_Helper_Shipping::create_simple_flat_rate(); $order_data = array('status' => 'pending', 'customer_id' => 1, 'customer_note' => '', 'total' => ''); $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // Required, else wc_create_order throws an exception $order = wc_create_order($order_data); // Add order products $item_id = $order->add_product($product, 4); // Set billing address $billing_address = array('country' => 'US', 'first_name' => 'Jeroen', 'last_name' => 'Sormani', 'company' => 'WooCompany', 'address_1' => 'WooAddress', 'address_2' => '', 'postcode' => '123456', 'city' => 'WooCity', 'state' => 'NY', 'email' => '*****@*****.**', 'phone' => '555-32123'); $order->set_address($billing_address, 'billing'); // Add shipping costs $shipping_taxes = WC_Tax::calc_shipping_tax('10', WC_Tax::get_shipping_tax_rates()); $order->add_shipping(new WC_Shipping_Rate('flat_rate_shipping', 'Flat rate shipping', '10', $shipping_taxes, 'flat_rate')); // Set payment gateway $payment_gateways = WC()->payment_gateways->payment_gateways(); $order->set_payment_method($payment_gateways['bacs']); // Set totals $order->set_total(10, 'shipping'); $order->set_total(0, 'cart_discount'); $order->set_total(0, 'cart_discount_tax'); $order->set_total(0, 'tax'); $order->set_total(0, 'shipping_tax'); $order->set_total(40, 'total'); // 4 x $10 simple helper product return wc_get_order($order->id); }
/** * Create a order. * * @since 2.4 * * @return WC_Order Order object. */ public static function create_order($customer_id = 1) { // Create product $product = WC_Helper_Product::create_simple_product(); WC_Helper_Shipping::create_simple_flat_rate(); $order_data = array('status' => 'pending', 'customer_id' => $customer_id, 'customer_note' => '', 'total' => ''); $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // Required, else wc_create_order throws an exception $order = wc_create_order($order_data); // Add order products $order->add_product($product, 4); // Set billing address $order->set_billing_first_name('Jeroen'); $order->set_billing_last_name('Sormani'); $order->set_billing_company('WooCompany'); $order->set_billing_address_1('WooAddress'); $order->set_billing_address_2(''); $order->set_billing_city('WooCity'); $order->set_billing_state('NY'); $order->set_billing_postcode('123456'); $order->set_billing_country('US'); $order->set_billing_email('*****@*****.**'); $order->set_billing_phone('555-32123'); // Add shipping costs $shipping_taxes = WC_Tax::calc_shipping_tax('10', WC_Tax::get_shipping_tax_rates()); $rate = new WC_Shipping_Rate('flat_rate_shipping', 'Flat rate shipping', '10', $shipping_taxes, 'flat_rate'); $item = new WC_Order_Item_Shipping(); $item->set_props(array('method_title' => $rate->label, 'method_id' => $rate->id, 'total' => wc_format_decimal($rate->cost), 'taxes' => $rate->taxes, 'meta_data' => $rate->get_meta_data())); $order->add_item($item); // Set payment gateway $payment_gateways = WC()->payment_gateways->payment_gateways(); $order->set_payment_method($payment_gateways['bacs']); // Set totals $order->set_shipping_total(10); $order->set_discount_total(0); $order->set_discount_tax(0); $order->set_cart_tax(0); $order->set_shipping_tax(0); $order->set_total(40); // 4 x $10 simple helper product $order->save(); return $order; }
/** * Add a rate * * A a shipping rate. If taxes are not set they will be calculated based on cost. */ function add_rate($args = array()) { global $woocommerce; $defaults = array('id' => '', 'label' => '', 'cost' => '0', 'taxes' => '', 'calc_tax' => 'per_order'); $args = wp_parse_args($args, $defaults); extract($args); // Id and label are required if (!$id || !$label) { return; } // Handle cost $total_cost = is_array($cost) ? array_sum($cost) : $cost; // Taxes - if not an array and not set to false, calc tax based on cost and passed calc_tax variable // This saves shipping methods having to do compelex tax calculations if (!is_array($taxes) && $taxes !== false && $total_cost > 0 && get_option('woocommerce_calc_taxes') == 'yes' && $this->tax_status == 'taxable') { $_tax = new WC_Tax(); $taxes = array(); switch ($calc_tax) { case "per_item": // If we have an array of costs we can look up each items tax class and add tax accordingly if (is_array($cost)) { $cart = $woocommerce->cart->get_cart(); foreach ($cost as $cost_key => $amount) { if (!isset($cart[$cost_key])) { continue; } $_product = $cart[$cost_key]['data']; $rates = $_tax->get_shipping_tax_rates($_product->get_tax_class()); $item_taxes = $_tax->calc_shipping_tax($amount, $rates); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } // Add any cost for the order - order costs are in the key 'order' if (isset($cost['order'])) { $rates = $_tax->get_shipping_tax_rates(); $item_taxes = $_tax->calc_shipping_tax($cost['order'], $rates); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } } break; default: $rates = $_tax->get_shipping_tax_rates(); $taxes = $_tax->calc_shipping_tax($total_cost, $rates); break; } } $this->rates[] = new WC_Shipping_Rate($id, $label, $total_cost, $taxes); }
/** * Calculate shipping when this method is used standalone. */ public function calculate_shipping($package) { $_tax = new WC_Tax(); $taxes = array(); $shipping_cost = 0; // This shipping method loops through products, adding up the cost if (sizeof($package['contents']) > 0) { foreach ($package['contents'] as $item_id => $values) { if ($values['quantity'] > 0) { if ($values['data']->needs_shipping()) { $rule = false; $item_shipping_cost = 0; if ($values['variation_id']) { $rule = woocommerce_per_product_shipping_get_matching_rule($values['variation_id'], $package); } if ($rule === false) { $rule = woocommerce_per_product_shipping_get_matching_rule($values['product_id'], $package); } if ($rule) { $item_shipping_cost += $rule->rule_item_cost * $values['quantity']; $item_shipping_cost += $rule->rule_cost; } elseif ($this->cost === '0' || $this->cost > 0) { // Use default $item_shipping_cost += $this->cost * $values['quantity']; } else { // NO default and nothing found - abort return; } // Fee $item_shipping_cost += $this->get_fee($this->fee, $item_shipping_cost) * $values['quantity']; $shipping_cost += $item_shipping_cost; if (get_option('woocommerce_calc_taxes') == 'yes' && $this->tax_status == 'taxable') { $rates = $_tax->get_shipping_tax_rates($values['data']->get_tax_class()); $item_taxes = $_tax->calc_shipping_tax($item_shipping_cost, $rates); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } } } } } // Add order shipping cost + tax if ($this->order_fee) { $order_fee = $this->get_fee($this->order_fee, $shipping_cost); $shipping_cost += $order_fee; if (get_option('woocommerce_calc_taxes') == 'yes' && $this->tax_status == 'taxable') { $rates = $_tax->get_shipping_tax_rates(); $item_taxes = $_tax->calc_shipping_tax($order_fee, $rates); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } } // Add rate $this->add_rate(array('id' => $this->id, 'label' => $this->title, 'cost' => $shipping_cost, 'taxes' => $taxes)); }
/** * 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; }
/** * Shipping tax amounts. */ public function test_calc_shipping_tax() { global $wpdb; $wpdb->query("DELETE FROM {$wpdb->prefix}woocommerce_tax_rates"); $wpdb->query("DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations"); $tax_rate = array('tax_rate_country' => 'GB', 'tax_rate_state' => '', 'tax_rate' => '20.0000', 'tax_rate_name' => 'VAT', 'tax_rate_priority' => '1', 'tax_rate_compound' => '0', 'tax_rate_shipping' => '1', 'tax_rate_order' => '1', 'tax_rate_class' => ''); $tax_rate_id = WC_Tax::_insert_tax_rate($tax_rate); $tax_rates = WC_Tax::find_rates(array('country' => 'GB', 'state' => 'Cambs', 'postcode' => 'PE14 1XX', 'city' => 'Somewhere', 'tax_class' => '')); $calced_tax = WC_Tax::calc_shipping_tax('10', $tax_rates); $this->assertEquals($calced_tax, array($tax_rate_id => '2')); WC_Tax::_delete_tax_rate($tax_rate_id); }
/** * Calculate taxes for all line items and shipping, and store the totals and tax rows. * * Will use the base country unless customer addresses are set. * * @return bool success or fail */ public function calculate_taxes() { $tax_total = 0; $taxes = array(); $tax_based_on = get_option('woocommerce_tax_based_on'); if ('billing' === $tax_based_on) { $country = $this->billing_country; $state = $this->billing_state; $postcode = $this->billing_postcode; $city = $this->billing_city; } elseif ('shipping' === $tax_based_on) { $country = $this->shipping_country; $state = $this->shipping_state; $postcode = $this->shipping_postcode; $city = $this->shipping_city; } // Default to base if ('base' === $tax_based_on || empty($country)) { $default = wc_get_base_location(); $country = $default['country']; $state = $default['state']; $postcode = ''; $city = ''; } // Get items foreach ($this->get_items(array('line_item', 'fee')) as $item_id => $item) { $product = $this->get_product_from_item($item); $line_total = isset($item['line_total']) ? $item['line_total'] : 0; $line_subtotal = isset($item['line_subtotal']) ? $item['line_subtotal'] : 0; $tax_class = $item['tax_class']; $item_tax_status = $product ? $product->get_tax_status() : 'taxable'; if ('0' !== $tax_class && 'taxable' === $item_tax_status) { $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class)); $line_subtotal_taxes = WC_Tax::calc_tax($line_subtotal, $tax_rates, false); $line_taxes = WC_Tax::calc_tax($line_total, $tax_rates, false); $line_subtotal_tax = max(0, array_sum($line_subtotal_taxes)); $line_tax = max(0, array_sum($line_taxes)); $tax_total += $line_tax; wc_update_order_item_meta($item_id, '_line_subtotal_tax', wc_format_decimal($line_subtotal_tax)); wc_update_order_item_meta($item_id, '_line_tax', wc_format_decimal($line_tax)); wc_update_order_item_meta($item_id, '_line_tax_data', array('total' => $line_taxes, 'subtotal' => $line_subtotal_taxes)); // 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 = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => '')); if (!empty($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($this->order_shipping, $matched_tax_rates); $shipping_tax_total = WC_Tax::round(array_sum($shipping_taxes)); // Save tax totals $this->set_total($shipping_tax_total, 'shipping_tax'); $this->set_total($tax_total, 'tax'); // Tax rows $this->remove_order_items('tax'); // Now merge to keep tax rows foreach (array_keys($taxes + $shipping_taxes) as $tax_rate_id) { $this->add_tax($tax_rate_id, isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0, isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] : 0); } return true; }
/** * Calc taxes per item being shipping in costs array. * @since 2.6.0 * @access protected * @param array $costs * @return array of taxes */ protected function get_taxes_per_item($costs) { $taxes = array(); // If we have an array of costs we can look up each items tax class and add tax accordingly if (is_array($costs)) { $cart = WC()->cart->get_cart(); foreach ($costs as $cost_key => $amount) { if (!isset($cart[$cost_key])) { continue; } $item_taxes = WC_Tax::calc_shipping_tax($amount, WC_Tax::get_shipping_tax_rates($cart[$cost_key]['data']->get_tax_class())); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } // Add any cost for the order - order costs are in the key 'order' if (isset($costs['order'])) { $item_taxes = WC_Tax::calc_shipping_tax($costs['order'], WC_Tax::get_shipping_tax_rates()); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } } return $taxes; }
/** * 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; }
/** * woocommerce_per_product_shipping_addition function. * * @access public * @return void */ function woocommerce_per_product_shipping_addition($rates, $package) { global $woocommerce; $_tax = new WC_Tax(); if ($rates) { foreach ($rates as $rate_id => $rate) { // Skip free shipping if ($rate->cost == 0 && apply_filters('woocommerce_per_product_shipping_skip_free_method_' . $rate->method_id, true)) { continue; } // Skip self if ($rate->method_id == 'per_product') { continue; } if (sizeof($package['contents']) > 0) { foreach ($package['contents'] as $item_id => $values) { if ($values['quantity'] > 0) { if ($values['data']->needs_shipping()) { $item_shipping_cost = 0; $rule = false; if ($values['variation_id']) { $rule = woocommerce_per_product_shipping_get_matching_rule($values['variation_id'], $package, false); } if ($rule === false) { $rule = woocommerce_per_product_shipping_get_matching_rule($values['product_id'], $package, false); } if (empty($rule)) { continue; } $item_shipping_cost += $rule->rule_item_cost * $values['quantity']; $item_shipping_cost += $rule->rule_cost; $rate->cost += $item_shipping_cost; if ($woocommerce->shipping->shipping_methods[$rate->method_id]->tax_status == 'taxable') { $tax_rates = $_tax->get_shipping_tax_rates($values['data']->get_tax_class()); $item_taxes = $_tax->calc_shipping_tax($item_shipping_cost, $tax_rates); // Sum the item taxes foreach (array_keys($rate->taxes + $item_taxes) as $key) { $rate->taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($rate->taxes[$key]) ? $rate->taxes[$key] : 0); } } } } } } } } return $rates; }
/** * Add a rate * * Add a shipping rate. If taxes are not set they will be calculated based on cost. * * @param array $args (default: array()) */ public function add_rate($args = array()) { $args = wp_parse_args($args, array('id' => '', 'label' => '', 'cost' => '0', 'taxes' => '', 'calc_tax' => 'per_order')); // Id and label are required if (!$args['id'] || !$args['label']) { return; } // Handle cost $total_cost = is_array($args['cost']) ? array_sum($args['cost']) : $args['cost']; $taxes = $args['taxes']; // Taxes - if not an array and not set to false, calc tax based on cost and passed calc_tax variable // This saves shipping methods having to do complex tax calculations if (!is_array($taxes) && $taxes !== false && $total_cost > 0 && $this->is_taxable()) { $taxes = array(); switch ($args['calc_tax']) { case "per_item": // If we have an array of costs we can look up each items tax class and add tax accordingly if (is_array($args['cost'])) { $cart = WC()->cart->get_cart(); foreach ($args['cost'] as $cost_key => $amount) { if (!isset($cart[$cost_key])) { continue; } $item_taxes = WC_Tax::calc_shipping_tax($amount, WC_Tax::get_shipping_tax_rates($cart[$cost_key]['data']->get_tax_class())); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } // Add any cost for the order - order costs are in the key 'order' if (isset($args['cost']['order'])) { $item_taxes = WC_Tax::calc_shipping_tax($args['cost']['order'], WC_Tax::get_shipping_tax_rates()); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } } break; default: $taxes = WC_Tax::calc_shipping_tax($total_cost, WC_Tax::get_shipping_tax_rates()); break; } } $this->rates[] = new WC_Shipping_Rate($args['id'], $args['label'], $total_cost, $taxes, $this->id); }
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; }
/** * 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; }
/** * Calc line tax */ public static function calc_line_taxes() { global $wpdb; check_ajax_referer('calc-totals', 'security'); if (!current_user_can('edit_shop_orders')) { die(-1); } $tax = new WC_Tax(); $order_id = absint($_POST['order_id']); $items = array(); $country = strtoupper(esc_attr($_POST['country'])); $state = strtoupper(esc_attr($_POST['state'])); $postcode = strtoupper(esc_attr($_POST['postcode'])); $city = wc_clean(esc_attr($_POST['city'])); $order = wc_get_order($order_id); $taxes = array(); $shipping_taxes = array(); // Parse the jQuery serialized items parse_str($_POST['items'], $items); // Prevent undefined warnings if (!isset($items['line_tax'])) { $items['line_tax'] = array(); } if (!isset($items['line_subtotal_tax'])) { $items['line_subtotal_tax'] = array(); } $items['order_taxes'] = array(); // Action $items = apply_filters('woocommerce_ajax_calc_line_taxes', $items, $order_id, $country, $_POST); // Get items and fees taxes if (isset($items['order_item_id'])) { $line_total = $line_subtotal = $order_item_tax_class = array(); foreach ($items['order_item_id'] as $item_id) { $item_id = absint($item_id); $line_total[$item_id] = isset($items['line_total'][$item_id]) ? wc_format_decimal($items['line_total'][$item_id]) : 0; $line_subtotal[$item_id] = isset($items['line_subtotal'][$item_id]) ? wc_format_decimal($items['line_subtotal'][$item_id]) : $line_total[$item_id]; $order_item_tax_class[$item_id] = isset($items['order_item_tax_class'][$item_id]) ? sanitize_text_field($items['order_item_tax_class'][$item_id]) : ''; $product_id = $order->get_item_meta($item_id, '_product_id', true); // Get product details if (get_post_type($product_id) == 'product') { $_product = wc_get_product($product_id); $item_tax_status = $_product->get_tax_status(); } else { $item_tax_status = 'taxable'; } if ('0' !== $order_item_tax_class[$item_id] && 'taxable' === $item_tax_status) { $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $order_item_tax_class[$item_id])); $line_taxes = WC_Tax::calc_tax($line_total[$item_id], $tax_rates, false); $line_subtotal_taxes = WC_Tax::calc_tax($line_subtotal[$item_id], $tax_rates, false); // Set the new line_tax foreach ($line_taxes as $_tax_id => $_tax_value) { $items['line_tax'][$item_id][$_tax_id] = $_tax_value; } // Set the new line_subtotal_tax foreach ($line_subtotal_taxes as $_tax_id => $_tax_value) { $items['line_subtotal_tax'][$item_id][$_tax_id] = $_tax_value; } // 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); } } } } // Get shipping taxes if (isset($items['shipping_method_id'])) { $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_cost = $shipping_taxes = array(); foreach ($items['shipping_method_id'] as $item_id) { $item_id = absint($item_id); $shipping_cost[$item_id] = isset($items['shipping_cost'][$item_id]) ? wc_format_decimal($items['shipping_cost'][$item_id]) : 0; $_shipping_taxes = WC_Tax::calc_shipping_tax($shipping_cost[$item_id], $matched_tax_rates); // Set the new shipping_taxes foreach ($_shipping_taxes as $_tax_id => $_tax_value) { $items['shipping_taxes'][$item_id][$_tax_id] = $_tax_value; $shipping_taxes[$_tax_id] = isset($shipping_taxes[$_tax_id]) ? $shipping_taxes[$_tax_id] + $_tax_value : $_tax_value; } } } // Remove old tax rows $order->remove_order_items('tax'); // Add tax rows foreach (array_keys($taxes + $shipping_taxes) as $tax_rate_id) { $order->add_tax($tax_rate_id, isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0, isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] : 0); } // Create the new order_taxes foreach ($order->get_taxes() as $tax_id => $tax_item) { $items['order_taxes'][$tax_id] = absint($tax_item['rate_id']); } // Save order items wc_save_order_items($order_id, $items); // Return HTML items $order = wc_get_order($order_id); $data = get_post_meta($order_id); include 'admin/meta-boxes/views/html-order-items.php'; die; }
public static function add_line_taxes($order_id) { global $wpdb; check_ajax_referer('calc-totals', 'security'); if (!current_user_can('edit_shop_orders')) { die(-1); } $tax = new WC_Tax(); $items = array(); $country = strtoupper(esc_attr($_POST['country'])); $state = strtoupper(esc_attr($_POST['state'])); $postcode = strtoupper(esc_attr($_POST['postcode'])); $city = wc_clean(esc_attr($_POST['city'])); $order = wc_get_order(absint($order_id)); $taxes = array(); $shipping_taxes = array(); // Parse the jQuery serialized items parse_str($_POST['items'], $items); // Prevent undefined warnings if (!isset($items['line_tax'])) { $items['line_tax'] = array(); } if (!isset($items['line_subtotal_tax'])) { $items['line_subtotal_tax'] = array(); } $items['order_taxes'] = array(); // Action $items = apply_filters('woocommerce_ajax_calc_line_taxes', $items, $order_id, $country, $_POST); // Get items and fees taxes if (isset($items['order_item_id'])) { $line_total = $line_subtotal = $order_item_tax_class = array(); foreach ($items['order_item_id'] as $parent_item_id) { $parent_item_id = absint($parent_item_id); $item_id = self::get_child_item_id($parent_item_id); if (empty($item_id)) { //no current suborder items continue; } $line_total[$item_id] = isset($items['line_total'][$parent_item_id]) ? wc_format_decimal($items['line_total'][$parent_item_id]) : 0; $line_subtotal[$item_id] = isset($items['line_subtotal'][$parent_item_id]) ? wc_format_decimal($items['line_subtotal'][$parent_item_id]) : $line_total[$parent_item_id]; $order_item_tax_class[$item_id] = isset($items['order_item_tax_class'][$parent_item_id]) ? sanitize_text_field($items['order_item_tax_class'][$parent_item_id]) : ''; $product_id = $order->get_item_meta($item_id, '_product_id', true); $vendor = yith_get_vendor($product_id, 'product'); if (!$vendor->is_valid()) { // no vnedor products continue; } $vendor_order_ids = $vendor->get_orders('suborder'); if (!in_array($order_id, $vendor_order_ids)) { // the current product isn't in the current suborder continue; } // Get product details if (get_post_type($product_id) == 'product') { $_product = wc_get_product($product_id); $item_tax_status = $_product->get_tax_status(); } else { $item_tax_status = 'taxable'; } if ('0' !== $order_item_tax_class[$item_id] && 'taxable' === $item_tax_status) { $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $order_item_tax_class[$item_id])); $line_taxes = WC_Tax::calc_tax($line_total[$item_id], $tax_rates, false); $line_subtotal_taxes = WC_Tax::calc_tax($line_subtotal[$item_id], $tax_rates, false); // Set the new line_tax foreach ($line_taxes as $_tax_id => $_tax_value) { $items['line_tax'][$item_id][$_tax_id] = $_tax_value; } // Set the new line_subtotal_tax foreach ($line_subtotal_taxes as $_tax_id => $_tax_value) { $items['line_subtotal_tax'][$item_id][$_tax_id] = $_tax_value; } // 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); } } } } // Get shipping taxes if (isset($items['shipping_method_id'])) { $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_cost = $shipping_taxes = array(); foreach ($items['shipping_method_id'] as $item_id) { $item_id = absint($item_id); $shipping_cost[$item_id] = isset($items['shipping_cost'][$parent_item_id]) ? wc_format_decimal($items['shipping_cost'][$parent_item_id]) : 0; $_shipping_taxes = WC_Tax::calc_shipping_tax($shipping_cost[$item_id], $matched_tax_rates); // Set the new shipping_taxes foreach ($_shipping_taxes as $_tax_id => $_tax_value) { $items['shipping_taxes'][$item_id][$_tax_id] = $_tax_value; $shipping_taxes[$_tax_id] = isset($shipping_taxes[$_tax_id]) ? $shipping_taxes[$_tax_id] + $_tax_value : $_tax_value; } } } // Remove old tax rows $order->remove_order_items('tax'); // Add tax rows foreach (array_keys($taxes + $shipping_taxes) as $tax_rate_id) { $order->add_tax($tax_rate_id, isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0, isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] : 0); } // Create the new order_taxes foreach ($order->get_taxes() as $tax_id => $tax_item) { $items['order_taxes'][$tax_id] = absint($tax_item['rate_id']); } foreach ($items as $meta_key => $meta_values) { if (is_array($meta_values)) { foreach ($meta_values as $key => $meta_value) { if ('order_taxes' == $meta_key) { continue; } else { if ('order_item_id' == $meta_key) { $child_item_id = self::get_child_item_id($meta_value); if ($child_item_id) { $items[$meta_key][$key] = $child_item_id; } else { unset($items[$meta_key][$key]); } } else { if ('meta_key' == $meta_key || 'meta_value' == $meta_key) { unset($items[$meta_key][$key]); } else { if ('line_tax' == $meta_key || 'line_subtotal_tax' == $meta_key || 'refund_line_tax' == $meta_key) { $line_tax_ids = $items[$meta_key]; $child_item_ids = array_keys($order->get_items()); foreach ($line_tax_ids as $line_tax_id => $line_tax_value) { if (!in_array($line_tax_id, $child_item_ids)) { unset($items[$meta_key][$line_tax_id]); } } } else { $child_item_id = self::get_child_item_id($meta_value); if ($child_item_id) { $items[$meta_key][$child_item_id] = $items[$meta_key][$key]; unset($items[$meta_key][$key]); } } } } } } } else { if ('_order_total' == $meta_key) { $items['_order_total'] = $order->get_total(); } } } if (!empty($items['order_item_id'])) { wc_save_order_items($order_id, $items); } }
function calculate_shipping($paquete = array()) { //Peso total del pedido $peso_total = WC()->cart->cart_contents_weight; //Variables $volumen = $largo = $ancho = $alto = 0; $clases = $medidas = array(); //Toma distintos datos de los productos foreach (WC()->cart->get_cart() as $identificador => $valores) { $producto = $valores['data']; $peso = $producto->get_weight() * $valores['quantity']; //Arregla un problema con los pesos en variaciones virtuales if ($producto->is_virtual()) { $peso_total -= $peso; } //Medidas y volúmenes if ($producto->length && $producto->width && $producto->height) { $volumen += $producto->length * $producto->width * $producto->height * $valores['quantity']; } $medidas[] = array('largo' => $producto->length, 'ancho' => $producto->width, 'alto' => $producto->height, 'cantidad' => $valores['quantity']); if ($producto->length > $largo) { $largo = $producto->length; } if ($producto->width > $ancho) { $ancho = $producto->width; } if ($producto->height > $alto) { $alto = $producto->height; } //Clase de producto if ($producto->needs_shipping()) { $clase = $producto->get_shipping_class() ? $producto->get_shipping_class() : 'todas'; if (!isset($clases['todas'])) { $clases['todas'] = 0; } $clases['todas'] += $peso; if (!isset($clases[$clase])) { $clases[$clase] = $peso; } else { if ($clase != 'todas') { $clases[$clase] += $peso; } } } } if ($this->clases_excluidas) { //Toma distintos datos de los productos foreach (WC()->cart->get_cart() as $identificador => $valores) { $producto = $valores['data']; //Clase de producto if (in_array($producto->get_shipping_class(), $this->clases_excluidas)) { return false; //No atiende a las clases de envío excluidas } } } $grupos = $this->dame_grupos($paquete, $clases); if (empty($grupos)) { return false; //No hay resultados } $grupos_excluidos = explode(',', preg_replace('/\\s+/', '', $this->grupos_excluidos)); foreach ($grupos_excluidos as $grupo_excluido) { if (in_array($grupo_excluido, $grupos)) { return false; //No atiende a los grupos excluidos } } if ($this->apg_free_shipping && $this->muestra == 'yes') { return false; //Sólo muestra el envío gratuito } $tarifas = $this->dame_tarifas($grupos); //Recoge las tarifas programadas $precios = $this->dame_tarifa_mas_barata($tarifas, $peso_total, $volumen, $largo, $ancho, $alto, $grupos, $medidas, $clases); //Filtra las tarifas if (empty($precios)) { return false; //No hay tarifa } //Calculamos el precio $precio_total = $suma_impuestos = $suma_cargos = 0; $impuestos_parciales = $impuestos_totales = array(); if ($this->tax_status != 'none') { $impuestos = new WC_Tax(); } //Cargos adicionales if ($this->fee > 0) { $suma_cargos += $this->fee; } if ($this->cargo > 0 && !strpos($this->cargo, '%')) { $suma_cargos += $this->cargo; } foreach ($precios as $grupo => $precio) { if ($this->cargo > 0 && strpos($this->cargo, '%')) { $suma_cargos += $precio * (str_replace('%', '', $this->cargo) / 100); //Cargos adicionales } $precio += $suma_cargos; $precio_total += $precio; if ($this->tax_status != 'none') { $impuestos_parciales[$grupo] = $impuestos->calc_shipping_tax($precio, $impuestos->get_shipping_tax_rates($this->settings['Tax_' . $grupo])); } } if ($this->tax_status != 'none') { foreach ($impuestos_parciales as $impuesto_parcial) { foreach ($impuesto_parcial as $clave => $impuesto) { $suma_impuestos += $impuesto; $impuestos_totales[$clave] = $suma_impuestos; } } } $tarifa = array('id' => $this->id, 'label' => $this->title, 'cost' => $precio_total, 'taxes' => $impuestos_totales, 'calc_tax' => 'per_order'); $this->add_rate($tarifa); }
/** * Calc line tax. */ public static function calc_line_taxes() { global $wpdb; check_ajax_referer('calc-totals', 'security'); if (!current_user_can('edit_shop_orders')) { die(-1); } $tax = new WC_Tax(); $tax_based_on = get_option('woocommerce_tax_based_on'); $order_id = absint($_POST['order_id']); $items = array(); $country = strtoupper(esc_attr($_POST['country'])); $state = strtoupper(esc_attr($_POST['state'])); $postcode = strtoupper(esc_attr($_POST['postcode'])); $city = wc_clean(esc_attr($_POST['city'])); $order = wc_get_order($order_id); $taxes = array(); $shipping_taxes = array(); $order_item_tax_classes = array(); // Default to base if ('base' === $tax_based_on || empty($country)) { $default = wc_get_base_location(); $country = $default['country']; $state = $default['state']; $postcode = ''; $city = ''; } // Parse the jQuery serialized items parse_str($_POST['items'], $items); // Prevent undefined warnings if (!isset($items['line_tax'])) { $items['line_tax'] = array(); } if (!isset($items['line_subtotal_tax'])) { $items['line_subtotal_tax'] = array(); } $items['order_taxes'] = array(); // Action $items = apply_filters('woocommerce_ajax_calc_line_taxes', $items, $order_id, $country, $_POST); $is_vat_exempt = get_post_meta($order_id, '_is_vat_exempt', true); // Tax is calculated only if tax is enabled and order is not vat exempted if (wc_tax_enabled() && $is_vat_exempt !== 'yes') { // Get items and fees taxes if (isset($items['order_item_id'])) { $line_total = $line_subtotal = array(); foreach ($items['order_item_id'] as $item_id) { $item_id = absint($item_id); $line_total[$item_id] = isset($items['line_total'][$item_id]) ? wc_format_decimal($items['line_total'][$item_id]) : 0; $line_subtotal[$item_id] = isset($items['line_subtotal'][$item_id]) ? wc_format_decimal($items['line_subtotal'][$item_id]) : $line_total[$item_id]; $order_item_tax_classes[$item_id] = isset($items['order_item_tax_class'][$item_id]) ? sanitize_text_field($items['order_item_tax_class'][$item_id]) : ''; $product_id = $order->get_item_meta($item_id, '_product_id', true); // Get product details if (get_post_type($product_id) == 'product') { $_product = wc_get_product($product_id); $item_tax_status = $_product->get_tax_status(); } else { $item_tax_status = 'taxable'; } if ('0' !== $order_item_tax_classes[$item_id] && 'taxable' === $item_tax_status) { $tax_rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $order_item_tax_classes[$item_id])); $line_taxes = WC_Tax::calc_tax($line_total[$item_id], $tax_rates, false); $line_subtotal_taxes = WC_Tax::calc_tax($line_subtotal[$item_id], $tax_rates, false); // Set the new line_tax foreach ($line_taxes as $_tax_id => $_tax_value) { $items['line_tax'][$item_id][$_tax_id] = $_tax_value; } // Set the new line_subtotal_tax foreach ($line_subtotal_taxes as $_tax_id => $_tax_value) { $items['line_subtotal_tax'][$item_id][$_tax_id] = $_tax_value; } // 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); } } } } // Get shipping taxes if (isset($items['shipping_method_id'])) { $matched_tax_rates = array(); $order_item_tax_classes = array_unique(array_values($order_item_tax_classes)); // If multiple classes are found, use the first one. Don't bother with standard rate, we can get that later. if (sizeof($order_item_tax_classes) > 1 && !in_array('', $order_item_tax_classes)) { $tax_classes = WC_Tax::get_tax_classes(); foreach ($tax_classes as $tax_class) { $tax_class = sanitize_title($tax_class); if (in_array($tax_class, $order_item_tax_classes)) { $matched_tax_rates = WC_Tax::find_shipping_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class)); break; } } // If a single tax class is found, use it } elseif (sizeof($order_item_tax_classes) === 1) { $matched_tax_rates = WC_Tax::find_shipping_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $order_item_tax_classes[0])); } // Get standard rate if no taxes were found if (!sizeof($matched_tax_rates)) { $matched_tax_rates = WC_Tax::find_shipping_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city)); } $shipping_cost = $shipping_taxes = array(); foreach ($items['shipping_method_id'] as $item_id) { $item_id = absint($item_id); $shipping_cost[$item_id] = isset($items['shipping_cost'][$item_id]) ? wc_format_decimal($items['shipping_cost'][$item_id]) : 0; $_shipping_taxes = WC_Tax::calc_shipping_tax($shipping_cost[$item_id], $matched_tax_rates); // Set the new shipping_taxes foreach ($_shipping_taxes as $_tax_id => $_tax_value) { $items['shipping_taxes'][$item_id][$_tax_id] = $_tax_value; $shipping_taxes[$_tax_id] = isset($shipping_taxes[$_tax_id]) ? $shipping_taxes[$_tax_id] + $_tax_value : $_tax_value; } } } } // Remove old tax rows $order->remove_order_items('tax'); // Add tax rows foreach (array_keys($taxes + $shipping_taxes) as $tax_rate_id) { $order->add_tax($tax_rate_id, isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0, isset($shipping_taxes[$tax_rate_id]) ? $shipping_taxes[$tax_rate_id] : 0); } // Create the new order_taxes foreach ($order->get_taxes() as $tax_id => $tax_item) { $items['order_taxes'][$tax_id] = absint($tax_item['rate_id']); } $items = apply_filters('woocommerce_ajax_after_calc_line_taxes', $items, $order_id, $country, $_POST); // Save order items wc_save_order_items($order_id, $items); // Return HTML items $order = wc_get_order($order_id); $data = get_post_meta($order_id); include 'admin/meta-boxes/views/html-order-items.php'; die; }
public static function createSimpleOrder($total = 40) { $product = self::createSimpleProduct(); self::createSimpleShippingFlatRate(); $order_data = array('status' => 'pending', 'customer_id' => 1, 'customer_note' => '', 'total' => ''); // Required, else wc_create_order throws an exception $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $order = wc_create_order($order_data); // Add order products $order->add_product($product, 4); // Set billing address $shipping_address = array('country' => 'US', 'first_name' => 'Jeroen', 'last_name' => 'Sormani', 'company' => 'WooCompany', 'address_1' => 'WooAddress', 'address_2' => '', 'postcode' => '123456', 'city' => 'WooCity', 'state' => 'NY', 'email' => '*****@*****.**', 'phone' => '555-32123'); $order->set_address($shipping_address, 'shipping'); // Add shipping costs $shipping_taxes = \WC_Tax::calc_shipping_tax('10', \WC_Tax::get_shipping_tax_rates()); $order->add_shipping(new \WC_Shipping_Rate('flagship_shipping_method|Purolator|PurolatorExpress|Purolator Express|1473811200', 'Purolator - Purolator Express', '10', $shipping_taxes, 'flagship_shipping_method')); // Set totals $order->set_total(10, 'shipping'); $order->set_total(0, 'cart_discount'); $order->set_total(0, 'cart_discount_tax'); $order->set_total(0, 'tax'); $order->set_total(0, 'shipping_tax'); $order->set_total($total, 'total'); // 4 x $10 simple helper product return wc_get_order($order->id); }