/**
  * Bulk edit
  * @param integer $post_id
  * @param WC_Product $product
  */
 public function bulk_edit_save($post_id, $product)
 {
     $old_regular_price = $product->regular_price;
     $old_sale_price = $product->sale_price;
     // Save fields
     if (!empty($_REQUEST['change_weight']) && isset($_REQUEST['_weight'])) {
         update_post_meta($post_id, '_weight', wc_clean(stripslashes($_REQUEST['_weight'])));
     }
     if (!empty($_REQUEST['change_dimensions'])) {
         if (isset($_REQUEST['_length'])) {
             update_post_meta($post_id, '_length', wc_clean(stripslashes($_REQUEST['_length'])));
         }
         if (isset($_REQUEST['_width'])) {
             update_post_meta($post_id, '_width', wc_clean(stripslashes($_REQUEST['_width'])));
         }
         if (isset($_REQUEST['_height'])) {
             update_post_meta($post_id, '_height', wc_clean(stripslashes($_REQUEST['_height'])));
         }
     }
     if (!empty($_REQUEST['_tax_status'])) {
         update_post_meta($post_id, '_tax_status', wc_clean($_REQUEST['_tax_status']));
     }
     if (!empty($_REQUEST['_tax_class'])) {
         $tax_class = wc_clean($_REQUEST['_tax_class']);
         if ('standard' == $tax_class) {
             $tax_class = '';
         }
         update_post_meta($post_id, '_tax_class', $tax_class);
     }
     if (!empty($_REQUEST['_stock_status'])) {
         $stock_status = wc_clean($_REQUEST['_stock_status']);
         if ($product->is_type('variable')) {
             foreach ($product->get_children() as $child_id) {
                 if ('yes' !== get_post_meta($child_id, '_manage_stock', true)) {
                     wc_update_product_stock_status($child_id, $stock_status);
                 }
             }
             WC_Product_Variable::sync_stock_status($post_id);
         } else {
             wc_update_product_stock_status($post_id, $stock_status);
         }
     }
     if (!empty($_REQUEST['_shipping_class'])) {
         $shipping_class = '_no_shipping_class' == $_REQUEST['_shipping_class'] ? '' : wc_clean($_REQUEST['_shipping_class']);
         wp_set_object_terms($post_id, $shipping_class, 'product_shipping_class');
     }
     if (!empty($_REQUEST['_visibility'])) {
         if (update_post_meta($post_id, '_visibility', wc_clean($_REQUEST['_visibility']))) {
             do_action('woocommerce_product_set_visibility', $post_id, wc_clean($_REQUEST['_visibility']));
         }
     }
     if (!empty($_REQUEST['_featured'])) {
         if (update_post_meta($post_id, '_featured', stripslashes($_REQUEST['_featured']))) {
             delete_transient('wc_featured_products');
         }
     }
     // Sold Individually
     if (!empty($_REQUEST['_sold_individually'])) {
         if ($_REQUEST['_sold_individually'] == 'yes') {
             update_post_meta($post_id, '_sold_individually', 'yes');
         } else {
             update_post_meta($post_id, '_sold_individually', '');
         }
     }
     // Handle price - remove dates and set to lowest
     if ($product->is_type('simple') || $product->is_type('external')) {
         $price_changed = false;
         if (!empty($_REQUEST['change_regular_price'])) {
             $change_regular_price = absint($_REQUEST['change_regular_price']);
             $regular_price = esc_attr(stripslashes($_REQUEST['_regular_price']));
             switch ($change_regular_price) {
                 case 1:
                     $new_price = $regular_price;
                     break;
                 case 2:
                     if (strstr($regular_price, '%')) {
                         $percent = str_replace('%', '', $regular_price) / 100;
                         $new_price = $old_regular_price + round($old_regular_price * $percent, wc_get_price_decimals());
                     } else {
                         $new_price = $old_regular_price + $regular_price;
                     }
                     break;
                 case 3:
                     if (strstr($regular_price, '%')) {
                         $percent = str_replace('%', '', $regular_price) / 100;
                         $new_price = max(0, $old_regular_price - round($old_regular_price * $percent, wc_get_price_decimals()));
                     } else {
                         $new_price = max(0, $old_regular_price - $regular_price);
                     }
                     break;
                 default:
                     break;
             }
             if (isset($new_price) && $new_price != $old_regular_price) {
                 $price_changed = true;
                 $new_price = round($new_price, wc_get_price_decimals());
                 update_post_meta($post_id, '_regular_price', $new_price);
                 $product->regular_price = $new_price;
             }
         }
         if (!empty($_REQUEST['change_sale_price'])) {
             $change_sale_price = absint($_REQUEST['change_sale_price']);
             $sale_price = esc_attr(stripslashes($_REQUEST['_sale_price']));
             switch ($change_sale_price) {
                 case 1:
                     $new_price = $sale_price;
                     break;
                 case 2:
                     if (strstr($sale_price, '%')) {
                         $percent = str_replace('%', '', $sale_price) / 100;
                         $new_price = $old_sale_price + $old_sale_price * $percent;
                     } else {
                         $new_price = $old_sale_price + $sale_price;
                     }
                     break;
                 case 3:
                     if (strstr($sale_price, '%')) {
                         $percent = str_replace('%', '', $sale_price) / 100;
                         $new_price = max(0, $old_sale_price - $old_sale_price * $percent);
                     } else {
                         $new_price = max(0, $old_sale_price - $sale_price);
                     }
                     break;
                 case 4:
                     if (strstr($sale_price, '%')) {
                         $percent = str_replace('%', '', $sale_price) / 100;
                         $new_price = max(0, $product->regular_price - $product->regular_price * $percent);
                     } else {
                         $new_price = max(0, $product->regular_price - $sale_price);
                     }
                     break;
                 default:
                     break;
             }
             if (isset($new_price) && $new_price != $old_sale_price) {
                 $price_changed = true;
                 $new_price = !empty($new_price) || '0' === $new_price ? round($new_price, wc_get_price_decimals()) : '';
                 update_post_meta($post_id, '_sale_price', $new_price);
                 $product->sale_price = $new_price;
             }
         }
         if ($price_changed) {
             update_post_meta($post_id, '_sale_price_dates_from', '');
             update_post_meta($post_id, '_sale_price_dates_to', '');
             if ($product->regular_price < $product->sale_price) {
                 $product->sale_price = '';
                 update_post_meta($post_id, '_sale_price', '');
             }
             if ($product->sale_price) {
                 update_post_meta($post_id, '_price', $product->sale_price);
             } else {
                 update_post_meta($post_id, '_price', $product->regular_price);
             }
         }
     }
     // Handle stock
     if (!$product->is_type('grouped')) {
         if (!empty($_REQUEST['change_stock'])) {
             update_post_meta($post_id, '_manage_stock', 'yes');
             wc_update_product_stock($post_id, wc_stock_amount($_REQUEST['_stock']));
         }
         if (!empty($_REQUEST['_manage_stock'])) {
             if ($_REQUEST['_manage_stock'] == 'yes') {
                 update_post_meta($post_id, '_manage_stock', 'yes');
             } else {
                 update_post_meta($post_id, '_manage_stock', 'no');
                 wc_update_product_stock($post_id, 0);
             }
         }
         if (!empty($_REQUEST['_backorders'])) {
             update_post_meta($post_id, '_backorders', wc_clean($_REQUEST['_backorders']));
         }
     }
     do_action('woocommerce_product_bulk_edit_save', $product);
 }
 /**
  * Register the stylesheets for the public-facing side of the site.
  *
  * @since    1.0.0
  */
 public function enqueue_scripts()
 {
     global $post, $product;
     if (is_object($post) && class_exists('WooCommerce')) {
         $is_product_type_variable = 'false';
         if (function_exists('wc_get_product')) {
             $product = wc_get_product($post);
             if ($product) {
                 if ($product->is_type('variable') && is_single()) {
                     $is_product_type_variable = 'true';
                 }
             }
         }
         $attach_id = isset($_SESSION['attach_id']) && !empty($_SESSION['attach_id']) ? $_SESSION['attach_id'] : '';
         if (!empty($attach_id)) {
             $total_word = get_post_meta($attach_id, 'total_word', true);
         } else {
             $total_word = '';
         }
         if (!empty($attach_id)) {
             $total_character = get_post_meta($attach_id, 'total_character', true);
         } else {
             $total_character = '';
         }
         wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/woocommerce-price-per-word-public.js', array('jquery'), $this->version, false);
         if (wp_script_is($this->plugin_name)) {
             wp_localize_script($this->plugin_name, 'woocommerce_price_per_word_params', apply_filters('woocommerce_price_per_word_params', array('ajax_url' => admin_url('admin-ajax.php'), 'woocommerce_price_per_word_params_nonce' => wp_create_nonce("woocommerce_price_per_word_params_nonce"), 'total_word' => $total_word, 'total_character' => $total_character, 'is_product_type_variable' => $is_product_type_variable, 'woocommerce_currency_symbol_js' => get_woocommerce_currency_symbol(), 'woocommerce_price_num_decimals' => wc_get_price_decimals(), 'aewcppw_word_character' => $this->wppw_get_product_type(), 'aewcppw_allow_users_to_enter_qty' => $this->aewcppw_allow_users_to_enter_qty())));
         }
         wp_enqueue_script($this->plugin_name . '-bn', plugin_dir_url(__FILE__) . 'js/woocommerce-price-per-word-bn.js', array('jquery'), $this->version, false);
     }
 }
 /**
  * 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())
 {
     $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 = round(is_array($cost) ? array_sum($cost) : $cost, wc_get_price_decimals());
     // 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 ($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 = WC()->cart->get_cart();
                     foreach ($cost as $cost_key => $amount) {
                         if (!isset($cart[$cost_key])) {
                             continue;
                         }
                         $_product = $cart[$cost_key]['data'];
                         $rates = WC_Tax::get_shipping_tax_rates($_product->get_tax_class());
                         $item_taxes = WC_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 = WC_Tax::get_shipping_tax_rates();
                         $item_taxes = WC_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 = WC_Tax::get_shipping_tax_rates();
                 $taxes = WC_Tax::calc_shipping_tax($total_cost, $rates);
                 break;
         }
     }
     $this->rates[] = new WC_Shipping_Rate($id, $label, $total_cost, $taxes, $this->id);
 }
/**
 * Uses the WooCommerce currency display settings to format CSV price values instead of machine-readable values
 *
 * @param array $item_data the data "items" columns in the CSV Export file
 * @return array - updated item data
 */
