/**
  * Create a order.
  *
  * @since 2.4
  *
  * @return WC_Order Order object.
  */
 public static function create_order()
 {
     // Create product
     $product = WC_Helper_Product::create_simple_product();
     WC_Helper_Shipping::create_simple_flat_rate();
     $order_data = array('status' => 'pending', 'customer_id' => 1, 'customer_note' => '', 'total' => '');
     $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
     // Required, else wc_create_order throws an exception
     $order = wc_create_order($order_data);
     // Add order products
     $item_id = $order->add_product($product, 4);
     // Set billing address
     $billing_address = array('country' => 'US', 'first_name' => 'Jeroen', 'last_name' => 'Sormani', 'company' => 'WooCompany', 'address_1' => 'WooAddress', 'address_2' => '', 'postcode' => '123456', 'city' => 'WooCity', 'state' => 'NY', 'email' => '*****@*****.**', 'phone' => '555-32123');
     $order->set_address($billing_address, 'billing');
     // Add shipping costs
     $shipping_taxes = WC_Tax::calc_shipping_tax('10', WC_Tax::get_shipping_tax_rates());
     $order->add_shipping(new WC_Shipping_Rate('flat_rate_shipping', 'Flat rate shipping', '10', $shipping_taxes, 'flat_rate'));
     // Set payment gateway
     $payment_gateways = WC()->payment_gateways->payment_gateways();
     $order->set_payment_method($payment_gateways['bacs']);
     // Set totals
     $order->set_total(10, 'shipping');
     $order->set_total(0, 'cart_discount');
     $order->set_total(0, 'cart_discount_tax');
     $order->set_total(0, 'tax');
     $order->set_total(0, 'shipping_tax');
     $order->set_total(40, 'total');
     // 4 x $10 simple helper product
     return wc_get_order($order->id);
 }
    /**
     * Output widget.
     *
     * @see WP_Widget
     *
     * @param array $args
     * @param array $instance
     */
    public function widget($args, $instance)
    {
        global $wp, $wp_the_query;
        if (!is_post_type_archive('product') && !is_tax(get_object_taxonomies('product'))) {
            return;
        }
        if (!$wp_the_query->post_count) {
            return;
        }
        $min_price = isset($_GET['min_price']) ? esc_attr($_GET['min_price']) : '';
        $max_price = isset($_GET['max_price']) ? esc_attr($_GET['max_price']) : '';
        wp_enqueue_script('wc-price-slider');
        // Find min and max price in current result set
        $prices = $this->get_filtered_price();
        $min = floor($prices->min_price);
        $max = ceil($prices->max_price);
        if ($min === $max) {
            return;
        }
        $this->widget_start($args, $instance);
        if ('' === get_option('permalink_structure')) {
            $form_action = remove_query_arg(array('page', 'paged'), add_query_arg($wp->query_string, '', home_url($wp->request)));
        } else {
            $form_action = preg_replace('%\\/page/[0-9]+%', '', home_url(trailingslashit($wp->request)));
        }
        /**
         * Adjust max if the store taxes are not displayed how they are stored.
         * Min is left alone because the product may not be taxable.
         * Kicks in when prices excluding tax are displayed including tax.
         */
        if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) {
            $tax_classes = array_merge(array(''), WC_Tax::get_tax_classes());
            $class_max = $max;
            foreach ($tax_classes as $tax_class) {
                if ($tax_rates = WC_Tax::get_rates($tax_class)) {
                    $class_max = $max + WC_Tax::get_tax_total(WC_Tax::calc_exclusive_tax($max, $tax_rates));
                }
            }
            $max = $class_max;
        }
        echo '<form method="get" action="' . esc_url($form_action) . '">
			<div class="price_slider_wrapper">
				<div class="price_slider" style="display:none;"></div>
				<div class="price_slider_amount">
					<input type="text" id="min_price" name="min_price" value="' . esc_attr($min_price) . '" data-min="' . esc_attr(apply_filters('woocommerce_price_filter_widget_min_amount', $min)) . '" placeholder="' . esc_attr__('Min price', 'woocommerce') . '" />
					<input type="text" id="max_price" name="max_price" value="' . esc_attr($max_price) . '" data-max="' . esc_attr(apply_filters('woocommerce_price_filter_widget_max_amount', $max)) . '" placeholder="' . esc_attr__('Max price', 'woocommerce') . '" />
					<button type="submit" class="button">' . __('Filter', 'woocommerce') . '</button>
					<div class="price_label" style="display:none;">
						' . __('Price:', 'woocommerce') . ' <span class="from"></span> &mdash; <span class="to"></span>
					</div>
					' . wc_query_string_form_fields(null, array('min_price', 'max_price'), '', true) . '
					<div class="clear"></div>
				</div>
			</div>
		</form>';
        $this->widget_end($args);
    }
 /**
  * Create a order.
  *
  * @since 2.4
  *
  * @return WC_Order Order object.
  */
 public static function create_order($customer_id = 1)
 {
     // Create product
     $product = WC_Helper_Product::create_simple_product();
     WC_Helper_Shipping::create_simple_flat_rate();
     $order_data = array('status' => 'pending', 'customer_id' => $customer_id, 'customer_note' => '', 'total' => '');
     $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
     // Required, else wc_create_order throws an exception
     $order = wc_create_order($order_data);
     // Add order products
     $order->add_product($product, 4);
     // Set billing address
     $order->set_billing_first_name('Jeroen');
     $order->set_billing_last_name('Sormani');
     $order->set_billing_company('WooCompany');
     $order->set_billing_address_1('WooAddress');
     $order->set_billing_address_2('');
     $order->set_billing_city('WooCity');
     $order->set_billing_state('NY');
     $order->set_billing_postcode('123456');
     $order->set_billing_country('US');
     $order->set_billing_email('*****@*****.**');
     $order->set_billing_phone('555-32123');
     // Add shipping costs
     $shipping_taxes = WC_Tax::calc_shipping_tax('10', WC_Tax::get_shipping_tax_rates());
     $rate = new WC_Shipping_Rate('flat_rate_shipping', 'Flat rate shipping', '10', $shipping_taxes, 'flat_rate');
     $item = new WC_Order_Item_Shipping();
     $item->set_props(array('method_title' => $rate->label, 'method_id' => $rate->id, 'total' => wc_format_decimal($rate->cost), 'taxes' => $rate->taxes, 'meta_data' => $rate->get_meta_data()));
     $order->add_item($item);
     // Set payment gateway
     $payment_gateways = WC()->payment_gateways->payment_gateways();
     $order->set_payment_method($payment_gateways['bacs']);
     // Set totals
     $order->set_shipping_total(10);
     $order->set_discount_total(0);
     $order->set_discount_tax(0);
     $order->set_cart_tax(0);
     $order->set_shipping_tax(0);
     $order->set_total(40);
     // 4 x $10 simple helper product
     $order->save();
     return $order;
 }
 /**
  * Calculate shipping when this method is used standalone.
  */
 public function calculate_shipping($package)
 {
     $_tax = new WC_Tax();
     $taxes = array();
     $shipping_cost = 0;
     // This shipping method loops through products, adding up the cost
     if (sizeof($package['contents']) > 0) {
         foreach ($package['contents'] as $item_id => $values) {
             if ($values['quantity'] > 0) {
                 if ($values['data']->needs_shipping()) {
                     $rule = false;
                     $item_shipping_cost = 0;
                     if ($values['variation_id']) {
                         $rule = woocommerce_per_product_shipping_get_matching_rule($values['variation_id'], $package);
                     }
                     if ($rule === false) {
                         $rule = woocommerce_per_product_shipping_get_matching_rule($values['product_id'], $package);
                     }
                     if ($rule) {
                         $item_shipping_cost += $rule->rule_item_cost * $values['quantity'];
                         $item_shipping_cost += $rule->rule_cost;
                     } elseif ($this->cost === '0' || $this->cost > 0) {
                         // Use default
                         $item_shipping_cost += $this->cost * $values['quantity'];
                     } else {
                         // NO default and nothing found - abort
                         return;
                     }
                     // Fee
                     $item_shipping_cost += $this->get_fee($this->fee, $item_shipping_cost) * $values['quantity'];
                     $shipping_cost += $item_shipping_cost;
                     if (get_option('woocommerce_calc_taxes') == 'yes' && $this->tax_status == 'taxable') {
                         $rates = $_tax->get_shipping_tax_rates($values['data']->get_tax_class());
                         $item_taxes = $_tax->calc_shipping_tax($item_shipping_cost, $rates);
                         // Sum the item taxes
                         foreach (array_keys($taxes + $item_taxes) as $key) {
                             $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
                         }
                     }
                 }
             }
         }
     }
     // Add order shipping cost + tax
     if ($this->order_fee) {
         $order_fee = $this->get_fee($this->order_fee, $shipping_cost);
         $shipping_cost += $order_fee;
         if (get_option('woocommerce_calc_taxes') == 'yes' && $this->tax_status == 'taxable') {
             $rates = $_tax->get_shipping_tax_rates();
             $item_taxes = $_tax->calc_shipping_tax($order_fee, $rates);
             // Sum the item taxes
             foreach (array_keys($taxes + $item_taxes) as $key) {
                 $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
             }
         }
     }
     // Add rate
     $this->add_rate(array('id' => $this->id, 'label' => $this->title, 'cost' => $shipping_cost, 'taxes' => $taxes));
 }
 /**
  * Add a rate
  *
  * Add a shipping rate. If taxes are not set they will be calculated based on cost.
  *
  * @access public
  * @param array $args (default: array())
  * @return void
  */
 function add_rate($args = array())
 {
     global $woocommerce;
     $defaults = array('id' => '', 'label' => '', 'cost' => '0', 'taxes' => '', 'calc_tax' => 'per_order');
     $args = wp_parse_args($args, $defaults);
     extract($args);
     // Id and label are required
     if (!$id || !$label) {
         return;
     }
     // Handle cost
     $total_cost = is_array($cost) ? array_sum($cost) : $cost;
     // Taxes - if not an array and not set to false, calc tax based on cost and passed calc_tax variable
     // This saves shipping methods having to do complex tax calculations
     if (!is_array($taxes) && $taxes !== false && $total_cost > 0 && get_option('woocommerce_calc_taxes') == 'yes' && $this->tax_status == 'taxable') {
         $_tax = new WC_Tax();
         $taxes = array();
         switch ($calc_tax) {
             case "per_item":
                 // If we have an array of costs we can look up each items tax class and add tax accordingly
                 if (is_array($cost)) {
                     $cart = $woocommerce->cart->get_cart();
                     foreach ($cost as $cost_key => $amount) {
                         if (!isset($cart[$cost_key])) {
                             continue;
                         }
                         $_product = $cart[$cost_key]['data'];
                         $rates = $_tax->get_shipping_tax_rates($_product->get_tax_class());
                         $item_taxes = $_tax->calc_shipping_tax($amount, $rates);
                         // Sum the item taxes
                         foreach (array_keys($taxes + $item_taxes) as $key) {
                             $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
                         }
                     }
                     // Add any cost for the order - order costs are in the key 'order'
                     if (isset($cost['order'])) {
                         $rates = $_tax->get_shipping_tax_rates();
                         $item_taxes = $_tax->calc_shipping_tax($cost['order'], $rates);
                         // Sum the item taxes
                         foreach (array_keys($taxes + $item_taxes) as $key) {
                             $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0);
                         }
                     }
                 }
                 break;
             default:
                 $rates = $_tax->get_shipping_tax_rates();
                 $taxes = $_tax->calc_shipping_tax($total_cost, $rates);
                 break;
         }
     }
     $this->rates[] = new WC_Shipping_Rate($id, $label, $total_cost, $taxes, $this->id);
 }
 /**
  * Set tax class.
  *
  * @param string $value
  * @throws WC_Data_Exception
  */
 public function set_tax_class($value)
 {
     if ($value && !in_array($value, WC_Tax::get_tax_classes())) {
         $this->error('order_item_fee_invalid_tax_class', __('Invalid tax class', 'woocommerce'));
     }
     $this->set_prop('tax_class', $value);
 }
 /**
  * Gets order total - formatted for display.
  *
  * @return string
  */
 public function get_formatted_order_total($tax_display = '', $display_refunded = true)
 {
     $formatted_total = wc_price($this->get_total(), array('currency' => $this->get_order_currency()));
     $order_total = $this->get_total();
     $total_refunded = $this->get_total_refunded();
     $tax_string = '';
     // Tax for inclusive prices
     if (wc_tax_enabled() && 'incl' == $tax_display) {
         $tax_string_array = array();
         if ('itemized' == get_option('woocommerce_tax_total_display')) {
             foreach ($this->get_tax_totals() as $code => $tax) {
                 $tax_amount = $total_refunded && $display_refunded ? wc_price(WC_Tax::round($tax->amount - $this->get_total_tax_refunded_by_rate_id($tax->rate_id)), array('currency' => $this->get_order_currency())) : $tax->formatted_amount;
                 $tax_string_array[] = sprintf('%s %s', $tax_amount, $tax->label);
             }
         } else {
             $tax_amount = $total_refunded && $display_refunded ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax();
             $tax_string_array[] = sprintf('%s %s', wc_price($tax_amount, array('currency' => $this->get_order_currency())), WC()->countries->tax_or_vat());
         }
         if (!empty($tax_string_array)) {
             $tax_string = ' ' . sprintf(__('(Includes %s)', 'woocommerce'), implode(', ', $tax_string_array));
         }
     }
     if ($total_refunded && $display_refunded) {
         $formatted_total = '<del>' . strip_tags($formatted_total) . '</del> <ins>' . wc_price($order_total - $total_refunded, array('currency' => $this->get_order_currency())) . $tax_string . '</ins>';
     } else {
         $formatted_total .= $tax_string;
     }
     return apply_filters('woocommerce_get_formatted_order_total', $formatted_total, $this);
 }
 /**
  * Whenever a WooCommerce tax rate is saved, also save the tax rate's hidden status.
  *
  * Executed whenever a WooCommerce tax rate is added, updated or deleted.
  *
  * @param int $tax_rate_id The WooCommerce Tax Rate ID.
  */
 public function save_tax_rate_hidden_status()
 {
     // nonce and cap checks are copied from WC_AJAX::tax_rates_save_changes()
     // Use return instead of exit so that WooCommerce core will handle the AJAX error messages
     if (!isset($_POST['wc_tax_nonce'], $_POST['changes'])) {
         return;
     }
     $current_class = !empty($_POST['current_class']) ? $_POST['current_class'] : '';
     // This is sanitized seven lines later.
     if (!wp_verify_nonce($_POST['wc_tax_nonce'], 'wc_tax_nonce-class:' . $current_class)) {
         return;
     }
     // Check User Caps
     if (!current_user_can('manage_woocommerce')) {
         return;
     }
     $hidden_rates = array();
     $current_class = WC_Tax::format_tax_rate_class($current_class);
     $rates = WC_Tax::get_rates_for_tax_class($current_class);
     foreach ($rates as $tax_rate_id => $rate) {
         if (isset($_POST['tax_rate_hidden'][$tax_rate_id])) {
             // @codingStandardsIgnoreEnd
             $hidden_rates[$tax_rate_id] = true;
         } else {
             if (isset($hidden_rates[$tax_rate_id])) {
                 unset($hidden_rates[$tax_rate_id]);
             }
         }
     }
     wc_hidden_taxes()->set_option('hidden_rates', $hidden_rates);
 }
