/** * Whenever a WooCommerce tax rate is saved, also save the tax rate's hidden status. * * Executed whenever a WooCommerce tax rate is added, updated or deleted. * * @param int $tax_rate_id The WooCommerce Tax Rate ID. */ public function save_tax_rate_hidden_status() { // nonce and cap checks are copied from WC_AJAX::tax_rates_save_changes() // Use return instead of exit so that WooCommerce core will handle the AJAX error messages if (!isset($_POST['wc_tax_nonce'], $_POST['changes'])) { return; } $current_class = !empty($_POST['current_class']) ? $_POST['current_class'] : ''; // This is sanitized seven lines later. if (!wp_verify_nonce($_POST['wc_tax_nonce'], 'wc_tax_nonce-class:' . $current_class)) { return; } // Check User Caps if (!current_user_can('manage_woocommerce')) { return; } $hidden_rates = array(); $current_class = WC_Tax::format_tax_rate_class($current_class); $rates = WC_Tax::get_rates_for_tax_class($current_class); foreach ($rates as $tax_rate_id => $rate) { if (isset($_POST['tax_rate_hidden'][$tax_rate_id])) { // @codingStandardsIgnoreEnd $hidden_rates[$tax_rate_id] = true; } else { if (isset($hidden_rates[$tax_rate_id])) { unset($hidden_rates[$tax_rate_id]); } } } wc_hidden_taxes()->set_option('hidden_rates', $hidden_rates); }
/** * Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model. */ public static function tax_rates_save_changes() { if (!isset($_POST['current_class'], $_POST['wc_tax_nonce'], $_POST['changes'])) { wp_send_json_error('missing_fields'); exit; } $current_class = $_POST['current_class']; // This is sanitized seven lines later. if (!wp_verify_nonce($_POST['wc_tax_nonce'], 'wc_tax_nonce-class:' . $current_class)) { wp_send_json_error('bad_nonce'); exit; } $current_class = WC_Tax::format_tax_rate_class($current_class); // Check User Caps if (!current_user_can('manage_woocommerce')) { wp_send_json_error('missing_capabilities'); exit; } $changes = $_POST['changes']; foreach ($changes as $tax_rate_id => $data) { if (isset($data['deleted'])) { if (isset($data['newRow'])) { // So the user added and deleted a new row. // That's fine, it's not in the database anyways. NEXT! continue; } WC_Tax::_delete_tax_rate($tax_rate_id); } $tax_rate = array_intersect_key($data, array('tax_rate_country' => 1, 'tax_rate_state' => 1, 'tax_rate' => 1, 'tax_rate_name' => 1, 'tax_rate_priority' => 1, 'tax_rate_compound' => 1, 'tax_rate_shipping' => 1, 'tax_rate_order' => 1)); if (isset($data['newRow'])) { // Hurrah, shiny and new! $tax_rate['tax_rate_class'] = $current_class; $tax_rate_id = WC_Tax::_insert_tax_rate($tax_rate); } else { // Updating an existing rate ... if (!empty($tax_rate)) { WC_Tax::_update_tax_rate($tax_rate_id, $tax_rate); } } if (isset($data['postcode'])) { WC_Tax::_update_tax_rate_postcodes($tax_rate_id, array_map('wc_clean', $data['postcode'])); } if (isset($data['city'])) { WC_Tax::_update_tax_rate_cities($tax_rate_id, array_map('wc_clean', $data['city'])); } } wp_send_json_success(array('rates' => WC_Tax::get_rates_for_tax_class($current_class))); }
/** * Output tax rate tables. */ public function output_tax_rates() { global $wpdb, $current_section; $current_class = $this->get_current_tax_class(); $countries = array(); foreach (WC()->countries->get_allowed_countries() as $value => $label) { $countries[] = array('value' => $value, 'label' => esc_js(html_entity_decode($label))); } $states = array(); foreach (WC()->countries->get_allowed_country_states() as $label) { foreach ($label as $code => $state) { $states[] = array('value' => $code, 'label' => esc_js(html_entity_decode($state))); } } $base_url = admin_url(add_query_arg(array('page' => 'wc-settings', 'tab' => 'tax', 'section' => $current_section), 'admin.php')); // Localize and enqueue our js. wp_localize_script('wc-settings-tax', 'htmlSettingsTaxLocalizeScript', array('current_class' => $current_class, 'wc_tax_nonce' => wp_create_nonce('wc_tax_nonce-class:' . $current_class), 'base_url' => $base_url, 'rates' => array_values(WC_Tax::get_rates_for_tax_class($current_class)), 'page' => !empty($_GET['p']) ? absint($_GET['p']) : 1, 'limit' => 100, 'countries' => $countries, 'states' => $states, 'default_rate' => array('tax_rate_id' => 0, 'tax_rate_country' => '', 'tax_rate_state' => '', 'tax_rate' => '', 'tax_rate_name' => '', 'tax_rate_priority' => 1, 'tax_rate_compound' => 0, 'tax_rate_shipping' => 1, 'tax_rate_order' => null, 'tax_rate_class' => $current_class), 'strings' => array('no_rows_selected' => __('No row(s) selected', 'woocommerce'), 'unload_confirmation_msg' => __('Your changed data will be lost if you leave this page without saving.', 'woocommerce'), 'csv_data_cols' => array(__('Country code', 'woocommerce'), __('State code', 'woocommerce'), __('Postcode / ZIP', 'woocommerce'), __('City', 'woocommerce'), __('Rate %', 'woocommerce'), __('Tax name', 'woocommerce'), __('Priority', 'woocommerce'), __('Compound', 'woocommerce'), __('Shipping', 'woocommerce'), __('Tax class', 'woocommerce'))))); wp_enqueue_script('wc-settings-tax'); include 'views/html-settings-tax.php'; }
<span class="wpallimport-clear"></span> <select name="pmwi_order[taxes][ROWNUMBER][tax_code]" id="order_tax_code_ROWNUMBER" class="rad4 switcher" style="font-size: 14px !important;"> <option value=""><?php _e("Select", "wp_all_import_plugin"); ?> </option> <?php foreach ($classes_options as $key => $value) { ?> <optgroup label="<?php echo $value; ?> "> <?php foreach (WC_Tax::get_rates_for_tax_class($key) as $rate_key => $rate) { ?> <option value="<?php echo $rate->tax_rate_id; ?> "><?php echo $rate->tax_rate_name; ?> </option> <?php } ?> </optgroup> <?php }
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; }