function sv_wc_csv_export_localize_price_items_columns($item_data)
{
    $decimals = wc_get_price_decimals();
    $decimal_separator = wc_get_price_decimal_separator();
    $thousand_separator = wc_get_price_thousand_separator();
    $price_data = array('subtotal', 'subtotal_tax', 'total', 'total_tax', 'refunded');
    // localize price for each piece of price data
    foreach ($price_data as $data_key) {
        if (isset($item_data[$data_key])) {
            $item_data[$data_key] = number_format($item_data[$data_key], $decimals, $decimal_separator, $thousand_separator);
        }
    }
    return $item_data;
}
Example #5
0
 /**
  * Constructor for the cart class. Loads options and hooks in the init method.
  */
 public function __construct()
 {
     $this->prices_include_tax = wc_prices_include_tax();
     $this->round_at_subtotal = get_option('woocommerce_tax_round_at_subtotal') == 'yes';
     $this->tax_display_cart = get_option('woocommerce_tax_display_cart');
     $this->dp = wc_get_price_decimals();
     $this->display_totals_ex_tax = $this->tax_display_cart == 'excl';
     $this->display_cart_ex_tax = $this->tax_display_cart == 'excl';
     add_action('wp_loaded', array($this, 'init'));
     // Get cart after WP and plugins are loaded.
     add_action('wp', array($this, 'maybe_set_cart_cookies'), 99);
     // Set cookies
     add_action('shutdown', array($this, 'maybe_set_cart_cookies'), 0);
     // Set cookies before shutdown and ob flushing
     add_action('woocommerce_add_to_cart', array($this, 'calculate_totals'), 20, 0);
     add_action('woocommerce_applied_coupon', array($this, 'calculate_totals'), 20, 0);
 }
 /**
  * Enqueue scripts
  */
 public function admin_scripts()
 {
     global $post;
     get_currentuserinfo();
     $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
     // Register scripts
     wp_register_script('woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array('jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip'), WC_VERSION);
     wp_register_script('jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array('jquery'), '2.66', true);
     wp_register_script('jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array('jquery'), WC_VERSION, true);
     wp_register_script('accounting', WC()->plugin_url() . '/assets/js/admin/accounting' . $suffix . '.js', array('jquery'), '0.3.2');
     wp_register_script('round', WC()->plugin_url() . '/assets/js/admin/round' . $suffix . '.js', array('jquery'), WC_VERSION);
     wp_register_script('wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array('jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable'), WC_VERSION);
     wp_register_script('qrcode', WC()->plugin_url() . '/assets/js/admin/jquery.qrcode.min.js', array('jquery'), WC_VERSION);
     wp_register_script('stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array('jquery'), WC_VERSION);
     wp_register_script('wc-admin-notices', WC()->plugin_url() . '/assets/js/admin/woocommerce_notices' . $suffix . '.js', array('jquery'), WC_VERSION, true);
     // Select2 is the replacement for chosen
     wp_register_script('select2', WC()->plugin_url() . '/assets/js/select2/select2' . $suffix . '.js', array('jquery'), '3.5.2');
     wp_register_script('wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array('jquery', 'select2'), WC_VERSION);
     wp_localize_script('select2', 'wc_select_params', array('i18n_matches_1' => _x('One result is available, press enter to select it.', 'enhanced select', 'woocommerce'), 'i18n_matches_n' => _x('%qty% results are available, use up and down arrow keys to navigate.', 'enhanced select', 'woocommerce'), 'i18n_no_matches' => _x('No matches found', 'enhanced select', 'woocommerce'), 'i18n_ajax_error' => _x('Loading failed', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_1' => _x('Please enter 1 or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_n' => _x('Please enter %qty% or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_1' => _x('Please delete 1 character', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_n' => _x('Please delete %qty% characters', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_1' => _x('You can only select 1 item', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_n' => _x('You can only select %qty% items', 'enhanced select', 'woocommerce'), 'i18n_load_more' => _x('Loading more results&hellip;', 'enhanced select', 'woocommerce'), 'i18n_searching' => _x('Searching&hellip;', 'enhanced select', 'woocommerce')));
     wp_localize_script('wc-enhanced-select', 'wc_enhanced_select_params', array('ajax_url' => admin_url('admin-ajax.php'), 'search_products_nonce' => wp_create_nonce('search-products'), 'search_customers_nonce' => wp_create_nonce('search-customers')));
     // Accounting
     wp_localize_script('accounting', 'accounting_params', array('mon_decimal_point' => wc_get_price_decimal_separator()));
     // WooCommerce admin pages
     wp_enqueue_script('woocommerce_admin');
     wp_enqueue_script('iris');
     wp_enqueue_script('wc-enhanced-select');
     wp_enqueue_script('jquery-ui-sortable');
     wp_enqueue_script('jquery-ui-autocomplete');
     $locale = localeconv();
     $decimal = isset($locale['decimal_point']) ? $locale['decimal_point'] : '.';
     $params = array('i18n_decimal_error' => sprintf(__('Please enter in decimal (%s) format without thousand separators.', 'woocommerce'), $decimal), 'i18n_mon_decimal_error' => sprintf(__('Please enter in monetary decimal (%s) format without thousand separators and currency symbols.', 'woocommerce'), wc_get_price_decimal_separator()), 'i18n_country_iso_error' => __('Please enter in country code with two capital letters.', 'woocommerce'), 'i18_sale_less_than_regular_error' => __('Please enter in a value less than the regular price.', 'woocommerce'), 'decimal_point' => $decimal, 'mon_decimal_point' => wc_get_price_decimal_separator());
     wp_localize_script('woocommerce_admin', 'woocommerce_admin', $params);
     // Meta boxes
     wp_enqueue_media();
     wp_enqueue_script('wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION);
     wp_enqueue_script('wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION);
     $params = array('post_id' => isset($post->ID) ? $post->ID : '', 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'woocommerce_placeholder_img_src' => wc_placeholder_img_src(), 'add_variation_nonce' => wp_create_nonce("add-variation"), 'link_variation_nonce' => wp_create_nonce("link-variations"), 'delete_variations_nonce' => wp_create_nonce("delete-variations"), 'i18n_link_all_variations' => esc_js(__('Are you sure you want to link all variations? This will create a new variation for each and every possible combination of variation attributes (max 50 per run).', 'woocommerce')), 'i18n_enter_a_value' => esc_js(__('Enter a value', 'woocommerce')), 'i18n_enter_a_value_fixed_or_percent' => esc_js(__('Enter a value (fixed or %)', 'woocommerce')), 'i18n_delete_all_variations' => esc_js(__('Are you sure you want to delete all variations? This cannot be undone.', 'woocommerce')), 'i18n_last_warning' => esc_js(__('Last warning, are you sure?', 'woocommerce')), 'i18n_choose_image' => esc_js(__('Choose an image', 'woocommerce')), 'i18n_set_image' => esc_js(__('Set variation image', 'woocommerce')), 'i18n_variation_added' => esc_js(__("variation added", 'woocommerce')), 'i18n_variations_added' => esc_js(__("variations added", 'woocommerce')), 'i18n_no_variations_added' => esc_js(__("No variations added", 'woocommerce')), 'i18n_remove_variation' => esc_js(__('Are you sure you want to remove this variation?', 'woocommerce')), 'i18n_scheduled_sale_start' => esc_js(__('Sale start date (YYYY-MM-DD format or leave blank)', 'woocommerce')), 'i18n_scheduled_sale_end' => esc_js(__('Sale end date  (YYYY-MM-DD format or leave blank)', 'woocommerce')));
     wp_localize_script('wc-admin-variation-meta-boxes', 'woocommerce_admin_meta_boxes_variations', $params);
     $params = array('remove_item_notice' => __('Are you sure you want to remove the selected items? If you have previously reduced this item\'s stock, or this order was submitted by a customer, you will need to manually restore the item\'s stock.', 'woocommerce'), 'i18n_select_items' => __('Please select some items.', 'woocommerce'), 'i18n_do_refund' => __('Are you sure you wish to process this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_refund' => __('Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_tax' => __('Are you sure you wish to delete this tax column? This action cannot be undone.', 'woocommerce'), 'remove_item_meta' => __('Remove this item meta?', 'woocommerce'), 'remove_attribute' => __('Remove this attribute?', 'woocommerce'), 'name_label' => __('Name', 'woocommerce'), 'remove_label' => __('Remove', 'woocommerce'), 'click_to_toggle' => __('Click to toggle', 'woocommerce'), 'values_label' => __('Value(s)', 'woocommerce'), 'text_attribute_tip' => __('Enter some text, or some attributes by pipe (|) separating values.', 'woocommerce'), 'visible_label' => __('Visible on the product page', 'woocommerce'), 'used_for_variations_label' => __('Used for variations', 'woocommerce'), 'new_attribute_prompt' => __('Enter a name for the new attribute term:', 'woocommerce'), 'calc_totals' => __('Calculate totals based on order items, discounts, and shipping?', 'woocommerce'), 'calc_line_taxes' => __('Calculate line taxes? This will calculate taxes based on the customers country. If no billing/shipping is set it will use the store base country.', 'woocommerce'), 'copy_billing' => __('Copy billing information to shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'load_billing' => __('Load the customer\'s billing information? This will remove any currently entered billing information.', 'woocommerce'), 'load_shipping' => __('Load the customer\'s shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'featured_label' => __('Featured', 'woocommerce'), 'prices_include_tax' => esc_attr(get_option('woocommerce_prices_include_tax')), 'round_at_subtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'no_customer_selected' => __('No customer selected', 'woocommerce'), 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'order_item_nonce' => wp_create_nonce('order-item'), 'add_attribute_nonce' => wp_create_nonce('add-attribute'), 'save_attributes_nonce' => wp_create_nonce('save-attributes'), 'calc_totals_nonce' => wp_create_nonce('calc-totals'), 'get_customer_details_nonce' => wp_create_nonce('get-customer-details'), 'search_products_nonce' => wp_create_nonce('search-products'), 'grant_access_nonce' => wp_create_nonce('grant-access'), 'revoke_access_nonce' => wp_create_nonce('revoke-access'), 'add_order_note_nonce' => wp_create_nonce('add-order-note'), 'delete_order_note_nonce' => wp_create_nonce('delete-order-note'), 'calendar_image' => WC()->plugin_url() . '/assets/images/calendar.png', 'post_id' => isset($post->ID) ? $post->ID : '', 'base_country' => WC()->countries->get_base_country(), 'currency_format_num_decimals' => wc_get_price_decimals(), 'currency_format_symbol' => get_woocommerce_currency_symbol(), 'currency_format_decimal_sep' => esc_attr(wc_get_price_decimal_separator()), 'currency_format_thousand_sep' => esc_attr(wc_get_price_thousand_separator()), 'currency_format' => esc_attr(str_replace(array('%1$s', '%2$s'), array('%s', '%v'), get_woocommerce_price_format())), 'rounding_precision' => WC_ROUNDING_PRECISION, 'tax_rounding_mode' => WC_TAX_ROUNDING_MODE, 'product_types' => array_map('sanitize_title', get_terms('product_type', array('hide_empty' => false, 'fields' => 'names'))), 'default_attribute_visibility' => apply_filters('default_attribute_visibility', false), 'default_attribute_variation' => apply_filters('default_attribute_variation', false), 'i18n_download_permission_fail' => __('Could not grant access - the user may already have permission for this file or billing email is not set. Ensure the billing email is set, and the order has been saved.', 'woocommerce'), 'i18n_permission_revoke' => __('Are you sure you want to revoke access to this download?', 'woocommerce'), 'i18n_tax_rate_already_exists' => __('You cannot add the same tax rate twice!', 'woocommerce'), 'i18n_product_type_alert' => __('Your product has variations! Before changing the product type, it is a good idea to delete the variations to avoid errors in the stock reports.', 'woocommerce'));
     wp_localize_script('wc-admin-meta-boxes', 'woocommerce_admin_meta_boxes', $params);
 }
 /**
  * Get an array of all sale and regular prices from all variations. This is used for example when displaying the price range at variable product level or seeing if the variable product is on sale.
  *
  * Can be filtered by plugins which modify costs, but otherwise will include the raw meta costs unlike get_price() which runs costs through the woocommerce_get_price filter.
  * This is to ensure modified prices are not cached, unless intended.
  *
  * @param  bool $display Are prices for display? If so, taxes will be calculated.
  * @return array() Array of RAW prices, regular prices, and sale prices with keys set to variation ID.
  */
 public function get_variation_prices($display = false)
 {
     global $wp_filter;
     /**
      * Transient name for storing prices for this product (note: Max transient length is 45)
      * @since 2.5.0 a single transient is used per product for all prices, rather than many transients per product.
      */
     $transient_name = 'wc_var_prices_' . $this->id;
     /**
      * Create unique cache key based on the tax location (affects displayed/cached prices), product version and active price filters.
      * DEVELOPERS should filter this hash if offering conditonal pricing to keep it unique.
      * @var string
      */
     if ($display) {
         $price_hash = array(get_option('woocommerce_tax_display_shop', 'excl'), WC_Tax::get_rates());
     } else {
         $price_hash = array(false);
     }
     $filter_names = array('woocommerce_variation_prices_price', 'woocommerce_variation_prices_regular_price', 'woocommerce_variation_prices_sale_price');
     foreach ($filter_names as $filter_name) {
         if (!empty($wp_filter[$filter_name])) {
             $price_hash[$filter_name] = array();
             foreach ($wp_filter[$filter_name] as $priority => $callbacks) {
                 $price_hash[$filter_name][] = array_values(wp_list_pluck($callbacks, 'function'));
             }
         }
     }
     $price_hash = md5(json_encode(apply_filters('woocommerce_get_variation_prices_hash', $price_hash, $this, $display)));
     // If the value has already been generated, we don't need to grab the values again.
     if (empty($this->prices_array[$price_hash])) {
         // Get value of transient
         $prices_array = array_filter((array) json_decode(strval(get_transient($transient_name)), true));
         // If the product version has changed, reset cache
         if (empty($prices_array['version']) || $prices_array['version'] !== WC_Cache_Helper::get_transient_version('product')) {
             $this->prices_array = array('version' => WC_Cache_Helper::get_transient_version('product'));
         }
         // If the prices are not stored for this hash, generate them
         if (empty($prices_array[$price_hash])) {
             $prices = array();
             $regular_prices = array();
             $sale_prices = array();
             $variation_ids = $this->get_children(true);
             foreach ($variation_ids as $variation_id) {
                 if ($variation = $this->get_child($variation_id)) {
                     $price = apply_filters('woocommerce_variation_prices_price', $variation->price, $variation, $this);
                     $regular_price = apply_filters('woocommerce_variation_prices_regular_price', $variation->regular_price, $variation, $this);
                     $sale_price = apply_filters('woocommerce_variation_prices_sale_price', $variation->sale_price, $variation, $this);
                     // Skip empty prices
                     if ('' === $price) {
                         continue;
                     }
                     // If sale price does not equal price, the product is not yet on sale
                     if ($sale_price === $regular_price || $sale_price !== $price) {
                         $sale_price = $regular_price;
                     }
                     // If we are getting prices for display, we need to account for taxes
                     if ($display) {
                         if ('incl' === get_option('woocommerce_tax_display_shop')) {
                             $price = '' === $price ? '' : $variation->get_price_including_tax(1, $price);
                             $regular_price = '' === $regular_price ? '' : $variation->get_price_including_tax(1, $regular_price);
                             $sale_price = '' === $sale_price ? '' : $variation->get_price_including_tax(1, $sale_price);
                         } else {
                             $price = '' === $price ? '' : $variation->get_price_excluding_tax(1, $price);
                             $regular_price = '' === $regular_price ? '' : $variation->get_price_excluding_tax(1, $regular_price);
                             $sale_price = '' === $sale_price ? '' : $variation->get_price_excluding_tax(1, $sale_price);
                         }
                     }
                     $prices[$variation_id] = wc_format_decimal($price, wc_get_price_decimals());
                     $regular_prices[$variation_id] = wc_format_decimal($regular_price, wc_get_price_decimals());
                     $sale_prices[$variation_id] = wc_format_decimal($sale_price . '.00', wc_get_price_decimals());
                 }
             }
             asort($prices);
             asort($regular_prices);
             asort($sale_prices);
             $prices_array[$price_hash] = array('price' => $prices, 'regular_price' => $regular_prices, 'sale_price' => $sale_prices);
             set_transient($transient_name, json_encode($prices_array), DAY_IN_SECONDS * 30);
         }
         /**
          * Give plugins one last chance to filter the variation prices array which has been generated.
          */
         $this->prices_array[$price_hash] = apply_filters('woocommerce_variation_prices', $prices_array[$price_hash], $this, $display);
     }
     /**
      * Return the values.
      */
     return $this->prices_array[$price_hash];
 }
 /**
  * Get the site index.
  *
  * This endpoint describes the capabilities of the site.
  *
  * @since 2.3
  * @return array Index entity
  */
 public function get_index()
 {
     // General site data
     $available = array('store' => array('name' => get_option('blogname'), 'description' => get_option('blogdescription'), 'URL' => get_option('siteurl'), 'wc_version' => WC()->version, 'routes' => array(), 'meta' => array('timezone' => wc_timezone_string(), 'currency' => get_woocommerce_currency(), 'currency_format' => get_woocommerce_currency_symbol(), 'currency_position' => get_option('woocommerce_currency_pos'), 'thousand_separator' => get_option('woocommerce_price_decimal_sep'), 'decimal_separator' => get_option('woocommerce_price_thousand_sep'), 'price_num_decimals' => wc_get_price_decimals(), 'tax_included' => wc_prices_include_tax(), 'weight_unit' => get_option('woocommerce_weight_unit'), 'dimension_unit' => get_option('woocommerce_dimension_unit'), 'ssl_enabled' => 'yes' === get_option('woocommerce_force_ssl_checkout'), 'permalinks_enabled' => '' !== get_option('permalink_structure'), 'links' => array('help' => 'http://woothemes.github.io/woocommerce-rest-api-docs/'))));
     // Find the available routes
     foreach ($this->get_routes() as $route => $callbacks) {
         $data = array();
         $route = preg_replace('#\\(\\?P(<\\w+?>).*?\\)#', '$1', $route);
         foreach (self::$method_map as $name => $bitmask) {
             foreach ($callbacks as $callback) {
                 // Skip to the next route if any callback is hidden
                 if ($callback[1] & self::HIDDEN_ENDPOINT) {
                     continue 3;
                 }
                 if ($callback[1] & $bitmask) {
                     $data['supports'][] = $name;
                 }
                 if ($callback[1] & self::ACCEPT_DATA) {
                     $data['accepts_data'] = true;
                 }
                 // For non-variable routes, generate links
                 if (strpos($route, '<') === false) {
                     $data['meta'] = array('self' => get_woocommerce_api_url($route));
                 }
             }
         }
         $available['store']['routes'][$route] = apply_filters('woocommerce_api_endpoints_description', $data);
     }
     return apply_filters('woocommerce_api_index', $available);
 }
    /**
     * Get the main chart.
     *
     * @return string
     */
    public function get_main_chart()
    {
        global $wp_locale;
        if (empty($this->show_categories)) {
            ?>
			<div class="chart-container">
				<p class="chart-prompt"><?php 
            _e('&larr; Choose a category to view stats', 'woocommerce');
            ?>
</p>
			</div>
			<?php 
        } else {
            $chart_data = array();
            $index = 0;
            foreach ($this->show_categories as $category) {
                $category = get_term($category, 'product_cat');
                $product_ids = $this->get_products_in_category($category->term_id);
                $category_chart_data = array();
                for ($i = 0; $i <= $this->chart_interval; $i++) {
                    $interval_total = 0;
                    switch ($this->chart_groupby) {
                        case 'day':
                            $time = strtotime(date('Ymd', strtotime("+{$i} DAY", $this->start_date))) * 1000;
                            break;
                        case 'month':
                        default:
                            $time = strtotime(date('Ym', strtotime("+{$i} MONTH", $this->start_date)) . '01') * 1000;
                            break;
                    }
                    foreach ($product_ids as $id) {
                        if (isset($this->item_sales_and_times[$time][$id])) {
                            $interval_total += $this->item_sales_and_times[$time][$id];
                        }
                    }
                    $category_chart_data[] = array($time, (double) wc_format_decimal($interval_total, wc_get_price_decimals()));
                }
                $chart_data[$category->term_id]['category'] = $category->name;
                $chart_data[$category->term_id]['data'] = $category_chart_data;
                $index++;
            }
            ?>
			<div class="chart-container">
				<div class="chart-placeholder main"></div>
			</div>
			<script type="text/javascript">
				var main_chart;

				jQuery(function(){
					var drawGraph = function( highlight ) {
						var series = [
							<?php 
            $index = 0;
            foreach ($chart_data as $data) {
                $color = isset($this->chart_colours[$index]) ? $this->chart_colours[$index] : $this->chart_colours[0];
                $width = $this->barwidth / sizeof($chart_data);
                $offset = $width * $index;
                $series = $data['data'];
                foreach ($series as $key => $series_data) {
                    $series[$key][0] = $series_data[0] + $offset;
                }
                echo '{
										label: "' . esc_js($data['category']) . '",
										data: jQuery.parseJSON( "' . json_encode($series) . '" ),
										color: "' . $color . '",
										bars: {
											fillColor: "' . $color . '",
											fill: true,
											show: true,
											lineWidth: 1,
											align: "center",
											barWidth: ' . $width * 0.75 . ',
											stack: false
										},
										' . $this->get_currency_tooltip() . ',
										enable_tooltip: true,
										prepend_label: true
									},';
                $index++;
            }
            ?>
						];

						if ( highlight !== 'undefined' && series[ highlight ] ) {
							highlight_series = series[ highlight ];

							highlight_series.color = '#9c5d90';

							if ( highlight_series.bars ) {
								highlight_series.bars.fillColor = '#9c5d90';
							}

							if ( highlight_series.lines ) {
								highlight_series.lines.lineWidth = 5;
							}
						}

						main_chart = jQuery.plot(
							jQuery('.chart-placeholder.main'),
							series,
							{
								legend: {
									show: false
								},
								grid: {
									color: '#aaa',
									borderColor: 'transparent',
									borderWidth: 0,
									hoverable: true
								},
								xaxes: [ {
									color: '#aaa',
									reserveSpace: true,
									position: "bottom",
									tickColor: 'transparent',
									mode: "time",
									timeformat: "<?php 
            if ($this->chart_groupby == 'day') {
                echo '%d %b';
            } else {
                echo '%b';
            }
            ?>
",
									monthNames: <?php 
            echo json_encode(array_values($wp_locale->month_abbrev));
            ?>
,
									tickLength: 1,
									minTickSize: [1, "<?php 
            echo $this->chart_groupby;
            ?>
"],
									tickSize: [1, "<?php 
            echo $this->chart_groupby;
            ?>
"],
									font: {
										color: "#aaa"
									}
								} ],
								yaxes: [
									{
										min: 0,
										tickDecimals: 2,
										color: 'transparent',
										font: { color: "#aaa" }
									}
								],
							}
						);

						jQuery('.chart-placeholder').resize();

					}

					drawGraph();

					jQuery('.highlight_series').hover(
						function() {
							drawGraph( jQuery(this).data('series') );
						},
						function() {
							drawGraph();
						}
					);
				});
			</script>
			<?php 
        }
    }
Example #10
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 
 /**
  * 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', 'meta_data' => array()));
     // ID and label are required
     if (!$args['id'] || !$args['label']) {
         return;
     }
     // Total up the 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 = 'per_item' === $args['calc_tax'] ? $this->get_taxes_per_item($args['cost']) : WC_Tax::calc_shipping_tax($total_cost, WC_Tax::get_shipping_tax_rates());
     }
     // Round the total cost after taxes have been calculated.
     $total_cost = wc_format_decimal($total_cost, wc_get_price_decimals());
     // Create rate object
     $rate = new WC_Shipping_Rate($args['id'], $args['label'], $total_cost, $taxes, $this->id);
     if (!empty($args['meta_data'])) {
         foreach ($args['meta_data'] as $key => $value) {
             $rate->add_meta_data($key, $value);
         }
     }
     $this->rates[$args['id']] = $rate;
 }
/**
 * Get rounding precision for internal WC calculations.
 * Will increase the precision of wc_get_price_decimals by 2 decimals, unless WC_ROUNDING_PRECISION is set to a higher number.
 *
 * @since 2.6.3
 * @return int
 */
function wc_get_rounding_precision()
{
    $precision = wc_get_price_decimals() + 2;
    if (absint(WC_ROUNDING_PRECISION) > $precision) {
        $precision = absint(WC_ROUNDING_PRECISION);
    }
    return $precision;
}
 /**
  * Get an array of all sale and regular prices from all variations. This is used for example when displaying the price range at variable product level or seeing if the variable product is on sale.
  *
  * Can be filtered by plugins which modify costs, but otherwise will include the raw meta costs unlike get_price() which runs costs through the woocommerce_get_price filter.
  * This is to ensure modified prices are not cached, unless intended.
  *
  * @since  2.7.0
  * @param  WC_Product
  * @param  bool $include_taxes If taxes should be calculated or not.
  */
 private function read_price_data(&$product, $include_taxes = false)
 {
     global $wp_filter;
     /**
      * Transient name for storing prices for this product (note: Max transient length is 45)
      * @since 2.5.0 a single transient is used per product for all prices, rather than many transients per product.
      */
     $transient_name = 'wc_var_prices_' . $product->get_id();
     /**
      * Create unique cache key based on the tax location (affects displayed/cached prices), product version and active price filters.
      * DEVELOPERS should filter this hash if offering conditonal pricing to keep it unique.
      * @var string
      */
     $price_hash = $include_taxes ? array(get_option('woocommerce_tax_display_shop', 'excl'), WC_Tax::get_rates()) : array(false);
     $filter_names = array('woocommerce_variation_prices_price', 'woocommerce_variation_prices_regular_price', 'woocommerce_variation_prices_sale_price');
     foreach ($filter_names as $filter_name) {
         if (!empty($wp_filter[$filter_name])) {
             $price_hash[$filter_name] = array();
             foreach ($wp_filter[$filter_name] as $priority => $callbacks) {
                 $price_hash[$filter_name][] = array_values(wp_list_pluck($callbacks, 'function'));
             }
         }
     }
     $price_hash[] = WC_Cache_Helper::get_transient_version('product');
     $price_hash = md5(json_encode(apply_filters('woocommerce_get_variation_prices_hash', $price_hash, $product, $include_taxes)));
     /**
      * $this->prices_array is an array of values which may have been modified from what is stored in transients - this may not match $transient_cached_prices_array.
      * If the value has already been generated, we don't need to grab the values again so just return them. They are already filtered.
      */
     if (!empty($this->prices_array[$price_hash])) {
         if ($include_taxes) {
             $product->set_variation_prices_including_taxes($this->prices_array[$price_hash]);
         } else {
             $product->set_variation_prices($this->prices_array[$price_hash]);
         }
         /**
          * No locally cached value? Get the data from the transient or generate it.
          */
     } else {
         // Get value of transient
         $transient_cached_prices_array = array_filter((array) json_decode(strval(get_transient($transient_name)), true));
         // If the product version has changed since the transient was last saved, reset the transient cache.
         if (empty($transient_cached_prices_array['version']) || WC_Cache_Helper::get_transient_version('product') !== $transient_cached_prices_array['version']) {
             $transient_cached_prices_array = array('version' => WC_Cache_Helper::get_transient_version('product'));
         }
         // If the prices are not stored for this hash, generate them and add to the transient.
         if (empty($transient_cached_prices_array[$price_hash])) {
             $prices = array();
             $regular_prices = array();
             $sale_prices = array();
             $variation_ids = $product->get_visible_children();
             foreach ($variation_ids as $variation_id) {
                 if ($variation = wc_get_product($variation_id)) {
                     $price = apply_filters('woocommerce_variation_prices_price', $variation->get_price('edit'), $variation, $product);
                     $regular_price = apply_filters('woocommerce_variation_prices_regular_price', $variation->get_regular_price('edit'), $variation, $product);
                     $sale_price = apply_filters('woocommerce_variation_prices_sale_price', $variation->get_sale_price('edit'), $variation, $product);
                     // Skip empty prices
                     if ('' === $price) {
                         continue;
                     }
                     // If sale price does not equal price, the product is not yet on sale
                     if ($sale_price === $regular_price || $sale_price !== $price) {
                         $sale_price = $regular_price;
                     }
                     // If we are getting prices for display, we need to account for taxes
                     if ($include_taxes) {
                         if ('incl' === get_option('woocommerce_tax_display_shop')) {
                             $price = '' === $price ? '' : wc_get_price_including_tax($variation, array('qty' => 1, 'price' => $price));
                             $regular_price = '' === $regular_price ? '' : wc_get_price_including_tax($variation, array('qty' => 1, 'price' => $regular_price));
                             $sale_price = '' === $sale_price ? '' : wc_get_price_including_tax($variation, array('qty' => 1, 'price' => $sale_price));
                         } else {
                             $price = '' === $price ? '' : wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $price));
                             $regular_price = '' === $regular_price ? '' : wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $regular_price));
                             $sale_price = '' === $sale_price ? '' : wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $sale_price));
                         }
                     }
                     $prices[$variation_id] = wc_format_decimal($price, wc_get_price_decimals());
                     $regular_prices[$variation_id] = wc_format_decimal($regular_price, wc_get_price_decimals());
                     $sale_prices[$variation_id] = wc_format_decimal($sale_price . '.00', wc_get_price_decimals());
                 }
             }
             asort($prices);
             asort($regular_prices);
             asort($sale_prices);
             $transient_cached_prices_array[$price_hash] = array('price' => $prices, 'regular_price' => $regular_prices, 'sale_price' => $sale_prices);
             set_transient($transient_name, json_encode($transient_cached_prices_array), DAY_IN_SECONDS * 30);
         }
         /**
          * Give plugins one last chance to filter the variation prices array which has been generated and store locally to the class.
          * This value may differ from the transient cache. It is filtered once before storing locally.
          */
         $this->prices_array[$price_hash] = apply_filters('woocommerce_variation_prices', $transient_cached_prices_array[$price_hash], $product, $include_taxes);
         if ($include_taxes) {
             $product->set_variation_prices_including_taxes($this->prices_array[$price_hash]);
         } else {
             $product->set_variation_prices($this->prices_array[$price_hash]);
         }
     }
 }
 /**
  * Function to include styles & script for 'Generate Coupon' page
  */
 public function generate_coupon_styles_and_scripts()
 {
     global $pagenow, $wp_scripts;
     if (empty($pagenow) || $pagenow != 'admin.php') {
         return;
     }
     if (empty($_GET['page']) || $_GET['page'] != 'woocommerce_smart_coupon_csv_import') {
         return;
     }
     if (!$this->is_wc_gte_21()) {
         return;
     }
     $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
     $jquery_version = isset($wp_scripts->registered['jquery-ui-core']->ver) ? $wp_scripts->registered['jquery-ui-core']->ver : '1.9.2';
     $locale = localeconv();
     $decimal = isset($locale['decimal_point']) ? $locale['decimal_point'] : '.';
     wp_enqueue_style('woocommerce_admin_menu_styles', $this->global_wc()->plugin_url() . '/assets/css/menu.css', array(), $this->global_wc()->version);
     wp_enqueue_style('woocommerce_admin_styles', $this->global_wc()->plugin_url() . '/assets/css/admin.css', array(), $this->global_wc()->version);
     wp_enqueue_style('jquery-ui-style', '//code.jquery.com/ui/' . $jquery_version . '/themes/smoothness/jquery-ui.css', array(), $jquery_version);
     $woocommerce_admin_params = array('i18n_decimal_error' => sprintf(__('Please enter in decimal (%s) format without thousand separators.', 'woocommerce'), $decimal), 'i18n_mon_decimal_error' => sprintf(__('Please enter in monetary decimal (%s) format without thousand separators and currency symbols.', 'woocommerce'), wc_get_price_decimal_separator()), 'i18n_country_iso_error' => __('Please enter in country code with two capital letters.', 'woocommerce'), 'i18_sale_less_than_regular_error' => __('Please enter in a value less than the regular price.', 'woocommerce'), 'decimal_point' => $decimal, 'mon_decimal_point' => wc_get_price_decimal_separator());
     $woocommerce_admin_meta_boxes_params = array('remove_item_notice' => __('Are you sure you want to remove the selected items? If you have previously reduced this item\'s stock, or this order was submitted by a customer, you will need to manually restore the item\'s stock.', 'woocommerce'), 'i18n_select_items' => __('Please select some items.', 'woocommerce'), 'i18n_do_refund' => __('Are you sure you wish to process this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_refund' => __('Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_tax' => __('Are you sure you wish to delete this tax column? This action cannot be undone.', 'woocommerce'), 'remove_item_meta' => __('Remove this item meta?', 'woocommerce'), 'remove_attribute' => __('Remove this attribute?', 'woocommerce'), 'name_label' => __('Name', 'woocommerce'), 'remove_label' => __('Remove', 'woocommerce'), 'click_to_toggle' => __('Click to toggle', 'woocommerce'), 'values_label' => __('Value(s)', 'woocommerce'), 'text_attribute_tip' => __('Enter some text, or some attributes by pipe (|) separating values.', 'woocommerce'), 'visible_label' => __('Visible on the product page', 'woocommerce'), 'used_for_variations_label' => __('Used for variations', 'woocommerce'), 'new_attribute_prompt' => __('Enter a name for the new attribute term:', 'woocommerce'), 'calc_totals' => __('Calculate totals based on order items, discounts, and shipping?', 'woocommerce'), 'calc_line_taxes' => __('Calculate line taxes? This will calculate taxes based on the customers country. If no billing/shipping is set it will use the store base country.', 'woocommerce'), 'copy_billing' => __('Copy billing information to shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'load_billing' => __('Load the customer\'s billing information? This will remove any currently entered billing information.', 'woocommerce'), 'load_shipping' => __('Load the customer\'s shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'featured_label' => __('Featured', 'woocommerce'), 'prices_include_tax' => esc_attr(get_option('woocommerce_prices_include_tax')), 'round_at_subtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'no_customer_selected' => __('No customer selected', 'woocommerce'), 'plugin_url' => $this->global_wc()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'order_item_nonce' => wp_create_nonce('order-item'), 'add_attribute_nonce' => wp_create_nonce('add-attribute'), 'save_attributes_nonce' => wp_create_nonce('save-attributes'), 'calc_totals_nonce' => wp_create_nonce('calc-totals'), 'get_customer_details_nonce' => wp_create_nonce('get-customer-details'), 'search_products_nonce' => wp_create_nonce('search-products'), 'grant_access_nonce' => wp_create_nonce('grant-access'), 'revoke_access_nonce' => wp_create_nonce('revoke-access'), 'add_order_note_nonce' => wp_create_nonce('add-order-note'), 'delete_order_note_nonce' => wp_create_nonce('delete-order-note'), 'calendar_image' => $this->global_wc()->plugin_url() . '/assets/images/calendar.png', 'post_id' => '', 'base_country' => $this->global_wc()->countries->get_base_country(), 'currency_format_num_decimals' => wc_get_price_decimals(), 'currency_format_symbol' => get_woocommerce_currency_symbol(), 'currency_format_decimal_sep' => esc_attr(wc_get_price_decimal_separator()), 'currency_format_thousand_sep' => esc_attr(wc_get_price_thousand_separator()), 'currency_format' => esc_attr(str_replace(array('%1$s', '%2$s'), array('%s', '%v'), get_woocommerce_price_format())), 'rounding_precision' => WC_ROUNDING_PRECISION, 'tax_rounding_mode' => WC_TAX_ROUNDING_MODE, 'product_types' => array_map('sanitize_title', get_terms('product_type', array('hide_empty' => false, 'fields' => 'names'))), 'i18n_download_permission_fail' => __('Could not grant access - the user may already have permission for this file or billing email is not set. Ensure the billing email is set, and the order has been saved.', 'woocommerce'), 'i18n_permission_revoke' => __('Are you sure you want to revoke access to this download?', 'woocommerce'), 'i18n_tax_rate_already_exists' => __('You cannot add the same tax rate twice!', 'woocommerce'), 'i18n_product_type_alert' => __('Your product has variations! Before changing the product type, it is a good idea to delete the variations to avoid errors in the stock reports.', 'woocommerce'));
     if ($this->is_wc_gte_23()) {
         if (!wp_script_is('wc-admin-coupon-meta-boxes')) {
             wp_enqueue_script('wc-admin-coupon-meta-boxes', $this->global_wc()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array('woocommerce_admin', 'wc-enhanced-select', 'wc-admin-meta-boxes'), $this->global_wc()->version);
             wp_localize_script('wc-admin-meta-boxes', 'woocommerce_admin_meta_boxes', $woocommerce_admin_meta_boxes_params);
             wp_enqueue_script('woocommerce_admin', $this->global_wc()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array('jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip'), $this->global_wc()->version);
             wp_localize_script('woocommerce_admin', 'woocommerce_admin', $woocommerce_admin_params);
         }
     } else {
         if (!wp_script_is('ajax-chosen', 'registered')) {
             wp_register_script('chosen', $this->global_wc()->plugin_url() . '/assets/js/chosen/chosen.jquery' . $suffix . '.js', array('jquery'), $this->global_wc()->version);
             wp_register_script('ajax-chosen', $this->global_wc()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . $suffix . '.js', array('jquery', 'woocommerce_admin', 'woocommerce_admin_meta_boxes', 'chosen'), $this->global_wc()->version);
         }
         wp_localize_script('woocommerce_admin', 'woocommerce_admin', $woocommerce_admin_params);
         wp_localize_script('woocommerce_admin_meta_boxes', 'woocommerce_admin_meta_boxes', $woocommerce_admin_meta_boxes_params);
         wp_enqueue_script('ajax-chosen');
         wp_enqueue_style('woocommerce_chosen_styles', $assets_path . 'css/chosen.css');
     }
 }
Example #15
0
 /**
  * Test wc_get_price_decimals().
  *
  * @since 2.4
  */
 public function test_wc_get_price_decimals()
 {
     $decimals = get_option('woocommerce_price_num_decimals');
     // defualt value
     $this->assertEquals(2, wc_get_price_decimals());
     update_option('woocommerce_price_num_decimals', '1');
     $this->assertEquals(1, wc_get_price_decimals());
     update_option('woocommerce_price_num_decimals', '-2');
     $this->assertEquals(2, wc_get_price_decimals());
     update_option('woocommerce_price_num_decimals', '2.50');
     $this->assertEquals(2, wc_get_price_decimals());
     update_option('woocommerce_price_num_decimals', $decimals);
 }
 /**
  * Get some setting values for the site that are useful for debugging
  * purposes. For full settings access, use the settings api.
  *
  * @return array
  */
 public function get_settings()
 {
     // Get a list of terms used for product/order taxonomies
     $term_response = array();
     $terms = get_terms('product_type', array('hide_empty' => 0));
     foreach ($terms as $term) {
         $term_response[$term->slug] = strtolower($term->name);
     }
     // Return array of useful settings for debugging.
     return array('api_enabled' => 'yes' === get_option('woocommerce_api_enabled'), 'force_ssl' => 'yes' === get_option('woocommerce_force_ssl_checkout'), 'currency' => get_woocommerce_currency(), 'currency_symbol' => get_woocommerce_currency_symbol(), 'currency_position' => get_option('woocommerce_currency_pos'), 'thousand_separator' => wc_get_price_thousand_separator(), 'decimal_separator' => wc_get_price_decimal_separator(), 'number_of_decimals' => wc_get_price_decimals(), 'geolocation_enabled' => in_array(get_option('woocommerce_default_customer_address'), array('geolocation_ajax', 'geolocation')), 'taxonomies' => $term_response);
 }
 /**
  * Returns the price (including tax). Uses customer 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_including_tax($qty = 1, $price = '')
 {
     if ($price === '') {
         $price = $this->get_price();
     }
     if ($this->is_taxable()) {
         if (get_option('woocommerce_prices_include_tax') === 'no') {
             $tax_rates = WC_Tax::get_rates($this->get_tax_class());
             $taxes = WC_Tax::calc_tax($price * $qty, $tax_rates, false);
             $tax_amount = WC_Tax::get_tax_total($taxes);
             $price = round($price * $qty + $tax_amount, wc_get_price_decimals());
         } else {
             $tax_rates = WC_Tax::get_rates($this->get_tax_class());
             $base_tax_rates = WC_Tax::get_base_tax_rates($this->tax_class);
             if (!empty(WC()->customer) && WC()->customer->is_vat_exempt()) {
                 $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true);
                 $base_tax_amount = array_sum($base_taxes);
                 $price = round($price * $qty - $base_tax_amount, wc_get_price_decimals());
                 /**
                  * 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.
                  */
             } elseif ($tax_rates !== $base_tax_rates && apply_filters('woocommerce_adjust_non_base_location_prices', true)) {
                 $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true);
                 $modded_taxes = WC_Tax::calc_tax($price * $qty - array_sum($base_taxes), $tax_rates, false);
                 $price = round($price * $qty - array_sum($base_taxes) + array_sum($modded_taxes), wc_get_price_decimals());
             } else {
                 $price = $price * $qty;
             }
         }
     } else {
         $price = $price * $qty;
     }
     return apply_filters('woocommerce_get_price_including_tax', $price, $qty, $this);
 }
 /**
  * Get the order data for the given ID.
  *
  * @since  2.5.0
  * @param  WC_Order $order The order instance
  * @return array
  */
 protected function get_order_data($order)
 {
     $order_post = get_post($order->id);
     $dp = wc_get_price_decimals();
     $order_data = array('id' => $order->id, 'order_number' => $order->get_order_number(), 'created_at' => $this->format_datetime($order_post->post_date_gmt), 'updated_at' => $this->format_datetime($order_post->post_modified_gmt), 'completed_at' => $this->format_datetime($order->completed_date, true), 'status' => $order->get_status(), 'currency' => $order->get_order_currency(), 'total' => wc_format_decimal($order->get_total(), $dp), 'subtotal' => wc_format_decimal($order->get_subtotal(), $dp), 'total_line_items_quantity' => $order->get_item_count(), 'total_tax' => wc_format_decimal($order->get_total_tax(), $dp), 'total_shipping' => wc_format_decimal($order->get_total_shipping(), $dp), 'cart_tax' => wc_format_decimal($order->get_cart_tax(), $dp), 'shipping_tax' => wc_format_decimal($order->get_shipping_tax(), $dp), 'total_discount' => wc_format_decimal($order->get_total_discount(), $dp), 'shipping_methods' => $order->get_shipping_method(), 'payment_details' => array('method_id' => $order->payment_method, 'method_title' => $order->payment_method_title, 'paid' => isset($order->paid_date)), 'billing_address' => array('first_name' => $order->billing_first_name, 'last_name' => $order->billing_last_name, 'company' => $order->billing_company, 'address_1' => $order->billing_address_1, 'address_2' => $order->billing_address_2, 'city' => $order->billing_city, 'state' => $order->billing_state, 'postcode' => $order->billing_postcode, 'country' => $order->billing_country, 'email' => $order->billing_email, 'phone' => $order->billing_phone), 'shipping_address' => array('first_name' => $order->shipping_first_name, 'last_name' => $order->shipping_last_name, 'company' => $order->shipping_company, 'address_1' => $order->shipping_address_1, 'address_2' => $order->shipping_address_2, 'city' => $order->shipping_city, 'state' => $order->shipping_state, 'postcode' => $order->shipping_postcode, 'country' => $order->shipping_country), 'note' => $order->customer_note, 'customer_ip' => $order->customer_ip_address, 'customer_user_agent' => $order->customer_user_agent, 'customer_id' => $order->get_user_id(), 'view_order_url' => $order->get_view_order_url(), 'line_items' => array(), 'shipping_lines' => array(), 'tax_lines' => array(), 'fee_lines' => array(), 'coupon_lines' => array());
     // add line items
     foreach ($order->get_items() as $item_id => $item) {
         $product = $order->get_product_from_item($item);
         $product_id = null;
         $product_sku = null;
         // Check if the product exists.
         if (is_object($product)) {
             $product_id = isset($product->variation_id) ? $product->variation_id : $product->id;
             $product_sku = $product->get_sku();
         }
         $meta = new WC_Order_Item_Meta($item, $product);
         $item_meta = array();
         foreach ($meta->get_formatted(null) as $meta_key => $formatted_meta) {
             $item_meta[] = array('key' => $meta_key, 'label' => $formatted_meta['label'], 'value' => $formatted_meta['value']);
         }
         $order_data['line_items'][] = array('id' => $item_id, 'subtotal' => wc_format_decimal($order->get_line_subtotal($item, false, false), $dp), 'subtotal_tax' => wc_format_decimal($item['line_subtotal_tax'], $dp), 'total' => wc_format_decimal($order->get_line_total($item, false, false), $dp), 'total_tax' => wc_format_decimal($item['line_tax'], $dp), 'price' => wc_format_decimal($order->get_item_total($item, false, false), $dp), 'quantity' => wc_stock_amount($item['qty']), 'tax_class' => !empty($item['tax_class']) ? $item['tax_class'] : null, 'name' => $item['name'], 'product_id' => $product_id, 'sku' => $product_sku, 'meta' => $item_meta);
     }
     // Add shipping.
     foreach ($order->get_shipping_methods() as $shipping_item_id => $shipping_item) {
         $order_data['shipping_lines'][] = array('id' => $shipping_item_id, 'method_id' => $shipping_item['method_id'], 'method_title' => $shipping_item['name'], 'total' => wc_format_decimal($shipping_item['cost'], $dp));
     }
     // Add taxes.
     foreach ($order->get_tax_totals() as $tax_code => $tax) {
         $order_data['tax_lines'][] = array('id' => $tax->id, 'rate_id' => $tax->rate_id, 'code' => $tax_code, 'title' => $tax->label, 'total' => wc_format_decimal($tax->amount, $dp), 'compound' => (bool) $tax->is_compound);
     }
     // Add fees.
     foreach ($order->get_fees() as $fee_item_id => $fee_item) {
         $order_data['fee_lines'][] = array('id' => $fee_item_id, 'title' => $fee_item['name'], 'tax_class' => !empty($fee_item['tax_class']) ? $fee_item['tax_class'] : null, 'total' => wc_format_decimal($order->get_line_total($fee_item), $dp), 'total_tax' => wc_format_decimal($order->get_line_tax($fee_item), $dp));
     }
     // Add coupons.
     foreach ($order->get_items('coupon') as $coupon_item_id => $coupon_item) {
         $order_data['coupon_lines'][] = array('id' => $coupon_item_id, 'code' => $coupon_item['name'], 'amount' => wc_format_decimal($coupon_item['discount_amount'], $dp));
     }
     $order_data = apply_filters('woocommerce_cli_order_data', $order_data);
     return $this->flatten_array($order_data);
 }
 /**
  * Get an individual variation's data
  *
  * @since  2.5.0
  * @param  WC_Product $product
  * @return array
  */
 private function get_variation_data($product)
 {
     $prices_precision = wc_get_price_decimals();
     $variations = array();
     foreach ($product->get_children() as $child_id) {
         $variation = $product->get_child($child_id);
         if (!$variation->exists()) {
             continue;
         }
         $variations[] = array('id' => $variation->get_variation_id(), 'created_at' => $this->format_datetime($variation->get_post_data()->post_date_gmt), 'updated_at' => $this->format_datetime($variation->get_post_data()->post_modified_gmt), 'downloadable' => $variation->is_downloadable(), 'virtual' => $variation->is_virtual(), 'permalink' => $variation->get_permalink(), 'sku' => $variation->get_sku(), 'price' => wc_format_decimal($variation->get_price(), $prices_precision), 'regular_price' => wc_format_decimal($variation->get_regular_price(), $prices_precision), 'sale_price' => $variation->get_sale_price() ? wc_format_decimal($variation->get_sale_price(), $prices_precision) : null, 'taxable' => $variation->is_taxable(), 'tax_status' => $variation->get_tax_status(), 'tax_class' => $variation->get_tax_class(), 'managing_stock' => $variation->managing_stock(), 'stock_quantity' => $variation->get_stock_quantity(), 'in_stock' => $variation->is_in_stock(), 'backordered' => $variation->is_on_backorder(), 'purchaseable' => $variation->is_purchasable(), 'visible' => $variation->variation_is_visible(), 'on_sale' => $variation->is_on_sale(), 'weight' => $variation->get_weight() ? wc_format_decimal($variation->get_weight(), 2) : null, 'dimensions' => array('length' => $variation->length, 'width' => $variation->width, 'height' => $variation->height, 'unit' => get_option('woocommerce_dimension_unit')), 'shipping_class' => $variation->get_shipping_class(), 'shipping_class_id' => 0 !== $variation->get_shipping_class_id() ? $variation->get_shipping_class_id() : null, 'image' => $this->get_images($variation), 'attributes' => $this->get_attributes($variation), 'downloads' => $this->get_downloads($variation), 'download_limit' => (int) $product->download_limit, 'download_expiry' => (int) $product->download_expiry);
     }
     return $variations;
 }
			<td><?php 
echo wc_get_price_decimal_separator();
?>
</td>
		</tr>
		<tr>
			<td data-export-label="Number of Decimals"><?php 
_e('Number of Decimals', 'woocommerce');
?>
</td>
			<td class="help"><?php 
echo wc_help_tip(__('The number of decimal points shown in displayed prices.', 'woocommerce'));
?>
</td>
			<td><?php 
echo wc_get_price_decimals();
?>
</td>
		</tr>
	</tbody>
</table>
<table class="wc_status_table widefat" cellspacing="0">
	<thead>
		<tr>
			<th colspan="3" data-export-label="API"><h2><?php 
_e('API', 'woocommerce');
?>
</h2></th>
		</tr>
	</thead>
	<tbody>
 /**
  * Calculate totals by looking at the contents of the order. Stores the totals and returns the orders final total.
  *
  * @since 2.2
  * @param  $and_taxes bool Calc taxes if true
  * @return float calculated grand total
  */
 public function calculate_totals($and_taxes = true)
 {
     $cart_subtotal = 0;
     $cart_total = 0;
     $fee_total = 0;
     $cart_subtotal_tax = 0;
     $cart_total_tax = 0;
     if ($and_taxes && wc_tax_enabled()) {
         $this->calculate_taxes();
     }
     // line items
     foreach ($this->get_items() as $item) {
         $cart_subtotal += wc_format_decimal(isset($item['line_subtotal']) ? $item['line_subtotal'] : 0);
         $cart_total += wc_format_decimal(isset($item['line_total']) ? $item['line_total'] : 0);
         $cart_subtotal_tax += wc_format_decimal(isset($item['line_subtotal_tax']) ? $item['line_subtotal_tax'] : 0);
         $cart_total_tax += wc_format_decimal(isset($item['line_tax']) ? $item['line_tax'] : 0);
     }
     $this->calculate_shipping();
     foreach ($this->get_fees() as $item) {
         $fee_total += $item['line_total'];
     }
     $this->set_total($cart_subtotal - $cart_total, 'cart_discount');
     $this->set_total($cart_subtotal_tax - $cart_total_tax, 'cart_discount_tax');
     $grand_total = round($cart_total + $fee_total + $this->get_total_shipping() + $this->get_cart_tax() + $this->get_shipping_tax(), wc_get_price_decimals());
     $this->set_total($grand_total, 'total');
     return $grand_total;
 }
Example #22
0
 /**
  * Auto-load in-accessible properties on demand.
  *
  * @param mixed $key
  * @return mixed
  */
 public function __get($key)
 {
     switch ($key) {
         case 'prices_include_tax':
             return wc_prices_include_tax();
             break;
         case 'round_at_subtotal':
             return 'yes' === get_option('woocommerce_tax_round_at_subtotal');
             break;
         case 'tax_display_cart':
             return get_option('woocommerce_tax_display_cart');
             break;
         case 'dp':
             return wc_get_price_decimals();
             break;
         case 'display_totals_ex_tax':
         case 'display_cart_ex_tax':
             return $this->tax_display_cart === 'excl';
             break;
         case 'cart_contents_weight':
             return $this->get_cart_contents_weight();
             break;
         case 'cart_contents_count':
             return $this->get_cart_contents_count();
             break;
         case 'tax':
             _deprecated_argument('WC_Cart->tax', '2.3', 'Use WC_Tax:: directly');
             $this->tax = new WC_Tax();
             return $this->tax;
         case 'discount_total':
             _deprecated_argument('WC_Cart->discount_total', '2.3', 'After tax coupons are no longer supported. For more information see: https://woocommerce.wordpress.com/2014/12/upcoming-coupon-changes-in-woocommerce-2-3/');
             return 0;
     }
 }
 /**
  * Calculate line total - useful for gateways.
  *
  * @param mixed $item
  * @param bool $inc_tax (default: false)
  * @param bool $round (default: true)
  * @return float
  */
 public function get_line_total($item, $inc_tax = false, $round = true)
 {
     // Check if we need to add line tax to the line total
     $line_total = $inc_tax ? $item['line_total'] + $item['line_tax'] : $item['line_total'];
     // Check if we need to round
     $line_total = $round ? round($line_total, wc_get_price_decimals()) : $line_total;
     return apply_filters('woocommerce_order_amount_line_total', $line_total, $this, $item, $inc_tax, $round);
 }
 /**
  * Enqueue scripts
  */
 public function admin_scripts()
 {
     global $wp_query, $post, $current_user;
     get_currentuserinfo();
     $screen = get_current_screen();
     $wc_screen_id = sanitize_title(__('WooCommerce', 'woocommerce'));
     $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
     // Register scripts
     wp_register_script('woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array('jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip'), WC_VERSION);
     wp_register_script('jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array('jquery'), '2.70', true);
     wp_register_script('jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array('jquery'), WC_VERSION, true);
     wp_register_script('accounting', WC()->plugin_url() . '/assets/js/admin/accounting' . $suffix . '.js', array('jquery'), '0.4.2');
     wp_register_script('round', WC()->plugin_url() . '/assets/js/admin/round' . $suffix . '.js', array('jquery'), WC_VERSION);
     wp_register_script('wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array('jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable'), WC_VERSION);
     wp_register_script('zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array('jquery'), WC_VERSION);
     wp_register_script('qrcode', WC()->plugin_url() . '/assets/js/jquery-qrcode/jquery.qrcode' . $suffix . '.js', array('jquery'), WC_VERSION);
     wp_register_script('stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array('jquery'), WC_VERSION);
     // Chosen is @deprecated (2.3) in favour of select2, but is registered for backwards compat
     wp_register_script('ajax-chosen', WC()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . $suffix . '.js', array('jquery', 'chosen'), WC_VERSION);
     wp_register_script('chosen', WC()->plugin_url() . '/assets/js/chosen/chosen.jquery' . $suffix . '.js', array('jquery'), WC_VERSION);
     // Select2 is the replacement for chosen
     wp_register_script('select2', WC()->plugin_url() . '/assets/js/select2/select2' . $suffix . '.js', array('jquery'), '3.5.2');
     wp_register_script('wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array('jquery', 'select2'), WC_VERSION);
     wp_localize_script('wc-enhanced-select', 'wc_enhanced_select_params', array('i18n_matches_1' => _x('One result is available, press enter to select it.', 'enhanced select', 'woocommerce'), 'i18n_matches_n' => _x('%qty% results are available, use up and down arrow keys to navigate.', 'enhanced select', 'woocommerce'), 'i18n_no_matches' => _x('No matches found', 'enhanced select', 'woocommerce'), 'i18n_ajax_error' => _x('Loading failed', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_1' => _x('Please enter 1 or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_n' => _x('Please enter %qty% or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_1' => _x('Please delete 1 character', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_n' => _x('Please delete %qty% characters', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_1' => _x('You can only select 1 item', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_n' => _x('You can only select %qty% items', 'enhanced select', 'woocommerce'), 'i18n_load_more' => _x('Loading more results&hellip;', 'enhanced select', 'woocommerce'), 'i18n_searching' => _x('Searching&hellip;', 'enhanced select', 'woocommerce'), 'ajax_url' => admin_url('admin-ajax.php'), 'search_products_nonce' => wp_create_nonce('search-products'), 'search_customers_nonce' => wp_create_nonce('search-customers')));
     // Accounting
     wp_localize_script('accounting', 'accounting_params', array('mon_decimal_point' => wc_get_price_decimal_separator()));
     // WooCommerce admin pages
     if (in_array($screen->id, wc_get_screen_ids())) {
         wp_enqueue_script('woocommerce_admin');
         wp_enqueue_script('iris');
         wp_enqueue_script('wc-enhanced-select');
         wp_enqueue_script('jquery-ui-sortable');
         wp_enqueue_script('jquery-ui-autocomplete');
         $locale = localeconv();
         $decimal = isset($locale['decimal_point']) ? $locale['decimal_point'] : '.';
         $params = array('i18n_decimal_error' => sprintf(__('Please enter in decimal (%s) format without thousand separators.', 'woocommerce'), $decimal), 'i18n_mon_decimal_error' => sprintf(__('Please enter in monetary decimal (%s) format without thousand separators and currency symbols.', 'woocommerce'), wc_get_price_decimal_separator()), 'i18n_country_iso_error' => __('Please enter in country code with two capital letters.', 'woocommerce'), 'i18_sale_less_than_regular_error' => __('Please enter in a value less than the regular price.', 'woocommerce'), 'decimal_point' => $decimal, 'mon_decimal_point' => wc_get_price_decimal_separator());
         wp_localize_script('woocommerce_admin', 'woocommerce_admin', $params);
     }
     // Edit product category pages
     if (in_array($screen->id, array('edit-product_cat'))) {
         wp_enqueue_media();
     }
     // Products
     if (in_array($screen->id, array('edit-product'))) {
         wp_enqueue_script('woocommerce_quick-edit', WC()->plugin_url() . '/assets/js/admin/quick-edit' . $suffix . '.js', array('jquery'), WC_VERSION);
     }
     // Meta boxes
     if (in_array($screen->id, array('product', 'edit-product'))) {
         wp_enqueue_media();
         wp_enqueue_script('wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION);
         wp_enqueue_script('wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION);
         $params = array('post_id' => isset($post->ID) ? $post->ID : '', 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'woocommerce_placeholder_img_src' => wc_placeholder_img_src(), 'add_variation_nonce' => wp_create_nonce('add-variation'), 'link_variation_nonce' => wp_create_nonce('link-variations'), 'delete_variations_nonce' => wp_create_nonce('delete-variations'), 'load_variations_nonce' => wp_create_nonce('load-variations'), 'save_variations_nonce' => wp_create_nonce('save-variations'), 'bulk_edit_variations_nonce' => wp_create_nonce('bulk-edit-variations'), 'i18n_link_all_variations' => esc_js(__('Are you sure you want to link all variations? This will create a new variation for each and every possible combination of variation attributes (max 50 per run).', 'woocommerce')), 'i18n_enter_a_value' => esc_js(__('Enter a value', 'woocommerce')), 'i18n_enter_a_value_fixed_or_percent' => esc_js(__('Enter a value (fixed or %)', 'woocommerce')), 'i18n_delete_all_variations' => esc_js(__('Are you sure you want to delete all variations? This cannot be undone.', 'woocommerce')), 'i18n_last_warning' => esc_js(__('Last warning, are you sure?', 'woocommerce')), 'i18n_choose_image' => esc_js(__('Choose an image', 'woocommerce')), 'i18n_set_image' => esc_js(__('Set variation image', 'woocommerce')), 'i18n_variation_added' => esc_js(__("variation added", 'woocommerce')), 'i18n_variations_added' => esc_js(__("variations added", 'woocommerce')), 'i18n_no_variations_added' => esc_js(__("No variations added", 'woocommerce')), 'i18n_remove_variation' => esc_js(__('Are you sure you want to remove this variation?', 'woocommerce')), 'i18n_scheduled_sale_start' => esc_js(__('Sale start date (YYYY-MM-DD format or leave blank)', 'woocommerce')), 'i18n_scheduled_sale_end' => esc_js(__('Sale end date  (YYYY-MM-DD format or leave blank)', 'woocommerce')), 'i18n_edited_variations' => esc_js(__('Save changes before changing page?', 'woocommerce')), 'i18n_variation_count_single' => esc_js(__('%qty% variation', 'woocommerce')), 'i18n_variation_count_plural' => esc_js(__('%qty% variations', 'woocommerce')), 'variations_per_page' => absint(apply_filters('woocommerce_admin_meta_boxes_variations_per_page', 10)));
         wp_localize_script('wc-admin-variation-meta-boxes', 'woocommerce_admin_meta_boxes_variations', $params);
     }
     if (in_array(str_replace('edit-', '', $screen->id), wc_get_order_types('order-meta-boxes'))) {
         wp_enqueue_script('wc-admin-order-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION);
         wp_enqueue_script('wc-admin-order-meta-boxes-modal', WC()->plugin_url() . '/assets/js/admin/order-backbone-modal' . $suffix . '.js', array('underscore', 'backbone', 'wc-admin-order-meta-boxes'), WC_VERSION);
         $params = array('countries' => json_encode(array_merge(WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states())), 'i18n_select_state_text' => esc_attr__('Select an option&hellip;', 'woocommerce'));
         wp_localize_script('wc-admin-order-meta-boxes', 'woocommerce_admin_meta_boxes_order', $params);
     }
     if (in_array($screen->id, array('shop_coupon', 'edit-shop_coupon'))) {
         wp_enqueue_script('wc-admin-coupon-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION);
     }
     if (in_array(str_replace('edit-', '', $screen->id), array_merge(array('shop_coupon', 'product'), wc_get_order_types('order-meta-boxes')))) {
         $params = array('remove_item_notice' => __('Are you sure you want to remove the selected items? If you have previously reduced this item\'s stock, or this order was submitted by a customer, you will need to manually restore the item\'s stock.', 'woocommerce'), 'i18n_select_items' => __('Please select some items.', 'woocommerce'), 'i18n_do_refund' => __('Are you sure you wish to process this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_refund' => __('Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_tax' => __('Are you sure you wish to delete this tax column? This action cannot be undone.', 'woocommerce'), 'remove_item_meta' => __('Remove this item meta?', 'woocommerce'), 'remove_attribute' => __('Remove this attribute?', 'woocommerce'), 'name_label' => __('Name', 'woocommerce'), 'remove_label' => __('Remove', 'woocommerce'), 'click_to_toggle' => __('Click to toggle', 'woocommerce'), 'values_label' => __('Value(s)', 'woocommerce'), 'text_attribute_tip' => __('Enter some text, or some attributes by pipe (|) separating values.', 'woocommerce'), 'visible_label' => __('Visible on the product page', 'woocommerce'), 'used_for_variations_label' => __('Used for variations', 'woocommerce'), 'new_attribute_prompt' => __('Enter a name for the new attribute term:', 'woocommerce'), 'calc_totals' => __('Calculate totals based on order items, discounts, and shipping?', 'woocommerce'), 'calc_line_taxes' => __('Calculate line taxes? This will calculate taxes based on the customers country. If no billing/shipping is set it will use the store base country.', 'woocommerce'), 'copy_billing' => __('Copy billing information to shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'load_billing' => __('Load the customer\'s billing information? This will remove any currently entered billing information.', 'woocommerce'), 'load_shipping' => __('Load the customer\'s shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'featured_label' => __('Featured', 'woocommerce'), 'prices_include_tax' => esc_attr(get_option('woocommerce_prices_include_tax')), 'round_at_subtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'no_customer_selected' => __('No customer selected', 'woocommerce'), 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'order_item_nonce' => wp_create_nonce('order-item'), 'add_attribute_nonce' => wp_create_nonce('add-attribute'), 'save_attributes_nonce' => wp_create_nonce('save-attributes'), 'calc_totals_nonce' => wp_create_nonce('calc-totals'), 'get_customer_details_nonce' => wp_create_nonce('get-customer-details'), 'search_products_nonce' => wp_create_nonce('search-products'), 'grant_access_nonce' => wp_create_nonce('grant-access'), 'revoke_access_nonce' => wp_create_nonce('revoke-access'), 'add_order_note_nonce' => wp_create_nonce('add-order-note'), 'delete_order_note_nonce' => wp_create_nonce('delete-order-note'), 'calendar_image' => WC()->plugin_url() . '/assets/images/calendar.png', 'post_id' => isset($post->ID) ? $post->ID : '', 'base_country' => WC()->countries->get_base_country(), 'currency_format_num_decimals' => wc_get_price_decimals(), 'currency_format_symbol' => get_woocommerce_currency_symbol(), 'currency_format_decimal_sep' => esc_attr(wc_get_price_decimal_separator()), 'currency_format_thousand_sep' => esc_attr(wc_get_price_thousand_separator()), 'currency_format' => esc_attr(str_replace(array('%1$s', '%2$s'), array('%s', '%v'), get_woocommerce_price_format())), 'rounding_precision' => WC_ROUNDING_PRECISION, 'tax_rounding_mode' => WC_TAX_ROUNDING_MODE, 'product_types' => array_map('sanitize_title', get_terms('product_type', array('hide_empty' => false, 'fields' => 'names'))), 'i18n_download_permission_fail' => __('Could not grant access - the user may already have permission for this file or billing email is not set. Ensure the billing email is set, and the order has been saved.', 'woocommerce'), 'i18n_permission_revoke' => __('Are you sure you want to revoke access to this download?', 'woocommerce'), 'i18n_tax_rate_already_exists' => __('You cannot add the same tax rate twice!', 'woocommerce'), 'i18n_product_type_alert' => __('Your product has variations! Before changing the product type, it is a good idea to delete the variations to avoid errors in the stock reports.', 'woocommerce'));
         wp_localize_script('wc-admin-meta-boxes', 'woocommerce_admin_meta_boxes', $params);
     }
     // Term ordering - only when sorting by term_order
     if ((strstr($screen->id, 'edit-pa_') || !empty($_GET['taxonomy']) && in_array($_GET['taxonomy'], apply_filters('woocommerce_sortable_taxonomies', array('product_cat')))) && !isset($_GET['orderby'])) {
         wp_register_script('woocommerce_term_ordering', WC()->plugin_url() . '/assets/js/admin/term-ordering' . $suffix . '.js', array('jquery-ui-sortable'), WC_VERSION);
         wp_enqueue_script('woocommerce_term_ordering');
         $taxonomy = isset($_GET['taxonomy']) ? wc_clean($_GET['taxonomy']) : '';
         $woocommerce_term_order_params = array('taxonomy' => $taxonomy);
         wp_localize_script('woocommerce_term_ordering', 'woocommerce_term_ordering_params', $woocommerce_term_order_params);
     }
     // Product sorting - only when sorting by menu order on the products page
     if (current_user_can('edit_others_pages') && $screen->id == 'edit-product' && isset($wp_query->query['orderby']) && $wp_query->query['orderby'] == 'menu_order title') {
         wp_enqueue_script('woocommerce_product_ordering', WC()->plugin_url() . '/assets/js/admin/product-ordering' . $suffix . '.js', array('jquery-ui-sortable'), WC_VERSION, true);
     }
     // Reports Pages
     if (in_array($screen->id, apply_filters('woocommerce_reports_screen_ids', array($wc_screen_id . '_page_wc-reports', 'toplevel_page_wc-reports', 'dashboard')))) {
         wp_enqueue_script('wc-reports', WC()->plugin_url() . '/assets/js/admin/reports' . $suffix . '.js', array('jquery', 'jquery-ui-datepicker'), WC_VERSION);
         wp_enqueue_script('flot', WC()->plugin_url() . '/assets/js/admin/jquery.flot' . $suffix . '.js', array('jquery'), WC_VERSION);
         wp_enqueue_script('flot-resize', WC()->plugin_url() . '/assets/js/admin/jquery.flot.resize' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION);
         wp_enqueue_script('flot-time', WC()->plugin_url() . '/assets/js/admin/jquery.flot.time' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION);
         wp_enqueue_script('flot-pie', WC()->plugin_url() . '/assets/js/admin/jquery.flot.pie' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION);
         wp_enqueue_script('flot-stack', WC()->plugin_url() . '/assets/js/admin/jquery.flot.stack' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION);
     }
     // API settings
     if ($wc_screen_id . '_page_wc-settings' === $screen->id && isset($_GET['section']) && 'keys' == $_GET['section']) {
         wp_enqueue_script('wc-api-keys', WC()->plugin_url() . '/assets/js/admin/api-keys' . $suffix . '.js', array('jquery', 'woocommerce_admin', 'underscore', 'backbone', 'qrcode', 'zeroclipboard'), WC_VERSION, true);
         wp_localize_script('wc-api-keys', 'woocommerce_admin_api_keys', array('ajax_url' => admin_url('admin-ajax.php'), 'update_api_nonce' => wp_create_nonce('update-api-key')));
     }
     // System status
     if ($wc_screen_id . '_page_wc-status' === $screen->id) {
         wp_enqueue_script('zeroclipboard');
     }
     if (in_array($screen->id, array('user-edit', 'profile'))) {
         wp_enqueue_script('wc-users', WC()->plugin_url() . '/assets/js/admin/users' . $suffix . '.js', array('jquery', 'wc-enhanced-select'), WC_VERSION, true);
         wp_localize_script('wc-users', 'wc_users_params', array('countries' => json_encode(array_merge(WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states())), 'i18n_select_state_text' => esc_attr__('Select an option&hellip;', 'woocommerce')));
     }
 }
 /**
  * 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' => $this->get_rate_id(), 'label' => '', 'cost' => '0', 'taxes' => '', 'calc_tax' => 'per_order', 'meta_data' => array(), 'package' => false));
     // ID and label are required
     if (!$args['id'] || !$args['label']) {
         return;
     }
     // Total up the 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 = 'per_item' === $args['calc_tax'] ? $this->get_taxes_per_item($args['cost']) : WC_Tax::calc_shipping_tax($total_cost, WC_Tax::get_shipping_tax_rates());
     }
     // Round the total cost after taxes have been calculated.
     $total_cost = wc_format_decimal($total_cost, wc_get_price_decimals());
     // Create rate object
     $rate = new WC_Shipping_Rate($args['id'], $args['label'], $total_cost, $taxes, $this->id);
     if (!empty($args['meta_data'])) {
         foreach ($args['meta_data'] as $key => $value) {
             $rate->add_meta_data($key, $value);
         }
     }
     // Store package data
     if ($args['package']) {
         $items_in_package = array();
         foreach ($args['package']['contents'] as $item) {
             $product = $item['data'];
             $items_in_package[] = $product->get_title() . ' &times; ' . $item['quantity'];
         }
         $rate->add_meta_data(__('Items', 'woocommerce'), implode(', ', $items_in_package));
     }
     $this->rates[$args['id']] = $rate;
 }
 /**
  * Round our totals correctly
  * @param  string $amount
  * @return string
  */
 private function round_chart_totals($amount)
 {
     if (is_array($amount)) {
         return array_map(array($this, 'round_chart_totals'), $amount);
     } else {
         return wc_format_decimal($amount, wc_get_price_decimals());
     }
 }
 /**
  * Calculate line total - useful for gateways.
  *
  * @param object $item
  * @param bool $inc_tax (default: false).
  * @param bool $round (default: true).
  * @return float
  */
 public function get_line_total($item, $inc_tax = false, $round = true)
 {
     $total = 0;
     if (is_callable(array($item, 'get_total'))) {
         // Check if we need to add line tax to the line total.
         $total = $inc_tax ? $item->get_total() + $item->get_total_tax() : $item->get_total();
         // Check if we need to round.
         $total = $round ? round($total, wc_get_price_decimals()) : $total;
     }
     return apply_filters('woocommerce_order_amount_line_total', $total, $this, $item, $inc_tax, $round);
 }
/**
 * Format the price with a currency symbol.
 *
 * @param float $price
 * @param array $args (default: array())
 * @return string
 */
function wc_price($price, $args = array())
{
    extract(apply_filters('wc_price_args', wp_parse_args($args, array('ex_tax_label' => false, 'currency' => '', 'decimal_separator' => wc_get_price_decimal_separator(), 'thousand_separator' => wc_get_price_thousand_separator(), 'decimals' => wc_get_price_decimals(), 'price_format' => get_woocommerce_price_format()))));
    $negative = $price < 0;
    $price = apply_filters('raw_woocommerce_price', floatval($negative ? $price * -1 : $price));
    $price = apply_filters('formatted_woocommerce_price', number_format($price, $decimals, $decimal_separator, $thousand_separator), $price, $decimals, $decimal_separator, $thousand_separator);
    if (apply_filters('woocommerce_price_trim_zeros', false) && $decimals > 0) {
        $price = wc_trim_zeros($price);
    }
    $formatted_price = ($negative ? '-' : '') . sprintf($price_format, '<span class="woocommerce-Price-currencySymbol">' . get_woocommerce_currency_symbol($currency) . '</span>', $price);
    $return = '<span class="woocommerce-Price-amount amount">' . $formatted_price . '</span>';
    if ($ex_tax_label && wc_tax_enabled()) {
        $return .= ' <small class="woocommerce-Price-taxLabel tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
    }
    return apply_filters('wc_price', $return, $price, $args);
}
 /**
  * Returns the price (including tax). Uses customer 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_including_tax($qty = 1, $price = '')
 {
     if ($price === '') {
         $price = $this->get_price();
     }
     if ($this->is_taxable()) {
         if (get_option('woocommerce_prices_include_tax') === 'no') {
             $tax_rates = WC_Tax::get_rates($this->get_tax_class());
             $taxes = WC_Tax::calc_tax($price * $qty, $tax_rates, false);
             $tax_amount = WC_Tax::get_tax_total($taxes);
             $price = round($price * $qty + $tax_amount, wc_get_price_decimals());
         } else {
             $tax_rates = WC_Tax::get_rates($this->get_tax_class());
             $base_tax_rates = WC_Tax::get_base_tax_rates($this->tax_class);
             if (!empty(WC()->customer) && WC()->customer->is_vat_exempt()) {
                 $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true);
                 $base_tax_amount = array_sum($base_taxes);
                 $price = round($price * $qty - $base_tax_amount, wc_get_price_decimals());
             } elseif ($tax_rates !== $base_tax_rates) {
                 $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true);
                 $modded_taxes = WC_Tax::calc_tax($price * $qty - array_sum($base_taxes), $tax_rates, false);
                 $price = round($price * $qty - array_sum($base_taxes) + array_sum($modded_taxes), wc_get_price_decimals());
             } else {
                 $price = $price * $qty;
             }
         }
     } else {
         $price = $price * $qty;
     }
     return apply_filters('woocommerce_get_price_including_tax', $price, $qty, $this);
 }
/**
 * Formal total costs - format to the number of decimal places for the base currency.
 *
 * @access public
 * @param mixed $number
 * @deprecated 2.1
 * @return string
 */
function woocommerce_format_total($number)
{
    _deprecated_function(__FUNCTION__, '2.1', 'wc_format_decimal()');
    return wc_format_decimal($number, wc_get_price_decimals(), false);
}