Example #9
0
 /**
  * Test some discount logic which has caused issues in the past.
  * Tickets:
  * 	https://github.com/woothemes/woocommerce/issues/10573
  *  https://github.com/woothemes/woocommerce/issues/10963
  *
  * Due to discounts being split amongst products in cart.
  */
 public function test_cart_get_discounted_price()
 {
     global $wpdb;
     // We need this to have the calculate_totals() method calculate totals
     if (!defined('WOOCOMMERCE_CHECKOUT')) {
         define('WOOCOMMERCE_CHECKOUT', true);
     }
     # Test case 1 #10963
     // Create dummy coupon - fixed cart, 1 value
     $coupon = WC_Helper_Coupon::create_coupon();
     // Add coupon
     WC()->cart->add_discount($coupon->code);
     // Create dummy product - price will be 10
     $product = WC_Helper_Product::create_simple_product();
     // Add product to cart x1, calc and test
     WC()->cart->add_to_cart($product->id, 1);
     WC()->cart->calculate_totals();
     $this->assertEquals('9.00', number_format(WC()->cart->total, 2, '.', ''));
     $this->assertEquals('1.00', number_format(WC()->cart->discount_cart, 2, '.', ''));
     // Add product to cart x2, calc and test
     WC()->cart->add_to_cart($product->id, 1);
     WC()->cart->calculate_totals();
     $this->assertEquals('19.00', number_format(WC()->cart->total, 2, '.', ''));
     $this->assertEquals('1.00', number_format(WC()->cart->discount_cart, 2, '.', ''));
     // Add product to cart x3, calc and test
     WC()->cart->add_to_cart($product->id, 1);
     WC()->cart->calculate_totals();
     $this->assertEquals('29.00', number_format(WC()->cart->total, 2, '.', ''));
     $this->assertEquals('1.00', number_format(WC()->cart->discount_cart, 2, '.', ''));
     // Clean up the cart
     WC()->cart->empty_cart();
     WC()->cart->remove_coupons();
     # Test case 2 #10573
     update_post_meta($product->id, '_regular_price', '29.95');
     update_post_meta($product->id, '_price', '29.95');
     update_post_meta($coupon->id, 'discount_type', 'percent');
     update_post_meta($coupon->id, 'coupon_amount', '10');
     update_option('woocommerce_prices_include_tax', 'yes');
     update_option('woocommerce_calc_taxes', 'yes');
     $tax_rate = array('tax_rate_country' => '', 'tax_rate_state' => '', 'tax_rate' => '10.0000', 'tax_rate_name' => 'TAX', 'tax_rate_priority' => '1', 'tax_rate_compound' => '0', 'tax_rate_shipping' => '1', 'tax_rate_order' => '1', 'tax_rate_class' => '');
     WC_Tax::_insert_tax_rate($tax_rate);
     $product = wc_get_product($product->id);
     WC()->cart->add_to_cart($product->id, 1);
     WC()->cart->add_discount($coupon->code);
     WC()->cart->calculate_totals();
     $cart_item = current(WC()->cart->get_cart());
     $this->assertEquals('24.51', number_format($cart_item['line_total'], 2, '.', ''));
     // Cleanup
     $wpdb->query("DELETE FROM {$wpdb->prefix}woocommerce_tax_rates");
     $wpdb->query("DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations");
     WC()->cart->empty_cart();
     WC()->cart->remove_coupons();
     update_option('woocommerce_prices_include_tax', 'no');
     update_option('woocommerce_calc_taxes', 'no');
     // Delete coupon
     WC_Helper_Coupon::delete_coupon($coupon->id);
     // Clean up product
     WC_Helper_Product::delete_product($product->id);
 }
Example #10
0
 function ywev_get_tax_classes()
 {
     if (version_compare(WOOCOMMERCE_VERSION, '2.3', '<')) {
         return array_filter(array_map('trim', explode("\n", get_option('woocommerce_tax_classes'))));
     } else {
         return WC_Tax::get_tax_classes();
     }
 }
 public function set_base_tax_rates($rates, $tax_class)
 {
     $location = WC_Tax::get_tax_location($tax_class);
     if (in_array($tax_class, array('virtual-rate', 'virtual-reduced-rate')) && isset($location[0]) && sizeof($location) === 4 && $location[0] !== WC()->countries->get_base_country()) {
         list($country, $state, $postcode, $city) = $location;
         $rates = WC_Tax::find_rates(array('country' => $country, 'state' => $state, 'postcode' => $postcode, 'city' => $city, 'tax_class' => $tax_class));
     }
     return $rates;
 }
 public static function woocommerce_get_price($price, $product)
 {
     global $post, $woocommerce;
     $baseprice = $price;
     $result = $baseprice;
     if ($post == null || !is_admin()) {
         if ($product->is_type('variation')) {
             $commission = WRP_Variations_Admin::get_commission($product, $product->variation_id);
         } else {
             $commission = self::get_commission($product);
         }
         if ($commission) {
             $baseprice = $product->get_regular_price();
             if ($product->get_sale_price() != $product->get_regular_price() && $product->get_sale_price() == $product->price) {
                 if (get_option("wrp-baseprice", "regular") == "sale") {
                     $baseprice = $product->get_sale_price();
                 }
             }
             $product_price = $baseprice;
             $type = get_option("wrp-method", "rate");
             $result = 0;
             if ($type == "rate") {
                 // if rate and price includes taxes
                 if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
                     $_tax = new WC_Tax();
                     $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
                     $taxes = $_tax->calc_tax($baseprice, $tax_rates, true);
                     $product_price = $_tax->round($baseprice - array_sum($taxes));
                 }
                 $result = self::bcmul($product_price, $commission, WOO_ROLE_PRICING_DECIMALS);
                 if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
                     $_tax = new WC_Tax();
                     $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
                     $taxes = $_tax->calc_tax($result, $tax_rates, false);
                     // important false
                     $result = $_tax->round($result + array_sum($taxes));
                 }
             } else {
                 $result = self::bcsub($product_price, $commission, WOO_ROLE_PRICING_DECIMALS);
             }
         }
     }
     return $result;
 }
 public function tax_classes()
 {
     $tax_classes = WC_Tax::get_tax_classes();
     $classes_options = array();
     if (!empty($tax_classes)) {
         foreach ($tax_classes as $class) {
             $classes_options[sanitize_title($class)] = esc_html($class);
         }
     }
     return $classes_options;
 }
 /**
  * Returns base tax rates for all tax classes
  * @return array
  */
 public static function tax_rates()
 {
     $rates = array();
     foreach (self::tax_classes() as $class => $label) {
         if ($rate = WC_Tax::get_base_tax_rates($class)) {
             // WC_Tax returns a assoc array with int as keys = world of pain in js
             // possibly change $key to $rate['id']
             $rates[$class] = $rate;
         }
     }
     return $rates;
 }
 public static function woocommerce_get_price($price, $product)
 {
     global $post, $woocommerce;
     $baseprice = $price;
     $result = $baseprice;
     if ($post == null || !is_admin()) {
         $roleprice = self::get_role_price($product);
         if (empty($roleprice)) {
             $regularprice = $product->get_regular_price();
             if (!empty($regularprice)) {
                 $baseprice = $regularprice;
             }
             if ($product->get_sale_price() != $product->get_regular_price() && $product->get_sale_price() == $product->price) {
                 if (get_option("wrp-baseprice", "regular") == "sale") {
                     $baseprice = $product->get_sale_price();
                 }
             }
             $product_price = $baseprice;
         } else {
             $baseprice = $roleprice;
             $product_price = $roleprice;
         }
         $result = 0;
         if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
             $_tax = new WC_Tax();
             $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
             $taxes = $_tax->calc_tax($baseprice, $tax_rates, true);
             $product_price = $_tax->round($baseprice - array_sum($taxes));
         }
         $result = $product_price;
         if ($product->is_taxable() && get_option('woocommerce_prices_include_tax') == 'yes') {
             $_tax = new WC_Tax();
             $tax_rates = $_tax->get_shop_base_rate($product->tax_class);
             $taxes = $_tax->calc_tax($result, $tax_rates, false);
             // important false
             $result = $_tax->round($result + array_sum($taxes));
         }
     }
     return $result;
 }
Example #16
0
 /**
  * calculate_shipping function.
  *
  * @access public
  *
  * @param mixed $package
  *
  * @return void
  */
 public function calculate_shipping($package)
 {
     $products = $package['contents'];
     $destination_country = isset($package['destination']['country']) ? $package['destination']['country'] : '';
     $destination_state = isset($package['destination']['state']) ? $package['destination']['state'] : '';
     $amount = 0.0;
     if ($products) {
         $amount = $this->calculate_per_seller($products, $destination_country, $destination_state);
     }
     $tax_rate = $this->tax_status == 'none' ? false : '';
     if ($tax_rate === '') {
         $rates = WC_Tax::get_shipping_tax_rates();
         $taxRate = reset($rates);
         $taxkey = key($rates);
         $tax_rates = array();
         $shippingTaxes = 0;
         $price = $this->calculate_per_seller_prices($products, $destination_country, $destination_state);
         //var_dump($price);
         // var_dump($rates);
         if (!empty($price)) {
             foreach ($price as $seller_id => $value) {
                 //TODO: Check if taxxing from same state;
                 //var_dump($_product->post->post_author);
                 $country_obj = new WC_Countries();
                 $countries = $country_obj->countries;
                 $states = $country_obj->states;
                 $selleraddress = dokan_get_seller_address($seller_id, true);
                 $sellerState = $selleraddress['state'];
                 $stateCode = array_search(ucfirst(strtolower($sellerState)), $states['US']);
                 if ($stateCode !== false) {
                     $sellerState = $stateCode;
                 }
                 $location = WC()->customer->get_taxable_address();
                 $buyerState = $location[1];
                 if ($buyerState == $sellerState) {
                     $shippingCost = array_sum($value['addition_price']) + $value['default'] + array_sum($value['qty']) + $value['add_product'] + (isset($value['state_rates']) ? $value['state_rates'] : 0);
                     $shippingTaxes += $shippingCost * $taxRate['rate'] / 100;
                     //var_dump($shippingCost, $taxRate);
                 }
             }
         }
         $tax_rate[$taxkey] = $shippingTaxes;
         //var_dump($tax_rate);
     }
     $rate = array('id' => $this->id, 'label' => $this->title, 'cost' => $amount, 'taxes' => $tax_rate);
     // Register the rate
     $this->add_rate($rate);
 }
 /**
  * add_eu_countries_vat_rates.
  *
  * @version 2.3.10
  * @since   2.3.10
  */
 function add_eu_countries_vat_rates()
 {
     if (!isset($_POST['add_eu_countries_vat_rates'])) {
         return;
     }
     if (!is_super_admin() && !is_shop_manager()) {
         return;
     }
     $loop = 0;
     foreach (wcj_get_european_union_countries_with_vat() as $country => $rate) {
         $tax_rate = array('tax_rate_country' => $country, 'tax_rate' => $rate, 'tax_rate_name' => isset($_POST['wcj_tax_name']) ? $_POST['wcj_tax_name'] : __('VAT', 'woocommerce'), 'tax_rate_priority' => 1, 'tax_rate_compound' => 0, 'tax_rate_shipping' => 1, 'tax_rate_order' => $loop++, 'tax_rate_class' => '');
         $tax_rate_id = WC_Tax::_insert_tax_rate($tax_rate);
         WC_Tax::_update_tax_rate_postcodes($tax_rate_id, '');
         WC_Tax::_update_tax_rate_cities($tax_rate_id, '');
     }
 }
Example #18
0
 /**
  * Get tax row amounts with or without compound taxes includes.
  *
  * @return float price
  */
 public function get_taxes_total($compound = true)
 {
     $total = 0;
     foreach ($this->taxes as $key => $tax) {
         if (!$compound && $this->tax->is_compound($key)) {
             continue;
         }
         $total += $tax;
     }
     foreach ($this->shipping_taxes as $key => $tax) {
         if (!$compound && $this->tax->is_compound($key)) {
             continue;
         }
         $total += $tax;
     }
     return $total;
 }
Example #19
0
 public function install_standard_rates()
 {
     //  delete previous inserted standard rates
     $tax_rates = $this->get_tax_rates();
     foreach ($tax_rates as $tax_rate) {
         $tax_rate_name = sprintf("EU VAT (%s)", $tax_rate->tax_rate_country);
         if (0 == strpos($tax_rate->tax_rate_name, $tax_rate_name)) {
             WC_Tax::_delete_tax_rate($tax_rate->tax_rate_id);
         }
     }
     foreach ($this->tax_rates_data as $key => $value) {
         $tax_rate = array('tax_rate_country' => $key, 'tax_rate_state' => '*', 'tax_rate' => $value["standard_rate"], 'tax_rate_name' => sprintf("EU VAT (%s) %s%%", $key, $value["standard_rate"]), 'tax_rate_priority' => 1, 'tax_rate_compound' => 1, 'tax_rate_shipping' => 1, 'tax_rate_class' => '');
         $tax_rate_id = WC_Tax::_insert_tax_rate($tax_rate);
         WC_Tax::_update_tax_rate_postcodes($tax_rate_id, wc_clean('*'));
         WC_Tax::_update_tax_rate_cities($tax_rate_id, wc_clean('*'));
     }
 }
Example #20
0
 /**
  * Get tax row amounts with or without compound taxes includes.
  *
  * @param  boolean $compound True if getting compound taxes
  * @param  boolean $display  True if getting total to display
  * @return float price
  */
 public function get_taxes_total($compound = true, $display = true)
 {
     $total = 0;
     foreach ($this->taxes as $key => $tax) {
         if (!$compound && $this->tax->is_compound($key)) {
             continue;
         }
         $total += $tax;
     }
     foreach ($this->shipping_taxes as $key => $tax) {
         if (!$compound && $this->tax->is_compound($key)) {
             continue;
         }
         $total += $tax;
     }
     if ($display) {
         $total = wc_round_tax_total($total);
     }
     return apply_filters('woocommerce_cart_taxes_total', $total, $compound, $display, $this);
 }
 /**
  * Get tax row amounts with or without compound taxes includes.
  * @param  boolean $compound True if getting compound taxes
  * @param  boolean $display  True if getting total to display
  * @return float price
  */
 public function get_taxes_total($compound = true, $display = true)
 {
     $total = 0;
     foreach ($this->taxes as $key => $tax) {
         if (!$compound && $this->tax->is_compound($key)) {
             continue;
         }
         $total += $tax;
     }
     foreach ($this->shipping_taxes as $key => $tax) {
         if (!$compound && $this->tax->is_compound($key)) {
             continue;
         }
         $total += $tax;
     }
     if ($display) {
         return wc_round_tax_total($total);
     } else {
         return $total;
     }
 }
Example #22
0
 /**
  * copy of import function: WC_Tax_Rate_Importer->import()
  * https://github.com/woothemes/woocommerce/blob/master/includes/admin/importers/class-wc-tax-rate-importer.php
  */
 private function import_dummy_tax()
 {
     // clear tax rate tables
     global $wpdb;
     $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates");
     $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations");
     $file = WC_POS_PLUGIN_PATH . 'tests/data/sample_tax_rates.csv';
     $delimiter = ',';
     $loop = 0;
     if (($handle = fopen($file, "r")) !== false) {
         $header = fgetcsv($handle, 0, $delimiter);
         if (10 === sizeof($header)) {
             while (($row = fgetcsv($handle, 0, $delimiter)) !== false) {
                 list($country, $state, $postcode, $city, $rate, $name, $priority, $compound, $shipping, $class) = $row;
                 $tax_rate = array('tax_rate_country' => $country, 'tax_rate_state' => $state, 'tax_rate' => $rate, 'tax_rate_name' => $name, 'tax_rate_priority' => $priority, 'tax_rate_compound' => $compound ? 1 : 0, 'tax_rate_shipping' => $shipping ? 1 : 0, 'tax_rate_order' => $loop++, 'tax_rate_class' => $class);
                 $tax_rate_id = WC_Tax::_insert_tax_rate($tax_rate);
                 WC_Tax::_update_tax_rate_postcodes($tax_rate_id, wc_clean($postcode));
                 WC_Tax::_update_tax_rate_cities($tax_rate_id, wc_clean($city));
             }
         }
         fclose($handle);
     }
 }
 private function calc_tax_rate($product)
 {
     static $tax_rates = array();
     $item_tax_rates = array();
     $compound_tax_rates = 0;
     $regular_tax_rates = 0;
     if (empty($tax_rates[$product->get_tax_class()])) {
         $tax_rates[$product->get_tax_class()] = WC_Tax::get_rates($product->get_tax_class());
     }
     $item_tax_rates = $tax_rates[$product->get_tax_class()];
     $regular_tax_rates = $compound_tax_rates = 0;
     foreach ($item_tax_rates as $key => $rate) {
         if ($rate['compound'] == 'yes') {
             $compound_tax_rates = $compound_tax_rates + $rate['rate'];
         } else {
             $regular_tax_rates = $regular_tax_rates + $rate['rate'];
         }
     }
     $regular_tax_rate = 1 + $regular_tax_rates / 100;
     $compound_tax_rate = 1 + $compound_tax_rates / 100;
     $the_rate = 0;
     foreach ($item_tax_rates as $key => $rate) {
         if (!isset($taxes[$key])) {
             $taxes[$key] = 0;
         }
         $the_rate = $rate['rate'];
         // 100;
         if ($rate['compound'] == 'yes') {
             //$the_price = $price;
             //    $the_rate  = $the_rate / $compound_tax_rate;
         } else {
             //$the_price = $non_compound_price;
             //    $the_rate  = $the_rate / $regular_tax_rate;
         }
     }
     return $the_rate;
 }
 public function __construct()
 {
     $this->order = new WC_Order();
     $this->type = 'preview';
     $this->number = get_option('wc_gzdp_invoice_simple') + 1;
     $this->recipient = array('firstname' => _x('Max', 'invoices-preview', 'woocommerce-germanized-pro'), 'lastname' => _x('Mustermann', 'invoices-preview', 'woocommerce-germanized-pro'));
     $this->address = implode('<br/>', array(_x('Max Mustermann', 'invoices-preview', 'woocommerce-germanized-pro'), _x('Musterstraße 35', 'invoices-preview', 'woocommerce-germanized-pro'), _x('12209 Musterstadt', 'invoices-preview', 'woocommerce-germanized-pro')));
     $base_rate = WC_Tax::get_shop_base_rate();
     $base_rate_id = key($base_rate);
     $calc_tax = true;
     if (get_option('woocommerce_gzd_small_enterprise') == 'yes') {
         $calc_tax = false;
     }
     $this->items = array();
     $total = 0;
     $total_tax = 0;
     $shipping = 0;
     for ($i = 0; $i < 30; $i++) {
         $qty = 1;
         $subtotal_gross = 35.95;
         $subtotal_tax = $calc_tax ? array_sum(WC_Tax::calc_tax($subtotal_gross, $base_rate, true)) : 0;
         $subtotal_net = $subtotal_gross - $subtotal_tax;
         $subtotal = $subtotal_net;
         $item_total = $qty * $subtotal;
         $item_tax = $qty * $subtotal_tax;
         $item = array('name' => _x('Testprodukt', 'invoices-preview', 'woocommerce-germanized-pro'), 'item_meta' => array(), 'type' => 'line_item', 'qty' => $qty, 'line_total' => $item_total, 'line_subtotal' => $subtotal, 'line_tax' => $item_tax, 'line_subtotal_tax' => $subtotal_tax);
         $total += $subtotal_gross;
         $total_tax += $item_tax;
         array_push($this->items, $item);
     }
     $this->totals = array('subtotal' => $total - $shipping - $total_tax, 'total' => $total, 'shipping' => $shipping, 'tax' => $total_tax, 'discount' => 0);
     if ($calc_tax) {
         $tax_totals = array('amount' => $total_tax, 'rate_id' => $base_rate_id, 'formatted_amount' => wc_price($total_tax));
         $this->tax_totals = array();
         $this->tax_totals['DE'] = (object) $tax_totals;
     }
 }
 /**
  * Save shipping and tax options
  */
 public function wc_setup_shipping_taxes_save()
 {
     check_admin_referer('wc-setup');
     $woocommerce_calc_shipping = isset($_POST['woocommerce_calc_shipping']) ? 'yes' : 'no';
     $woocommerce_calc_taxes = isset($_POST['woocommerce_calc_taxes']) ? 'yes' : 'no';
     update_option('woocommerce_calc_shipping', $woocommerce_calc_shipping);
     update_option('woocommerce_calc_taxes', $woocommerce_calc_taxes);
     update_option('woocommerce_prices_include_tax', sanitize_text_field($_POST['woocommerce_prices_include_tax']));
     if ('yes' === $woocommerce_calc_shipping && !empty($_POST['shipping_cost_domestic'])) {
         // Delete existing settings if they exist
         delete_option('woocommerce_flat_rate_settings');
         // Init rate and settings
         $shipping_method = new WC_Shipping_Flat_Rate();
         $costs = array();
         $costs[] = wc_format_decimal(sanitize_text_field($_POST['shipping_cost_domestic']));
         if ($item_cost = sanitize_text_field($_POST['shipping_cost_domestic_item'])) {
             $costs[] = $item_cost . ' * [qty]';
         }
         $shipping_method->settings['cost'] = implode(' + ', array_filter($costs));
         $shipping_method->settings['enabled'] = 'yes';
         $shipping_method->settings['type'] = 'order';
         $shipping_method->settings['availability'] = 'specific';
         $shipping_method->settings['countries'] = array(WC()->countries->get_base_country());
         update_option($shipping_method->plugin_id . $shipping_method->id . '_settings', $shipping_method->settings);
     }
     if ('yes' === $woocommerce_calc_shipping && !empty($_POST['shipping_cost_international'])) {
         // Delete existing settings if they exist
         delete_option('woocommerce_international_delivery_settings');
         // Init rate and settings
         $shipping_method = new WC_Shipping_International_Delivery();
         $costs = array();
         $costs[] = wc_format_decimal(sanitize_text_field($_POST['shipping_cost_international']));
         if ($item_cost = sanitize_text_field($_POST['shipping_cost_international_item'])) {
             $costs[] = $item_cost . ' * [qty]';
         }
         $shipping_method->settings['cost'] = implode(' + ', array_filter($costs));
         $shipping_method->settings['enabled'] = 'yes';
         $shipping_method->settings['type'] = 'order';
         if (!empty($_POST['shipping_cost_domestic'])) {
             $shipping_method->settings['availability'] = 'excluding';
             $shipping_method->settings['countries'] = array(WC()->countries->get_base_country());
         }
         update_option($shipping_method->plugin_id . $shipping_method->id . '_settings', $shipping_method->settings);
     }
     if ('yes' === $woocommerce_calc_taxes && !empty($_POST['woocommerce_import_tax_rates'])) {
         $locale_info = (include WC()->plugin_path() . '/i18n/locale-info.php');
         $tax_rates = array();
         $country = WC()->countries->get_base_country();
         $state = WC()->countries->get_base_state();
         if (isset($locale_info[$country])) {
             if (isset($locale_info[$country]['tax_rates'][$state])) {
                 $tax_rates = $locale_info[$country]['tax_rates'][$state];
             } elseif (isset($locale_info[$country]['tax_rates'][''])) {
                 $tax_rates = $locale_info[$country]['tax_rates'][''];
             }
             if (isset($locale_info[$country]['tax_rates']['*'])) {
                 $tax_rates = array_merge($locale_info[$country]['tax_rates']['*'], $tax_rates);
             }
         }
         if ($tax_rates) {
             $loop = 0;
             foreach ($tax_rates as $rate) {
                 $tax_rate = array('tax_rate_country' => $rate['country'], 'tax_rate_state' => $rate['state'], 'tax_rate' => $rate['rate'], 'tax_rate_name' => $rate['name'], 'tax_rate_priority' => isset($rate['priority']) ? absint($rate['priority']) : 1, 'tax_rate_compound' => 0, 'tax_rate_shipping' => $rate['shipping'] ? 1 : 0, 'tax_rate_order' => $loop++, 'tax_rate_class' => '');
                 WC_Tax::_insert_tax_rate($tax_rate);
             }
         }
     }
     wp_redirect(esc_url_raw($this->get_next_step_link()));
     exit;
 }
 /**
  * Returns the price (excluding tax) - ignores tax_class filters since the price may *include* tax and thus needs subtracting.
  * Uses store base tax rates. Can work for a specific $qty for more accurate taxes.
  *
  * @param  string $price to calculate, left blank to just use get_price()
  * @return string
  */
 public function get_price_excluding_tax($qty = 1, $price = '')
 {
     if ($price === '') {
         $price = $this->get_price();
     }
     if ($this->is_taxable() && get_option('woocommerce_prices_include_tax') === 'yes') {
         $tax_rates = WC_Tax::get_base_tax_rates($this->tax_class);
         $taxes = WC_Tax::calc_tax($price * $qty, $tax_rates, true);
         $price = WC_Tax::round($price * $qty - array_sum($taxes));
     } else {
         $price = $price * $qty;
     }
     return apply_filters('woocommerce_get_price_excluding_tax', $price, $qty, $this);
 }
 /**
  * Update tax lines at order level by looking at the line item taxes themselves.
  *
  * @return bool success or fail
  */
 public function update_taxes()
 {
     $order_taxes = array();
     $order_shipping_taxes = array();
     foreach ($this->get_items(array('line_item', 'fee')) as $item_id => $item) {
         $line_tax_data = maybe_unserialize($item['line_tax_data']);
         if (isset($line_tax_data['total'])) {
             foreach ($line_tax_data['total'] as $tax_rate_id => $tax) {
                 if (!isset($order_taxes[$tax_rate_id])) {
                     $order_taxes[$tax_rate_id] = 0;
                 }
                 $order_taxes[$tax_rate_id] += $tax;
             }
         }
     }
     foreach ($this->get_items(array('shipping')) as $item_id => $item) {
         $line_tax_data = maybe_unserialize($item['taxes']);
         if (isset($line_tax_data)) {
             foreach ($line_tax_data as $tax_rate_id => $tax) {
                 if (!isset($order_shipping_taxes[$tax_rate_id])) {
                     $order_shipping_taxes[$tax_rate_id] = 0;
                 }
                 $order_shipping_taxes[$tax_rate_id] += $tax;
             }
         }
     }
     // Remove old existing tax rows
     $this->remove_order_items('tax');
     // Now merge to keep tax rows
     foreach (array_keys($order_taxes + $order_shipping_taxes) as $tax_rate_id) {
         $this->add_tax($tax_rate_id, isset($order_taxes[$tax_rate_id]) ? $order_taxes[$tax_rate_id] : 0, isset($order_shipping_taxes[$tax_rate_id]) ? $order_shipping_taxes[$tax_rate_id] : 0);
     }
     // Save tax totals
     $this->set_total(WC_Tax::round(array_sum($order_shipping_taxes)), 'shipping_tax');
     $this->set_total(WC_Tax::round(array_sum($order_taxes)), 'tax');
     return true;
 }
 /**
  * Return a meta query for filtering by price.
  * @return array
  */
 private function price_filter_meta_query()
 {
     if (isset($_GET['max_price']) || isset($_GET['min_price'])) {
         $min = isset($_GET['min_price']) ? floatval($_GET['min_price']) : 0;
         $max = isset($_GET['max_price']) ? floatval($_GET['max_price']) : 9999999999.0;
         /**
          * Adjust if the store taxes are not displayed how they are stored.
          * Max is left alone because the filter was already increased.
          * Kicks in when prices excluding tax are displayed including tax.
          */
         if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) {
             $tax_classes = array_merge(array(''), WC_Tax::get_tax_classes());
             $class_min = $min;
             foreach ($tax_classes as $tax_class) {
                 if ($tax_rates = WC_Tax::get_rates($tax_class)) {
                     $class_min = $min - WC_Tax::get_tax_total(WC_Tax::calc_exclusive_tax($min, $tax_rates));
                 }
             }
             $min = $class_min;
         }
         return array('key' => '_price', 'value' => array($min, $max), 'compare' => 'BETWEEN', 'type' => 'DECIMAL', 'price_filter' => true);
     }
     return array();
 }
    /**
     * Output the metabox
     */
    public static function output($post)
    {
        global $post, $thepostid;
        wp_nonce_field('woocommerce_save_data', 'woocommerce_meta_nonce');
        $thepostid = $post->ID;
        if ($terms = wp_get_object_terms($post->ID, 'product_type')) {
            $product_type = sanitize_title(current($terms)->name);
        } else {
            $product_type = apply_filters('default_product_type', 'simple');
        }
        $product_type_selector = apply_filters('product_type_selector', array('simple' => __('Simple product', 'woocommerce'), 'grouped' => __('Grouped product', 'woocommerce'), 'external' => __('External/Affiliate product', 'woocommerce'), 'variable' => __('Variable product', 'woocommerce')), $product_type);
        $type_box = '<label for="product-type"><select id="product-type" name="product-type"><optgroup label="' . __('Product Type', 'woocommerce') . '">';
        foreach ($product_type_selector as $value => $label) {
            $type_box .= '<option value="' . esc_attr($value) . '" ' . selected($product_type, $value, false) . '>' . esc_html($label) . '</option>';
        }
        $type_box .= '</optgroup></select></label>';
        $product_type_options = apply_filters('product_type_options', array('virtual' => array('id' => '_virtual', 'wrapper_class' => 'show_if_simple', 'label' => __('Virtual', 'woocommerce'), 'description' => __('Virtual products are intangible and aren\'t shipped.', 'woocommerce'), 'default' => 'no'), 'downloadable' => array('id' => '_downloadable', 'wrapper_class' => 'show_if_simple', 'label' => __('Downloadable', 'woocommerce'), 'description' => __('Downloadable products give access to a file upon purchase.', 'woocommerce'), 'default' => 'no')));
        foreach ($product_type_options as $key => $option) {
            $selected_value = get_post_meta($post->ID, '_' . $key, true);
            if ('' == $selected_value && isset($option['default'])) {
                $selected_value = $option['default'];
            }
            $type_box .= '<label for="' . esc_attr($option['id']) . '" class="' . esc_attr($option['wrapper_class']) . ' tips" data-tip="' . esc_attr($option['description']) . '">' . esc_html($option['label']) . ': <input type="checkbox" name="' . esc_attr($option['id']) . '" id="' . esc_attr($option['id']) . '" ' . checked($selected_value, 'yes', false) . ' /></label>';
        }
        ?>
		<div class="panel-wrap product_data">

			<span class="type_box"> &mdash; <?php 
        echo $type_box;
        ?>
</span>

			<ul class="product_data_tabs wc-tabs" style="display:none;">
				<?php 
        $product_data_tabs = apply_filters('woocommerce_product_data_tabs', array('general' => array('label' => __('General', 'woocommerce'), 'target' => 'general_product_data', 'class' => array('hide_if_grouped')), 'inventory' => array('label' => __('Inventory', 'woocommerce'), 'target' => 'inventory_product_data', 'class' => array('show_if_simple', 'show_if_variable', 'show_if_grouped')), 'shipping' => array('label' => __('Shipping', 'woocommerce'), 'target' => 'shipping_product_data', 'class' => array('hide_if_virtual', 'hide_if_grouped', 'hide_if_external')), 'linked_product' => array('label' => __('Linked Products', 'woocommerce'), 'target' => 'linked_product_data', 'class' => array()), 'attribute' => array('label' => __('Attributes', 'woocommerce'), 'target' => 'product_attributes', 'class' => array()), 'variations' => array('label' => __('Variations', 'woocommerce'), 'target' => 'variable_product_options', 'class' => array('variations_tab', 'show_if_variable')), 'advanced' => array('label' => __('Advanced', 'woocommerce'), 'target' => 'advanced_product_data', 'class' => array())));
        foreach ($product_data_tabs as $key => $tab) {
            ?>
<li class="<?php 
            echo $key;
            ?>
_options <?php 
            echo $key;
            ?>
_tab <?php 
            echo implode(' ', $tab['class']);
            ?>
">
							<a href="#<?php 
            echo $tab['target'];
            ?>
"><?php 
            echo esc_html($tab['label']);
            ?>
</a>
						</li><?php 
        }
        do_action('woocommerce_product_write_panel_tabs');
        ?>
			</ul>
			<div id="general_product_data" class="panel woocommerce_options_panel"><?php 
        echo '<div class="options_group hide_if_grouped">';
        // SKU
        if (wc_product_sku_enabled()) {
            woocommerce_wp_text_input(array('id' => '_sku', 'label' => '<abbr title="' . __('Stock Keeping Unit', 'woocommerce') . '">' . __('SKU', 'woocommerce') . '</abbr>', 'desc_tip' => 'true', 'description' => __('SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce')));
        } else {
            echo '<input type="hidden" name="_sku" value="' . esc_attr(get_post_meta($thepostid, '_sku', true)) . '" />';
        }
        do_action('woocommerce_product_options_sku');
        echo '</div>';
        echo '<div class="options_group show_if_external">';
        // External URL
        woocommerce_wp_text_input(array('id' => '_product_url', 'label' => __('Product URL', 'woocommerce'), 'placeholder' => 'http://', 'description' => __('Enter the external URL to the product.', 'woocommerce')));
        // Button text
        woocommerce_wp_text_input(array('id' => '_button_text', 'label' => __('Button text', 'woocommerce'), 'placeholder' => _x('Buy product', 'placeholder', 'woocommerce'), 'description' => __('This text will be shown on the button linking to the external product.', 'woocommerce')));
        echo '</div>';
        echo '<div class="options_group pricing show_if_simple show_if_external">';
        // Price
        woocommerce_wp_text_input(array('id' => '_regular_price', 'label' => __('Regular Price', 'woocommerce') . ' (' . get_woocommerce_currency_symbol() . ')', 'data_type' => 'price'));
        // Special Price
        woocommerce_wp_text_input(array('id' => '_sale_price', 'data_type' => 'price', 'label' => __('Sale Price', 'woocommerce') . ' (' . get_woocommerce_currency_symbol() . ')', 'description' => '<a href="#" class="sale_schedule">' . __('Schedule', 'woocommerce') . '</a>'));
        // Special Price date range
        $sale_price_dates_from = ($date = get_post_meta($thepostid, '_sale_price_dates_from', true)) ? date_i18n('Y-m-d', $date) : '';
        $sale_price_dates_to = ($date = get_post_meta($thepostid, '_sale_price_dates_to', true)) ? date_i18n('Y-m-d', $date) : '';
        echo '<p class="form-field sale_price_dates_fields">
								<label for="_sale_price_dates_from">' . __('Sale Price Dates', 'woocommerce') . '</label>
								<input type="text" class="short" name="_sale_price_dates_from" id="_sale_price_dates_from" value="' . esc_attr($sale_price_dates_from) . '" placeholder="' . _x('From&hellip;', 'placeholder', 'woocommerce') . ' YYYY-MM-DD" maxlength="10" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />
								<input type="text" class="short" name="_sale_price_dates_to" id="_sale_price_dates_to" value="' . esc_attr($sale_price_dates_to) . '" placeholder="' . _x('To&hellip;', 'placeholder', 'woocommerce') . '  YYYY-MM-DD" maxlength="10" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />
								<a href="#" class="cancel_sale_schedule">' . __('Cancel', 'woocommerce') . '</a>
								<img class="help_tip" style="margin-top: 21px;" data-tip="' . __('The sale will end at the beginning of the set date.', 'woocommerce') . '" src="' . esc_url(WC()->plugin_url()) . '/assets/images/help.png" height="16" width="16" />
							</p>';
        do_action('woocommerce_product_options_pricing');
        echo '</div>';
        echo '<div class="options_group show_if_downloadable">';
        ?>
					<div class="form-field downloadable_files">
						<label><?php 
        _e('Downloadable Files', 'woocommerce');
        ?>
:</label>
						<table class="widefat">
							<thead>
								<tr>
									<th class="sort">&nbsp;</th>
									<th><?php 
        _e('Name', 'woocommerce');
        ?>
 <span class="tips" data-tip="<?php 
        _e('This is the name of the download shown to the customer.', 'woocommerce');
        ?>
">[?]</span></th>
									<th colspan="2"><?php 
        _e('File URL', 'woocommerce');
        ?>
 <span class="tips" data-tip="<?php 
        _e('This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce');
        ?>
">[?]</span></th>
									<th>&nbsp;</th>
								</tr>
							</thead>
							<tbody>
								<?php 
        $downloadable_files = get_post_meta($post->ID, '_downloadable_files', true);
        if ($downloadable_files) {
            foreach ($downloadable_files as $key => $file) {
                include 'views/html-product-download.php';
            }
        }
        ?>
							</tbody>
							<tfoot>
								<tr>
									<th colspan="5">
										<a href="#" class="button insert" data-row="<?php 
        $file = array('file' => '', 'name' => '');
        ob_start();
        include 'views/html-product-download.php';
        echo esc_attr(ob_get_clean());
        ?>
"><?php 
        _e('Add File', 'woocommerce');
        ?>
</a>
									</th>
								</tr>
							</tfoot>
						</table>
					</div>
					<?php 
        // Download Limit
        woocommerce_wp_text_input(array('id' => '_download_limit', 'label' => __('Download Limit', 'woocommerce'), 'placeholder' => __('Unlimited', 'woocommerce'), 'description' => __('Leave blank for unlimited re-downloads.', 'woocommerce'), 'type' => 'number', 'custom_attributes' => array('step' => '1', 'min' => '0')));
        // Expirey
        woocommerce_wp_text_input(array('id' => '_download_expiry', 'label' => __('Download Expiry', 'woocommerce'), 'placeholder' => __('Never', 'woocommerce'), 'description' => __('Enter the number of days before a download link expires, or leave blank.', 'woocommerce'), 'type' => 'number', 'custom_attributes' => array('step' => '1', 'min' => '0')));
        // Download Type
        woocommerce_wp_select(array('id' => '_download_type', 'label' => __('Download Type', 'woocommerce'), 'description' => sprintf(__('Choose a download type - this controls the <a href="%s">schema</a>.', 'woocommerce'), 'http://schema.org/'), 'options' => array('' => __('Standard Product', 'woocommerce'), 'application' => __('Application/Software', 'woocommerce'), 'music' => __('Music', 'woocommerce'))));
        do_action('woocommerce_product_options_downloads');
        echo '</div>';
        if (wc_tax_enabled()) {
            echo '<div class="options_group show_if_simple show_if_external show_if_variable">';
            // Tax
            woocommerce_wp_select(array('id' => '_tax_status', 'label' => __('Tax Status', 'woocommerce'), 'options' => array('taxable' => __('Taxable', 'woocommerce'), 'shipping' => __('Shipping only', 'woocommerce'), 'none' => _x('None', 'Tax status', 'woocommerce'))));
            $tax_classes = WC_Tax::get_tax_classes();
            $classes_options = array();
            $classes_options[''] = __('Standard', 'woocommerce');
            if (!empty($tax_classes)) {
                foreach ($tax_classes as $class) {
                    $classes_options[sanitize_title($class)] = esc_html($class);
                }
            }
            woocommerce_wp_select(array('id' => '_tax_class', 'label' => __('Tax Class', 'woocommerce'), 'options' => $classes_options));
            do_action('woocommerce_product_options_tax');
            echo '</div>';
        }
        do_action('woocommerce_product_options_general_product_data');
        ?>
			</div>

			<div id="inventory_product_data" class="panel woocommerce_options_panel">

				<?php 
        echo '<div class="options_group">';
        if ('yes' == get_option('woocommerce_manage_stock')) {
            // manage stock
            woocommerce_wp_checkbox(array('id' => '_manage_stock', 'wrapper_class' => 'show_if_simple show_if_variable', 'label' => __('Manage stock?', 'woocommerce'), 'description' => __('Enable stock management at product level', 'woocommerce')));
            do_action('woocommerce_product_options_stock');
            echo '<div class="stock_fields show_if_simple show_if_variable">';
            // Stock
            woocommerce_wp_text_input(array('id' => '_stock', 'label' => __('Stock Qty', 'woocommerce'), 'desc_tip' => true, 'description' => __('Stock quantity. If this is a variable product this value will be used to control stock for all variations, unless you define stock at variation level.', 'woocommerce'), 'type' => 'number', 'custom_attributes' => array('step' => 'any'), 'data_type' => 'stock'));
            // Backorders?
            woocommerce_wp_select(array('id' => '_backorders', 'label' => __('Allow Backorders?', 'woocommerce'), 'options' => array('no' => __('Do not allow', 'woocommerce'), 'notify' => __('Allow, but notify customer', 'woocommerce'), 'yes' => __('Allow', 'woocommerce')), 'desc_tip' => true, 'description' => __('If managing stock, this controls whether or not backorders are allowed. If enabled, stock quantity can go below 0.', 'woocommerce')));
            do_action('woocommerce_product_options_stock_fields');
            echo '</div>';
        }
        // Stock status
        woocommerce_wp_select(array('id' => '_stock_status', 'wrapper_class' => 'hide_if_variable', 'label' => __('Stock status', 'woocommerce'), 'options' => array('instock' => __('In stock', 'woocommerce'), 'outofstock' => __('Out of stock', 'woocommerce')), 'desc_tip' => true, 'description' => __('Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce')));
        do_action('woocommerce_product_options_stock_status');
        echo '</div>';
        echo '<div class="options_group show_if_simple show_if_variable">';
        // Individual product
        woocommerce_wp_checkbox(array('id' => '_sold_individually', 'wrapper_class' => 'show_if_simple show_if_variable', 'label' => __('Sold Individually', 'woocommerce'), 'description' => __('Enable this to only allow one of this item to be bought in a single order', 'woocommerce')));
        do_action('woocommerce_product_options_sold_individually');
        echo '</div>';
        do_action('woocommerce_product_options_inventory_product_data');
        ?>

			</div>

			<div id="shipping_product_data" class="panel woocommerce_options_panel">

				<?php 
        echo '<div class="options_group">';
        // Weight
        if (wc_product_weight_enabled()) {
            woocommerce_wp_text_input(array('id' => '_weight', 'label' => __('Weight', 'woocommerce') . ' (' . get_option('woocommerce_weight_unit') . ')', 'placeholder' => wc_format_localized_decimal(0), 'desc_tip' => 'true', 'description' => __('Weight in decimal form', 'woocommerce'), 'type' => 'text', 'data_type' => 'decimal'));
        }
        // Size fields
        if (wc_product_dimensions_enabled()) {
            ?>
<p class="form-field dimensions_field">
							<label for="product_length"><?php 
            echo __('Dimensions', 'woocommerce') . ' (' . get_option('woocommerce_dimension_unit') . ')';
            ?>
</label>
							<span class="wrap">
								<input id="product_length" placeholder="<?php 
            _e('Length', 'woocommerce');
            ?>
" class="input-text wc_input_decimal" size="6" type="text" name="_length" value="<?php 
            echo esc_attr(wc_format_localized_decimal(get_post_meta($thepostid, '_length', true)));
            ?>
" />
								<input placeholder="<?php 
            _e('Width', 'woocommerce');
            ?>
" class="input-text wc_input_decimal" size="6" type="text" name="_width" value="<?php 
            echo esc_attr(wc_format_localized_decimal(get_post_meta($thepostid, '_width', true)));
            ?>
" />
								<input placeholder="<?php 
            _e('Height', 'woocommerce');
            ?>
" class="input-text wc_input_decimal last" size="6" type="text" name="_height" value="<?php 
            echo esc_attr(wc_format_localized_decimal(get_post_meta($thepostid, '_height', true)));
            ?>
" />
							</span>
							<img class="help_tip" data-tip="<?php 
            esc_attr_e('LxWxH in decimal form', 'woocommerce');
            ?>
" src="<?php 
            echo esc_url(WC()->plugin_url());
            ?>
/assets/images/help.png" height="16" width="16" />
						</p><?php 
        }
        do_action('woocommerce_product_options_dimensions');
        echo '</div>';
        echo '<div class="options_group">';
        // Shipping Class
        $classes = get_the_terms($thepostid, 'product_shipping_class');
        if ($classes && !is_wp_error($classes)) {
            $current_shipping_class = current($classes)->term_id;
        } else {
            $current_shipping_class = '';
        }
        $args = array('taxonomy' => 'product_shipping_class', 'hide_empty' => 0, 'show_option_none' => __('No shipping class', 'woocommerce'), 'name' => 'product_shipping_class', 'id' => 'product_shipping_class', 'selected' => $current_shipping_class, 'class' => 'select short');
        ?>
<p class="form-field dimensions_field"><label for="product_shipping_class"><?php 
        _e('Shipping class', 'woocommerce');
        ?>
</label> <?php 
        wp_dropdown_categories($args);
        ?>
 <img class="help_tip" data-tip="<?php 
        esc_attr_e('Shipping classes are used by certain shipping methods to group similar products.', 'woocommerce');
        ?>
" src="<?php 
        echo esc_url(WC()->plugin_url());
        ?>
/assets/images/help.png" height="16" width="16" /></p><?php 
        do_action('woocommerce_product_options_shipping');
        echo '</div>';
        ?>

			</div>

			<div id="product_attributes" class="panel wc-metaboxes-wrapper">
				<div class="product_attributes wc-metaboxes">

					<?php 
        global $wc_product_attributes;
        // Array of defined attribute taxonomies
        $attribute_taxonomies = wc_get_attribute_taxonomies();
        // Product attributes - taxonomies and custom, ordered, with visibility and variation attributes set
        $attributes = maybe_unserialize(get_post_meta($thepostid, '_product_attributes', true));
        // Output All Set Attributes
        if (!empty($attributes)) {
            $attribute_keys = array_keys($attributes);
            $attribute_total = sizeof($attribute_keys);
            for ($i = 0; $i < $attribute_total; $i++) {
                $attribute = $attributes[$attribute_keys[$i]];
                $position = empty($attribute['position']) ? 0 : absint($attribute['position']);
                $taxonomy = '';
                $metabox_class = array();
                if ($attribute['is_taxonomy']) {
                    $taxonomy = $attribute['name'];
                    if (!taxonomy_exists($taxonomy)) {
                        continue;
                    }
                    $attribute_taxonomy = $wc_product_attributes[$taxonomy];
                    $metabox_class[] = 'taxonomy';
                    $metabox_class[] = $taxonomy;
                    $attribute_label = wc_attribute_label($taxonomy);
                } else {
                    $attribute_label = apply_filters('woocommerce_attribute_label', $attribute['name'], $attribute['name']);
                }
                include 'views/html-product-attribute.php';
            }
        }
        ?>
				</div>

				<p class="toolbar">
					<button type="button" class="button button-primary add_attribute"><?php 
        _e('Add', 'woocommerce');
        ?>
</button>
					<select name="attribute_taxonomy" class="attribute_taxonomy">
						<option value=""><?php 
        _e('Custom product attribute', 'woocommerce');
        ?>
</option>
						<?php 
        if ($attribute_taxonomies) {
            foreach ($attribute_taxonomies as $tax) {
                $attribute_taxonomy_name = wc_attribute_taxonomy_name($tax->attribute_name);
                $label = $tax->attribute_label ? $tax->attribute_label : $tax->attribute_name;
                echo '<option value="' . esc_attr($attribute_taxonomy_name) . '">' . esc_html($label) . '</option>';
            }
        }
        ?>
					</select>

					<button type="button" class="button save_attributes"><?php 
        _e('Save attributes', 'woocommerce');
        ?>
</button>
				</p>
				<?php 
        do_action('woocommerce_product_options_attributes');
        ?>
			</div>
			<div id="linked_product_data" class="panel woocommerce_options_panel">

				<div class="options_group">

					<p class="form-field">
						<label for="upsell_ids"><?php 
        _e('Up-Sells', 'woocommerce');
        ?>
</label>
						<input type="hidden" class="wc-product-search" style="width: 50%;" id="upsell_ids" name="upsell_ids" data-placeholder="<?php 
        _e('Search for a product&hellip;', 'woocommerce');
        ?>
" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php 
        echo intval($post->ID);
        ?>
" data-selected="<?php 
        $product_ids = array_filter(array_map('absint', (array) get_post_meta($post->ID, '_upsell_ids', true)));
        $json_ids = array();
        foreach ($product_ids as $product_id) {
            $product = wc_get_product($product_id);
            if (is_object($product)) {
                $json_ids[$product_id] = wp_kses_post(html_entity_decode($product->get_formatted_name()));
            }
        }
        echo esc_attr(json_encode($json_ids));
        ?>
" value="<?php 
        echo implode(',', array_keys($json_ids));
        ?>
" /> <img class="help_tip" data-tip='<?php 
        _e('Up-sells are products which you recommend instead of the currently viewed product, for example, products that are more profitable or better quality or more expensive.', 'woocommerce');
        ?>
' src="<?php 
        echo WC()->plugin_url();
        ?>
/assets/images/help.png" height="16" width="16" />
					</p>

					<p class="form-field">
						<label for="crosssell_ids"><?php 
        _e('Cross-Sells', 'woocommerce');
        ?>
</label>
						<input type="hidden" class="wc-product-search" style="width: 50%;" id="crosssell_ids" name="crosssell_ids" data-placeholder="<?php 
        _e('Search for a product&hellip;', 'woocommerce');
        ?>
" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php 
        echo intval($post->ID);
        ?>
" data-selected="<?php 
        $product_ids = array_filter(array_map('absint', (array) get_post_meta($post->ID, '_crosssell_ids', true)));
        $json_ids = array();
        foreach ($product_ids as $product_id) {
            $product = wc_get_product($product_id);
            if (is_object($product)) {
                $json_ids[$product_id] = wp_kses_post(html_entity_decode($product->get_formatted_name()));
            }
        }
        echo esc_attr(json_encode($json_ids));
        ?>
" value="<?php 
        echo implode(',', array_keys($json_ids));
        ?>
" /> <img class="help_tip" data-tip='<?php 
        _e('Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce');
        ?>
' src="<?php 
        echo WC()->plugin_url();
        ?>
/assets/images/help.png" height="16" width="16" />
					</p>
				</div>

				<div class="options_group grouping show_if_simple show_if_external">

					<p class="form-field">
						<label for="parent_id"><?php 
        _e('Grouping', 'woocommerce');
        ?>
</label>
						<input type="hidden" class="wc-product-search" style="width: 50%;" id="parent_id" name="parent_id" data-placeholder="<?php 
        _e('Search for a product&hellip;', 'woocommerce');
        ?>
" data-action="woocommerce_json_search_grouped_products" data-allow_clear="true" data-multiple="false" data-exclude="<?php 
        echo intval($post->ID);
        ?>
" data-selected="<?php 
        $parent_id = absint($post->post_parent);
        if ($parent_id) {
            $parent = wc_get_product($parent_id);
            if (is_object($parent)) {
                $parent_title = wp_kses_post(html_entity_decode($parent->get_formatted_name()));
            }
            echo esc_attr($parent_title);
        }
        ?>
" value="<?php 
        echo $parent_id ? $parent_id : '';
        ?>
" /> <img class="help_tip" data-tip='<?php 
        _e('Set this option to make this product part of a grouped product.', 'woocommerce');
        ?>
' src="<?php 
        echo WC()->plugin_url();
        ?>
/assets/images/help.png" height="16" width="16" />
					</p>

					<?php 
        woocommerce_wp_hidden_input(array('id' => 'previous_parent_id', 'value' => absint($post->post_parent)));
        do_action('woocommerce_product_options_grouping');
        ?>
				</div>

				<?php 
        do_action('woocommerce_product_options_related');
        ?>
			</div>

			<div id="advanced_product_data" class="panel woocommerce_options_panel">

				<div class="options_group hide_if_external">
					<?php 
        // Purchase note
        woocommerce_wp_textarea_input(array('id' => '_purchase_note', 'label' => __('Purchase Note', 'woocommerce'), 'desc_tip' => 'true', 'description' => __('Enter an optional note to send the customer after purchase.', 'woocommerce')));
        ?>
				</div>

				<div class="options_group">
					<?php 
        // menu_order
        woocommerce_wp_text_input(array('id' => 'menu_order', 'label' => __('Menu order', 'woocommerce'), 'desc_tip' => 'true', 'description' => __('Custom ordering position.', 'woocommerce'), 'value' => intval($post->menu_order), 'type' => 'number', 'custom_attributes' => array('step' => '1')));
        ?>
				</div>

				<div class="options_group reviews">
					<?php 
        woocommerce_wp_checkbox(array('id' => 'comment_status', 'label' => __('Enable reviews', 'woocommerce'), 'cbvalue' => 'open', 'value' => esc_attr($post->comment_status)));
        do_action('woocommerce_product_options_reviews');
        ?>
				</div>

				<?php 
        do_action('woocommerce_product_options_advanced');
        ?>

			</div>

			<?php 
        self::output_variations();
        do_action('woocommerce_product_data_panels');
        do_action('woocommerce_product_write_panels');
        // _deprecated
        ?>

			<div class="clear"></div>

		</div>
		<?php 
    }
 public static function createSimpleOrder($total = 40)
 {
     $product = self::createSimpleProduct();
     self::createSimpleShippingFlatRate();
     $order_data = array('status' => 'pending', 'customer_id' => 1, 'customer_note' => '', 'total' => '');
     // Required, else wc_create_order throws an exception
     $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
     $order = wc_create_order($order_data);
     // Add order products
     $order->add_product($product, 4);
     // Set billing address
     $shipping_address = array('country' => 'US', 'first_name' => 'Jeroen', 'last_name' => 'Sormani', 'company' => 'WooCompany', 'address_1' => 'WooAddress', 'address_2' => '', 'postcode' => '123456', 'city' => 'WooCity', 'state' => 'NY', 'email' => '*****@*****.**', 'phone' => '555-32123');
     $order->set_address($shipping_address, 'shipping');
     // Add shipping costs
     $shipping_taxes = \WC_Tax::calc_shipping_tax('10', \WC_Tax::get_shipping_tax_rates());
     $order->add_shipping(new \WC_Shipping_Rate('flagship_shipping_method|Purolator|PurolatorExpress|Purolator Express|1473811200', 'Purolator - Purolator Express', '10', $shipping_taxes, 'flagship_shipping_method'));
     // Set totals
     $order->set_total(10, 'shipping');
     $order->set_total(0, 'cart_discount');
     $order->set_total(0, 'cart_discount_tax');
     $order->set_total(0, 'tax');
     $order->set_total(0, 'shipping_tax');
     $order->set_total($total, 'total');
     // 4 x $10 simple helper product
     return wc_get_order($order->id);
 }