Merge branch 'feature-wc-create-order'
This commit is contained in:
commit
cf3cca4c8e
|
@ -451,7 +451,6 @@ jQuery( function($){
|
|||
};
|
||||
|
||||
$.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {
|
||||
|
||||
if ( response ) {
|
||||
$items.each( function() {
|
||||
var $row = $(this);
|
||||
|
|
|
@ -786,8 +786,6 @@ class WC_Product {
|
|||
* @return string
|
||||
*/
|
||||
public function get_price_including_tax( $qty = 1, $price = '' ) {
|
||||
$_tax = new WC_Tax();
|
||||
|
||||
if ( ! $price ) {
|
||||
$price = $this->get_price();
|
||||
}
|
||||
|
@ -796,26 +794,26 @@ class WC_Product {
|
|||
|
||||
if ( get_option('woocommerce_prices_include_tax') === 'no' ) {
|
||||
|
||||
$tax_rates = $_tax->get_rates( $this->get_tax_class() );
|
||||
$taxes = $_tax->calc_tax( $price * $qty, $tax_rates, false );
|
||||
$tax_amount = $_tax->get_tax_total( $taxes );
|
||||
$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, absint( get_option( 'woocommerce_price_num_decimals' ) ) );
|
||||
|
||||
} else {
|
||||
|
||||
$tax_rates = $_tax->get_rates( $this->get_tax_class() );
|
||||
$base_tax_rates = $_tax->get_shop_base_rate( $this->tax_class );
|
||||
$tax_rates = WC_Tax::get_rates( $this->get_tax_class() );
|
||||
$base_tax_rates = WC_Tax::get_shop_base_rate( $this->tax_class );
|
||||
|
||||
if ( ! empty( WC()->customer ) && WC()->customer->is_vat_exempt() ) {
|
||||
|
||||
$base_taxes = $_tax->calc_tax( $price * $qty, $base_tax_rates, true );
|
||||
$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, absint( get_option( 'woocommerce_price_num_decimals' ) ) );
|
||||
|
||||
} elseif ( $tax_rates !== $base_tax_rates ) {
|
||||
|
||||
$base_taxes = $_tax->calc_tax( $price * $qty, $base_tax_rates, true );
|
||||
$modded_taxes = $_tax->calc_tax( ( $price * $qty ) - array_sum( $base_taxes ), $tax_rates, false );
|
||||
$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 ), absint( get_option( 'woocommerce_price_num_decimals' ) ) );
|
||||
|
||||
} else {
|
||||
|
@ -848,12 +846,9 @@ class WC_Product {
|
|||
}
|
||||
|
||||
if ( $this->is_taxable() && get_option('woocommerce_prices_include_tax') === 'yes' ) {
|
||||
|
||||
$_tax = new WC_Tax();
|
||||
$tax_rates = $_tax->get_shop_base_rate( $this->tax_class );
|
||||
$taxes = $_tax->calc_tax( $price * $qty, $tax_rates, true );
|
||||
$price = $_tax->round( $price * $qty - array_sum( $taxes ) );
|
||||
|
||||
$tax_rates = WC_Tax::get_shop_base_rate( $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;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,6 @@ abstract class WC_Shipping_Method extends WC_Settings_API {
|
|||
// This saves shipping methods having to do complex tax calculations
|
||||
if ( ! is_array( $taxes ) && $taxes !== false && $total_cost > 0 && $this->is_taxable() ) {
|
||||
|
||||
$_tax = new WC_Tax();
|
||||
$taxes = array();
|
||||
|
||||
switch ( $calc_tax ) {
|
||||
|
@ -114,8 +113,8 @@ abstract class WC_Shipping_Method extends WC_Settings_API {
|
|||
|
||||
$_product = $cart[ $cost_key ]['data'];
|
||||
|
||||
$rates = $_tax->get_shipping_tax_rates( $_product->get_tax_class() );
|
||||
$item_taxes = $_tax->calc_shipping_tax( $amount, $rates );
|
||||
$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 )
|
||||
|
@ -126,8 +125,8 @@ abstract class WC_Shipping_Method extends WC_Settings_API {
|
|||
// 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 );
|
||||
$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 )
|
||||
|
@ -140,8 +139,8 @@ abstract class WC_Shipping_Method extends WC_Settings_API {
|
|||
|
||||
default :
|
||||
|
||||
$rates = $_tax->get_shipping_tax_rates();
|
||||
$taxes = $_tax->calc_shipping_tax( $total_cost, $rates );
|
||||
$rates = WC_Tax::get_shipping_tax_rates();
|
||||
$taxes = WC_Tax::calc_shipping_tax( $total_cost, $rates );
|
||||
|
||||
break;
|
||||
|
||||
|
|
|
@ -1185,7 +1185,6 @@ class WC_AJAX {
|
|||
|
||||
self::json_headers();
|
||||
|
||||
$tax = new WC_Tax();
|
||||
$taxes = $tax_rows = $item_taxes = $shipping_taxes = array();
|
||||
$order_id = absint( $_POST['order_id'] );
|
||||
$order = new WC_Order( $order_id );
|
||||
|
@ -1200,17 +1199,12 @@ class WC_AJAX {
|
|||
// Calculate sales tax first
|
||||
if ( sizeof( $items ) > 0 ) {
|
||||
foreach( $items as $item_id => $item ) {
|
||||
|
||||
$item_id = absint( $item_id );
|
||||
$line_subtotal = isset( $item['line_subtotal'] ) ? wc_format_decimal( $item['line_subtotal'] ) : 0;
|
||||
$line_total = wc_format_decimal( $item['line_total'] );
|
||||
$tax_class = sanitize_text_field( $item['tax_class'] );
|
||||
$product_id = $order->get_item_meta( $item_id, '_product_id', true );
|
||||
|
||||
if ( ! $item_id || '0' == $tax_class ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get product details
|
||||
if ( get_post_type( $product_id ) == 'product' ) {
|
||||
$_product = get_product( $product_id );
|
||||
|
@ -1219,10 +1213,8 @@ class WC_AJAX {
|
|||
$item_tax_status = 'taxable';
|
||||
}
|
||||
|
||||
// Only calc if taxable
|
||||
if ( 'taxable' == $item_tax_status ) {
|
||||
|
||||
$tax_rates = $tax->find_rates( array(
|
||||
if ( '0' !== $tax_class && 'taxable' === $item_tax_status ) {
|
||||
$tax_rates = WC_Tax::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
|
@ -1230,18 +1222,10 @@ class WC_AJAX {
|
|||
'tax_class' => $tax_class
|
||||
) );
|
||||
|
||||
$line_subtotal_taxes = $tax->calc_tax( $line_subtotal, $tax_rates, false );
|
||||
$line_taxes = $tax->calc_tax( $line_total, $tax_rates, false );
|
||||
$line_subtotal_tax = array_sum( $line_subtotal_taxes );
|
||||
$line_tax = array_sum( $line_taxes );
|
||||
|
||||
if ( $line_subtotal_tax < 0 ) {
|
||||
$line_subtotal_tax = 0;
|
||||
}
|
||||
|
||||
if ( $line_tax < 0 ) {
|
||||
$line_tax = 0;
|
||||
}
|
||||
$line_subtotal_taxes = WC_Tax::calc_tax( $line_subtotal, $tax_rates, false );
|
||||
$line_taxes = WC_Tax::calc_tax( $line_total, $tax_rates, false );
|
||||
$line_subtotal_tax = max( 0, array_sum( $line_subtotal_taxes ) );
|
||||
$line_tax = max( 0, array_sum( $line_taxes ) );
|
||||
|
||||
$item_taxes[ $item_id ] = array(
|
||||
'line_subtotal_tax' => wc_format_localized_price( $line_subtotal_tax ),
|
||||
|
@ -1255,14 +1239,13 @@ class WC_AJAX {
|
|||
$taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Now calculate shipping tax
|
||||
$matched_tax_rates = array();
|
||||
|
||||
$tax_rates = $tax->find_rates( array(
|
||||
$tax_rates = WC_Tax::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
|
@ -1278,62 +1261,20 @@ class WC_AJAX {
|
|||
}
|
||||
}
|
||||
|
||||
$shipping_taxes = $tax->calc_shipping_tax( $shipping, $matched_tax_rates );
|
||||
$shipping_tax = $tax->round( array_sum( $shipping_taxes ) );
|
||||
$shipping_taxes = WC_Tax::calc_shipping_tax( $shipping, $matched_tax_rates );
|
||||
$shipping_tax = WC_Tax::round( array_sum( $shipping_taxes ) );
|
||||
|
||||
// Remove old tax rows
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'tax' )", $order_id ) );
|
||||
$order->remove_order_items( 'tax' );
|
||||
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = 'tax'", $order_id ) );
|
||||
|
||||
// Get tax rates
|
||||
$rates = $wpdb->get_results( "SELECT tax_rate_id, tax_rate_country, tax_rate_state, tax_rate_name, tax_rate_priority FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name" );
|
||||
|
||||
$tax_codes = array();
|
||||
|
||||
foreach( $rates as $rate ) {
|
||||
$code = array();
|
||||
|
||||
$code[] = $rate->tax_rate_country;
|
||||
$code[] = $rate->tax_rate_state;
|
||||
$code[] = $rate->tax_rate_name ? sanitize_title( $rate->tax_rate_name ) : 'TAX';
|
||||
$code[] = absint( $rate->tax_rate_priority );
|
||||
|
||||
$tax_codes[ $rate->tax_rate_id ] = strtoupper( implode( '-', array_filter( $code ) ) );
|
||||
// Add tax rows
|
||||
foreach ( array_keys( $taxes + $shipping_taxes ) as $tax_rate_id ) {
|
||||
$order->add_tax( $tax_rate_id, isset( $taxes[ $tax_rate_id ] ) ? $taxes[ $tax_rate_id ] : 0, isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] : 0 );
|
||||
}
|
||||
|
||||
// Now merge to keep tax rows
|
||||
ob_start();
|
||||
|
||||
foreach ( array_keys( $taxes + $shipping_taxes ) as $key ) {
|
||||
|
||||
$item = array();
|
||||
$item['rate_id'] = $key;
|
||||
$item['name'] = $tax_codes[ $key ];
|
||||
$item['label'] = $tax->get_rate_label( $key );
|
||||
$item['compound'] = $tax->is_compound( $key ) ? 1 : 0;
|
||||
$item['tax_amount'] = wc_format_decimal( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 );
|
||||
$item['shipping_tax_amount'] = wc_format_decimal( isset( $shipping_taxes[ $key ] ) ? $shipping_taxes[ $key ] : 0 );
|
||||
|
||||
if ( ! $item['label'] ) {
|
||||
$item['label'] = WC()->countries->tax_or_vat();
|
||||
}
|
||||
|
||||
// Add line item
|
||||
$item_id = wc_add_order_item( $order_id, array(
|
||||
'order_item_name' => $item['name'],
|
||||
'order_item_type' => 'tax'
|
||||
) );
|
||||
|
||||
// Add line item meta
|
||||
if ( $item_id ) {
|
||||
wc_add_order_item_meta( $item_id, 'rate_id', $item['rate_id'] );
|
||||
wc_add_order_item_meta( $item_id, 'label', $item['label'] );
|
||||
wc_add_order_item_meta( $item_id, 'compound', $item['compound'] );
|
||||
wc_add_order_item_meta( $item_id, 'tax_amount', $item['tax_amount'] );
|
||||
wc_add_order_item_meta( $item_id, 'shipping_tax_amount', $item['shipping_tax_amount'] );
|
||||
}
|
||||
|
||||
foreach ( $order->get_taxes() as $item_id => $item ) {
|
||||
include( 'admin/meta-boxes/views/html-order-tax.php' );
|
||||
}
|
||||
|
||||
|
|
|
@ -1371,7 +1371,7 @@ class WC_Cart {
|
|||
|
||||
$needs_shipping_address = false;
|
||||
|
||||
if ( WC()->cart->needs_shipping() === true && ! WC()->cart->ship_to_billing_address_only() ) {
|
||||
if ( $this->needs_shipping() === true && ! $this->ship_to_billing_address_only() ) {
|
||||
$needs_shipping_address = true;
|
||||
}
|
||||
|
||||
|
@ -1661,6 +1661,15 @@ class WC_Cart {
|
|||
return $this->applied_coupons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the discount amount for a used coupon
|
||||
* @param string $code coupon code
|
||||
* @return float discount amount
|
||||
*/
|
||||
public function get_coupon_discount_amount( $code ) {
|
||||
return isset( $this->coupon_discount_amounts[ $code ] ) ? $this->coupon_discount_amounts[ $code ] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove coupons from the cart of a defined type. Type 1 is before tax, type 2 is after tax.
|
||||
*
|
||||
|
@ -2075,6 +2084,24 @@ class WC_Cart {
|
|||
return apply_filters( 'woocommerce_get_cart_tax', $cart_total_tax ? wc_price( $cart_total_tax ) : '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a tax amount
|
||||
* @param string $tax_rate_id
|
||||
* @return float amount
|
||||
*/
|
||||
public function get_tax_amount( $tax_rate_id ) {
|
||||
return isset( $this->taxes[ $tax_rate_id ] ) ? $this->taxes[ $tax_rate_id ] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a tax amount
|
||||
* @param string $tax_rate_id
|
||||
* @return float amount
|
||||
*/
|
||||
public function get_shipping_tax_amount( $tax_rate_id ) {
|
||||
return isset( $this->shipping_taxes[ $tax_rate_id ] ) ? $this->shipping_taxes[ $tax_rate_id ] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tax row amounts with or without compound taxes includes.
|
||||
*
|
||||
|
|
|
@ -123,7 +123,6 @@ class WC_Checkout {
|
|||
do_action( 'woocommerce_checkout_init', $this );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checkout process
|
||||
*/
|
||||
|
@ -132,7 +131,6 @@ class WC_Checkout {
|
|||
do_action('woocommerce_check_cart_items');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output the billing information form
|
||||
*
|
||||
|
@ -143,7 +141,6 @@ class WC_Checkout {
|
|||
wc_get_template( 'checkout/form-billing.php', array( 'checkout' => $this ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output the shipping information form
|
||||
*
|
||||
|
@ -154,242 +151,184 @@ class WC_Checkout {
|
|||
wc_get_template( 'checkout/form-shipping.php', array( 'checkout' => $this ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create_order function.
|
||||
* @access public
|
||||
* @throws Exception
|
||||
* @return int
|
||||
* @return int|WP_ERROR
|
||||
*/
|
||||
public function create_order() {
|
||||
global $wpdb;
|
||||
|
||||
// Give plugins the opportunity to create an order themselves
|
||||
$order_id = apply_filters( 'woocommerce_create_order', null, $this );
|
||||
|
||||
if ( is_numeric( $order_id ) )
|
||||
if ( $order_id = apply_filters( 'woocommerce_create_order', null, $this ) ) {
|
||||
return $order_id;
|
||||
}
|
||||
|
||||
// Create Order (send cart variable so we can record items and reduce inventory). Only create if this is a new order, not if the payment was rejected.
|
||||
$order_data = apply_filters( 'woocommerce_new_order_data', array(
|
||||
'post_type' => 'shop_order',
|
||||
'post_title' => sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ),
|
||||
'post_status' => 'wc-' . apply_filters( 'woocommerce_default_order_status', 'pending' ),
|
||||
'ping_status' => 'closed',
|
||||
'post_excerpt' => isset( $this->posted['order_comments'] ) ? $this->posted['order_comments'] : '',
|
||||
'post_author' => 1,
|
||||
'post_password' => uniqid( 'order_' ) // Protects the post just in case
|
||||
) );
|
||||
try {
|
||||
// Start transaction if available
|
||||
$wpdb->query( 'START TRANSACTION' );
|
||||
|
||||
// Insert or update the post data
|
||||
$create_new_order = true;
|
||||
|
||||
if ( WC()->session->order_awaiting_payment > 0 ) {
|
||||
$order_data = array(
|
||||
'status' => apply_filters( 'woocommerce_default_order_status', 'pending' ),
|
||||
'customer_id' => $this->customer_id,
|
||||
'customer_note' => isset( $this->posted['order_comments'] ) ? $this->posted['order_comments'] : ''
|
||||
);
|
||||
|
||||
// Insert or update the post data
|
||||
$order_id = absint( WC()->session->order_awaiting_payment );
|
||||
|
||||
// Resume the unpaid order if its pending
|
||||
if ( ( $existing_order = get_post( $order_id ) ) && $existing_order->has_status( array( 'pending', 'failed' ) ) ) {
|
||||
if ( $order_id > 0 && ( $order = new WC_Order( $order_id ) ) && $order->has_status( array( 'pending', 'failed' ) ) ) {
|
||||
|
||||
// Update the existing order as we are resuming it
|
||||
$create_new_order = false;
|
||||
$order_data['ID'] = $order_id;
|
||||
wp_update_post( $order_data );
|
||||
$order_data['order_id'] = $order_id;
|
||||
$order = wc_update_order( $order_data );
|
||||
|
||||
// Clear the old line items - we'll add these again in case they changed
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d )", $order_id ) );
|
||||
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $order_id ) );
|
||||
|
||||
// Trigger an action for the resumed order
|
||||
do_action( 'woocommerce_resume_order', $order_id );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $create_new_order ) {
|
||||
$order_id = wp_insert_post( $order_data, true );
|
||||
|
||||
if ( is_wp_error( $order_id ) )
|
||||
throw new Exception( 'Error: Unable to create order. Please try again.' );
|
||||
else
|
||||
do_action( 'woocommerce_new_order', $order_id );
|
||||
}
|
||||
|
||||
// Store user data
|
||||
if ( $this->checkout_fields['billing'] )
|
||||
foreach ( $this->checkout_fields['billing'] as $key => $field ) {
|
||||
update_post_meta( $order_id, '_' . $key, $this->posted[ $key ] );
|
||||
|
||||
if ( $this->customer_id && apply_filters( 'woocommerce_checkout_update_customer_data', true, $this ) )
|
||||
update_user_meta( $this->customer_id, $key, $this->posted[ $key ] );
|
||||
}
|
||||
|
||||
if ( $this->checkout_fields['shipping'] && WC()->cart->needs_shipping() ) {
|
||||
foreach ( $this->checkout_fields['shipping'] as $key => $field ) {
|
||||
$postvalue = false;
|
||||
|
||||
if ( $this->posted['ship_to_different_address'] == false ) {
|
||||
if ( isset( $this->posted[ str_replace( 'shipping_', 'billing_', $key ) ] ) ) {
|
||||
$postvalue = $this->posted[ str_replace( 'shipping_', 'billing_', $key ) ];
|
||||
update_post_meta( $order_id, '_' . $key, $postvalue );
|
||||
}
|
||||
if ( is_wp_error( $order ) ) {
|
||||
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
|
||||
} else {
|
||||
$postvalue = $this->posted[ $key ];
|
||||
update_post_meta( $order_id, '_' . $key, $postvalue );
|
||||
$order->remove_order_items();
|
||||
do_action( 'woocommerce_resume_order', $order_id );
|
||||
}
|
||||
|
||||
// User
|
||||
if ( $postvalue && $this->customer_id && apply_filters( 'woocommerce_checkout_update_customer_data', true, $this ) )
|
||||
update_user_meta( $this->customer_id, $key, $postvalue );
|
||||
} else {
|
||||
|
||||
$order = wc_create_order( $order_data );
|
||||
|
||||
if ( is_wp_error( $order ) ) {
|
||||
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
|
||||
} else {
|
||||
$order_id = $order->id;
|
||||
do_action( 'woocommerce_new_order', $order_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save any other user meta
|
||||
if ( $this->customer_id )
|
||||
do_action( 'woocommerce_checkout_update_user_meta', $this->customer_id, $this->posted );
|
||||
// Store the line items to the new/resumed order
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
$item_id = $order->add_product(
|
||||
$values['data'],
|
||||
$values['quantity'],
|
||||
array(
|
||||
'variation' => $values['variation'],
|
||||
'totals' => array(
|
||||
'subtotal' => $values['line_subtotal'],
|
||||
'subtotal_tax' => $values['line_subtotal_tax'],
|
||||
'total' => $values['line_total'],
|
||||
'tax' => $values['line_tax']
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Store the line items to the new/resumed order
|
||||
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
|
||||
if ( ! $item_id ) {
|
||||
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$_product = $values['data'];
|
||||
// Allow plugins to add order item meta
|
||||
do_action( 'woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key );
|
||||
}
|
||||
|
||||
// Add line item
|
||||
$item_id = wc_add_order_item( $order_id, array(
|
||||
'order_item_name' => $_product->get_title(),
|
||||
'order_item_type' => 'line_item'
|
||||
) );
|
||||
// Store fees
|
||||
foreach ( WC()->cart->get_fees() as $fee_key => $fee ) {
|
||||
$item_id = $order->add_fee( $fee );
|
||||
|
||||
// Add line item meta
|
||||
if ( $item_id ) {
|
||||
wc_add_order_item_meta( $item_id, '_qty', apply_filters( 'woocommerce_stock_amount', $values['quantity'] ) );
|
||||
wc_add_order_item_meta( $item_id, '_tax_class', $_product->get_tax_class() );
|
||||
wc_add_order_item_meta( $item_id, '_product_id', $values['product_id'] );
|
||||
wc_add_order_item_meta( $item_id, '_variation_id', $values['variation_id'] );
|
||||
wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( $values['line_subtotal'] ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $values['line_total'] ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $values['line_tax'] ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( $values['line_subtotal_tax'] ) );
|
||||
if ( ! $item_id ) {
|
||||
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
// Allow plugins to add order item meta to fees
|
||||
do_action( 'woocommerce_add_order_fee_meta', $order_id, $item_id, $fee, $fee_key );
|
||||
}
|
||||
|
||||
// Store variation data in meta so admin can view it
|
||||
if ( $values['variation'] && is_array( $values['variation'] ) ) {
|
||||
foreach ( $values['variation'] as $key => $value ) {
|
||||
$key = str_replace( 'attribute_', '', $key );
|
||||
wc_add_order_item_meta( $item_id, $key, $value );
|
||||
// Store shipping for all packages
|
||||
foreach ( WC()->shipping->get_packages() as $package_key => $package ) {
|
||||
if ( isset( $package['rates'][ $this->shipping_methods[ $package_key ] ] ) ) {
|
||||
$item_id = $order->add_shipping( $package['rates'][ $this->shipping_methods[ $package_key ] ] );
|
||||
|
||||
if ( ! $item_id ) {
|
||||
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
// Allows plugins to add order item meta to shipping
|
||||
do_action( 'woocommerce_add_shipping_order_item', $order_id, $item_id, $package_key );
|
||||
}
|
||||
}
|
||||
|
||||
// Store tax rows
|
||||
foreach ( array_keys( WC()->cart->taxes + WC()->cart->shipping_taxes ) as $tax_rate_id ) {
|
||||
if ( ! $order->add_tax( $tax_rate_id, WC()->cart->get_tax_amount( $tax_rate_id ), WC()->cart->get_shipping_tax_amount( $tax_rate_id ) ) ) {
|
||||
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Store coupons
|
||||
foreach ( WC()->cart->get_coupons() as $code => $coupon ) {
|
||||
if ( ! $order->add_coupon( $code, WC()->cart->get_coupon_discount_amount( $code ) ) ) {
|
||||
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Billing address
|
||||
$billing_address = array(
|
||||
'first_name' => $this->get_posted_address_data( 'first_name' ),
|
||||
'last_name' => $this->get_posted_address_data( 'last_name' ),
|
||||
'company' => $this->get_posted_address_data( 'company' ),
|
||||
'email' => $this->get_posted_address_data( 'email' ),
|
||||
'phone' => $this->get_posted_address_data( 'phone' ),
|
||||
'address_1' => $this->get_posted_address_data( 'address_1' ),
|
||||
'address_2' => $this->get_posted_address_data( 'address_2' ),
|
||||
'city' => $this->get_posted_address_data( 'city' ),
|
||||
'state' => $this->get_posted_address_data( 'state' ),
|
||||
'postcode' => $this->get_posted_address_data( 'postcode' ),
|
||||
'country' => $this->get_posted_address_data( 'country' )
|
||||
);
|
||||
|
||||
$shipping_address = array(
|
||||
'first_name' => $this->get_posted_address_data( 'first_name', 'shipping' ),
|
||||
'last_name' => $this->get_posted_address_data( 'last_name', 'shipping' ),
|
||||
'company' => $this->get_posted_address_data( 'company', 'shipping' ),
|
||||
'address_1' => $this->get_posted_address_data( 'address_1', 'shipping' ),
|
||||
'address_2' => $this->get_posted_address_data( 'address_2', 'shipping' ),
|
||||
'city' => $this->get_posted_address_data( 'city', 'shipping' ),
|
||||
'state' => $this->get_posted_address_data( 'state', 'shipping' ),
|
||||
'postcode' => $this->get_posted_address_data( 'postcode', 'shipping' ),
|
||||
'country' => $this->get_posted_address_data( 'country', 'shipping' ),
|
||||
);
|
||||
|
||||
$order->set_address( $billing_address, 'billing' );
|
||||
$order->set_address( $shipping_address, 'shipping' );
|
||||
$order->set_payment_method( $this->payment_method );
|
||||
$order->set_total( WC()->cart->shipping_total, 'shipping' );
|
||||
$order->set_total( WC()->cart->get_order_discount_total(), 'order_discount' );
|
||||
$order->set_total( WC()->cart->get_cart_discount_total(), 'cart_discount' );
|
||||
$order->set_total( WC()->cart->tax_total, 'tax' );
|
||||
$order->set_total( WC()->cart->shipping_tax_total, 'shipping_tax' );
|
||||
$order->set_total( WC()->cart->total );
|
||||
|
||||
// Update user meta
|
||||
if ( $this->customer_id ) {
|
||||
if ( apply_filters( 'woocommerce_checkout_update_customer_data', true, $this ) ) {
|
||||
foreach( $billing_address as $key => $value ) {
|
||||
update_user_meta( $this->customer_id, 'billing_' . $key, $value );
|
||||
}
|
||||
foreach( $shipping_address as $key => $value ) {
|
||||
update_user_meta( $this->customer_id, 'shipping_' . $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
// Add line item meta for backorder status
|
||||
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $values['quantity'] ) ) {
|
||||
wc_add_order_item_meta( $item_id, apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ), $cart_item_key, $order_id ), $values['quantity'] - max( 0, $_product->get_total_stock() ) );
|
||||
}
|
||||
|
||||
// Allow plugins to add order item meta
|
||||
do_action( 'woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key );
|
||||
}
|
||||
}
|
||||
|
||||
// Store fees
|
||||
foreach ( WC()->cart->get_fees() as $fee_key => $fee ) {
|
||||
$item_id = wc_add_order_item( $order_id, array(
|
||||
'order_item_name' => $fee->name,
|
||||
'order_item_type' => 'fee'
|
||||
) );
|
||||
|
||||
if ( $fee->taxable )
|
||||
wc_add_order_item_meta( $item_id, '_tax_class', $fee->tax_class );
|
||||
else
|
||||
wc_add_order_item_meta( $item_id, '_tax_class', '0' );
|
||||
|
||||
wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $fee->amount ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $fee->tax ) );
|
||||
|
||||
// Allow plugins to add order item meta to fees
|
||||
do_action( 'woocommerce_add_order_fee_meta', $order_id, $item_id, $fee, $fee_key );
|
||||
}
|
||||
|
||||
// Store shipping for all packages
|
||||
$packages = WC()->shipping->get_packages();
|
||||
|
||||
foreach ( $packages as $i => $package ) {
|
||||
if ( isset( $package['rates'][ $this->shipping_methods[ $i ] ] ) ) {
|
||||
|
||||
$method = $package['rates'][ $this->shipping_methods[ $i ] ];
|
||||
|
||||
$item_id = wc_add_order_item( $order_id, array(
|
||||
'order_item_name' => $method->label,
|
||||
'order_item_type' => 'shipping'
|
||||
) );
|
||||
|
||||
if ( $item_id ) {
|
||||
wc_add_order_item_meta( $item_id, 'method_id', $method->id );
|
||||
wc_add_order_item_meta( $item_id, 'cost', wc_format_decimal( $method->cost ) );
|
||||
do_action( 'woocommerce_add_shipping_order_item', $order_id, $item_id, $i );
|
||||
}
|
||||
do_action( 'woocommerce_checkout_update_user_meta', $this->customer_id, $this->posted );
|
||||
}
|
||||
|
||||
// Let plugins add meta
|
||||
do_action( 'woocommerce_checkout_update_order_meta', $order_id, $this->posted );
|
||||
|
||||
// If we got here, the order was created without problems!
|
||||
$wpdb->query( 'COMMIT' );
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
// There was an error adding order data!
|
||||
$wpdb->query( 'ROLLBACK' );
|
||||
return new WP_Error( 'checkout-error', $e->getMessage() );
|
||||
}
|
||||
|
||||
// Store tax rows
|
||||
foreach ( array_keys( WC()->cart->taxes + WC()->cart->shipping_taxes ) as $key ) {
|
||||
$code = WC()->cart->tax->get_rate_code( $key );
|
||||
|
||||
if ( $code ) {
|
||||
$item_id = wc_add_order_item( $order_id, array(
|
||||
'order_item_name' => $code,
|
||||
'order_item_type' => 'tax'
|
||||
) );
|
||||
|
||||
// Add line item meta
|
||||
if ( $item_id ) {
|
||||
wc_add_order_item_meta( $item_id, 'rate_id', $key );
|
||||
wc_add_order_item_meta( $item_id, 'label', WC()->cart->tax->get_rate_label( $key ) );
|
||||
wc_add_order_item_meta( $item_id, 'compound', absint( WC()->cart->tax->is_compound( $key ) ? 1 : 0 ) );
|
||||
wc_add_order_item_meta( $item_id, 'tax_amount', wc_format_decimal( isset( WC()->cart->taxes[ $key ] ) ? WC()->cart->taxes[ $key ] : 0 ) );
|
||||
wc_add_order_item_meta( $item_id, 'shipping_tax_amount', wc_format_decimal( isset( WC()->cart->shipping_taxes[ $key ] ) ? WC()->cart->shipping_taxes[ $key ] : 0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store coupons
|
||||
if ( $applied_coupons = WC()->cart->get_coupons() ) {
|
||||
foreach ( $applied_coupons as $code => $coupon ) {
|
||||
|
||||
$item_id = wc_add_order_item( $order_id, array(
|
||||
'order_item_name' => $code,
|
||||
'order_item_type' => 'coupon'
|
||||
) );
|
||||
|
||||
// Add line item meta
|
||||
if ( $item_id ) {
|
||||
wc_add_order_item_meta( $item_id, 'discount_amount', isset( WC()->cart->coupon_discount_amounts[ $code ] ) ? WC()->cart->coupon_discount_amounts[ $code ] : 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->payment_method ) {
|
||||
update_post_meta( $order_id, '_payment_method', $this->payment_method->id );
|
||||
update_post_meta( $order_id, '_payment_method_title', $this->payment_method->get_title() );
|
||||
}
|
||||
if ( empty( $this->posted['billing_email'] ) && is_user_logged_in() ) {
|
||||
$current_user = wp_get_current_user();
|
||||
update_post_meta( $order_id, '_billing_email', $current_user->user_email );
|
||||
}
|
||||
update_post_meta( $order_id, '_order_shipping', wc_format_decimal( WC()->cart->shipping_total ) );
|
||||
update_post_meta( $order_id, '_order_discount', wc_format_decimal( WC()->cart->get_order_discount_total() ) );
|
||||
update_post_meta( $order_id, '_cart_discount', wc_format_decimal( WC()->cart->get_cart_discount_total() ) );
|
||||
update_post_meta( $order_id, '_order_tax', wc_format_decimal( WC()->cart->tax_total ) );
|
||||
update_post_meta( $order_id, '_order_shipping_tax', wc_format_decimal( WC()->cart->shipping_tax_total ) );
|
||||
update_post_meta( $order_id, '_order_total', wc_format_decimal( WC()->cart->total, get_option( 'woocommerce_price_num_decimals' ) ) );
|
||||
|
||||
update_post_meta( $order_id, '_order_key', 'wc_' . apply_filters('woocommerce_generate_order_key', uniqid('order_') ) );
|
||||
update_post_meta( $order_id, '_customer_user', absint( $this->customer_id ) );
|
||||
update_post_meta( $order_id, '_order_currency', get_woocommerce_currency() );
|
||||
update_post_meta( $order_id, '_prices_include_tax', get_option( 'woocommerce_prices_include_tax' ) );
|
||||
update_post_meta( $order_id, '_customer_ip_address', isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'] );
|
||||
update_post_meta( $order_id, '_customer_user_agent', isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '' );
|
||||
|
||||
// Let plugins add meta
|
||||
do_action( 'woocommerce_checkout_update_order_meta', $order_id, $this->posted );
|
||||
|
||||
return $order_id;
|
||||
}
|
||||
|
||||
|
@ -658,6 +597,10 @@ class WC_Checkout {
|
|||
|
||||
$order_id = $this->create_order();
|
||||
|
||||
if ( is_wp_error( $order_id ) ) {
|
||||
throw new Exception( $order_id->get_error_message() );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_checkout_order_processed', $order_id, $this->posted );
|
||||
|
||||
// Process payment
|
||||
|
@ -717,10 +660,9 @@ class WC_Checkout {
|
|||
}
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
|
||||
if ( ! empty( $e ) )
|
||||
if ( ! empty( $e ) ) {
|
||||
wc_add_notice( $e->getMessage(), 'error' );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // endif
|
||||
|
@ -746,6 +688,26 @@ class WC_Checkout {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a posted address field after sanitization and validation.
|
||||
* @param string $key
|
||||
* @param string $type billing for shipping
|
||||
* @return string
|
||||
*/
|
||||
public function get_posted_address_data( $key, $type = 'billing' ) {
|
||||
if ( 'billing' === $type || false === $this->posted['ship_to_different_address'] ) {
|
||||
$return = isset( $this->posted[ 'billing_' . $key ] ) ? $this->posted[ 'billing_' . $key ] : '';
|
||||
} else {
|
||||
$return = isset( $this->posted[ 'shipping_' . $key ] ) ? $this->posted[ 'shipping_' . $key ] : '';
|
||||
}
|
||||
|
||||
// Use logged in user's billing email if neccessary
|
||||
if ( 'email' === $key && empty( $return ) && is_user_logged_in() ) {
|
||||
$current_user = wp_get_current_user();
|
||||
$return = $current_user->user_email;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value either from the posted data, or from the users meta data
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* The WooCommerce order class handles order data.
|
||||
*
|
||||
* @class WC_Order
|
||||
* @version 2.1.0
|
||||
* @version 2.2.0
|
||||
* @package WooCommerce/Classes
|
||||
* @category Class
|
||||
* @author WooThemes
|
||||
|
@ -34,6 +34,360 @@ class WC_Order {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all line items (products, coupons, shipping, taxes) from the order.
|
||||
*/
|
||||
public function remove_order_items( $type = null ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( $type ) {
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = %s )", $this->id, $type ) );
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = %s", $this->id, $type ) );
|
||||
} else {
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d )", $this->id ) );
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $this->id ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the payment method for the order
|
||||
* @param WC_Payment_Gateway
|
||||
*/
|
||||
public function set_payment_method( $payment_method ) {
|
||||
if ( is_object( $payment_method ) ) {
|
||||
update_post_meta( $this->id, '_payment_method', $payment_method->id );
|
||||
update_post_meta( $this->id, '_payment_method_title', $payment_method->get_title() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the customer address
|
||||
* @param array $address Address data
|
||||
* @param string $type billing or shipping
|
||||
*/
|
||||
public function set_address( $address, $type = 'billing' ) {
|
||||
foreach( $address as $key => $value ) {
|
||||
update_post_meta( $this->id, "_{$type}_" . $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a product line item to the order
|
||||
* @param WC_Product $item
|
||||
* @param int $qty Line item quantity
|
||||
* @param array args
|
||||
* @return int|bool Item ID or false
|
||||
*/
|
||||
public function add_product( $product, $qty = 1, $args = array() ) {
|
||||
$default_args = array(
|
||||
'variation' => array(),
|
||||
'totals' => array()
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $default_args );
|
||||
$item_id = wc_add_order_item( $this->id, array(
|
||||
'order_item_name' => $product->get_title(),
|
||||
'order_item_type' => 'line_item'
|
||||
) );
|
||||
|
||||
if ( ! $item_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wc_add_order_item_meta( $item_id, '_qty', apply_filters( 'woocommerce_stock_amount', $qty ) );
|
||||
wc_add_order_item_meta( $item_id, '_tax_class', $product->get_tax_class() );
|
||||
wc_add_order_item_meta( $item_id, '_product_id', $product->id );
|
||||
wc_add_order_item_meta( $item_id, '_variation_id', isset( $product->variation_id ) ? $product->variation_id : 0 );
|
||||
|
||||
// Set line item totals, either passed in or from the product
|
||||
wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( isset( $args['totals']['subtotal'] ) ? $args['totals']['subtotal'] : $product->get_price_excluding_tax( $qty ) ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( isset( $args['totals']['total'] ) ? $args['total']['subtotal_tax'] : $product->get_price_excluding_tax( $qty ) ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( isset( $args['totals']['subtotal_tax'] ) ? $args['totals']['subtotal_tax'] : 0 ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( isset( $args['totals']['tax'] ) ? $args['totals']['tax'] : 0 ) );
|
||||
|
||||
// Add variation meta
|
||||
foreach ( $args['variation'] as $key => $value ) {
|
||||
wc_add_order_item_meta( $item_id, str_replace( 'attribute_', '', $key ), $value );
|
||||
}
|
||||
|
||||
// Backorders
|
||||
if ( $product->backorders_require_notification() && $product->is_on_backorder( $qty ) ) {
|
||||
wc_add_order_item_meta( $item_id, apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $qty - max( 0, $product->get_total_stock() ) );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_order_add_product', $this->id, $item_id, $product, $qty, $args );
|
||||
|
||||
return $item_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add coupon code to the order
|
||||
* @param string $code
|
||||
* @param float $discount_amount
|
||||
* @return int|bool Item ID or false
|
||||
*/
|
||||
public function add_coupon( $code, $discount_amount = 0 ) {
|
||||
$item_id = wc_add_order_item( $this->id, array(
|
||||
'order_item_name' => $code,
|
||||
'order_item_type' => 'coupon'
|
||||
) );
|
||||
|
||||
if ( ! $item_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wc_add_order_item_meta( $item_id, 'discount_amount', $discount_amount );
|
||||
|
||||
do_action( 'woocommerce_order_add_coupon', $this->id, $item_id, $code, $discount_amount );
|
||||
|
||||
return $item_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tax row to the order
|
||||
* @param int tax_rate_id
|
||||
* @return int|bool Item ID or false
|
||||
*/
|
||||
public function add_tax( $tax_rate_id, $tax_amount = 0, $shipping_tax_amount = 0 ) {
|
||||
$code = WC_Tax::get_rate_code( $tax_rate_id );
|
||||
|
||||
if ( ! $code ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$item_id = wc_add_order_item( $this->id, array(
|
||||
'order_item_name' => $code,
|
||||
'order_item_type' => 'tax'
|
||||
) );
|
||||
|
||||
if ( ! $item_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wc_add_order_item_meta( $item_id, 'rate_id', $tax_rate_id );
|
||||
wc_add_order_item_meta( $item_id, 'label', WC_Tax::get_rate_label( $tax_rate_id ) );
|
||||
wc_add_order_item_meta( $item_id, 'compound', WC_Tax::is_compound( $tax_rate_id ) ? 1 : 0 );
|
||||
wc_add_order_item_meta( $item_id, 'tax_amount', wc_format_decimal( $tax_amount ) );
|
||||
wc_add_order_item_meta( $item_id, 'shipping_tax_amount', wc_format_decimal( $shipping_tax_amount ) );
|
||||
|
||||
do_action( 'woocommerce_order_add_tax', $this->id, $item_id, $tax_rate_id, $tax_amount, $shipping_tax_amount );
|
||||
|
||||
return $item_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a shipping row to the order
|
||||
* @param WC_Shipping_Rate shipping_rate
|
||||
* @return int|bool Item ID or false
|
||||
*/
|
||||
public function add_shipping( $shipping_rate ) {
|
||||
$item_id = wc_add_order_item( $this->id, array(
|
||||
'order_item_name' => $shipping_rate->label,
|
||||
'order_item_type' => 'shipping'
|
||||
) );
|
||||
|
||||
if ( ! $item_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wc_add_order_item_meta( $item_id, 'method_id', $shipping_rate->id );
|
||||
wc_add_order_item_meta( $item_id, 'cost', wc_format_decimal( $shipping_rate->cost ) );
|
||||
|
||||
do_action( 'woocommerce_order_add_shipping', $this->id, $item_id, $shipping_rate );
|
||||
|
||||
// Update total
|
||||
$this->set_total( $this->order_shipping + wc_format_decimal( $shipping_rate->cost ), 'shipping' );
|
||||
|
||||
return $item_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a fee to the order
|
||||
* @param object $fee
|
||||
* @return int|bool Item ID or false
|
||||
*/
|
||||
public function add_fee( $fee ) {
|
||||
$item_id = wc_add_order_item( $this->id, array(
|
||||
'order_item_name' => $fee->name,
|
||||
'order_item_type' => 'fee'
|
||||
) );
|
||||
|
||||
if ( ! $item_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $fee->taxable ) {
|
||||
wc_add_order_item_meta( $item_id, '_tax_class', $fee->tax_class );
|
||||
} else {
|
||||
wc_add_order_item_meta( $item_id, '_tax_class', '0' );
|
||||
}
|
||||
|
||||
wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $fee->amount ) );
|
||||
wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $fee->tax ) );
|
||||
|
||||
do_action( 'woocommerce_order_add_fee', $this->id, $item_id, $fee );
|
||||
|
||||
return $item_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an order total
|
||||
* @param float $amount
|
||||
* @param string $total_type
|
||||
*/
|
||||
public function set_total( $amount, $total_type = 'total' ) {
|
||||
if ( ! in_array( $total_type, array( 'shipping', 'order_discount', 'tax', 'shipping_tax', 'total', 'cart_discount' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
switch ( $total_type ) {
|
||||
case 'total' :
|
||||
$key = '_order_total';
|
||||
$amount = wc_format_decimal( $amount, get_option( 'woocommerce_price_num_decimals' ) );
|
||||
break;
|
||||
case 'order_discount' :
|
||||
case 'cart_discount' :
|
||||
$key = '_' . $total_type;
|
||||
$amount = wc_format_decimal( $amount );
|
||||
break;
|
||||
default :
|
||||
$key = '_order_' . $total_type;
|
||||
$amount = wc_format_decimal( $amount );
|
||||
break;
|
||||
}
|
||||
update_post_meta( $this->id, $key, $amount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate taxes for all line items and shipping, and store the totals and tax rows.
|
||||
*
|
||||
* Will use the base country unless customer addresses are set.
|
||||
*
|
||||
* @return bool success or fail
|
||||
*/
|
||||
public function calculate_taxes() {
|
||||
$shipping_tax_total = 0;
|
||||
$tax_total = 0;
|
||||
$taxes = array();
|
||||
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
|
||||
|
||||
if ( 'base' === $tax_based_on ) {
|
||||
$default = get_option( 'woocommerce_default_country' );
|
||||
$postcode = '';
|
||||
$city = '';
|
||||
if ( strstr( $default, ':' ) ) {
|
||||
list( $country, $state ) = explode( ':', $default );
|
||||
} else {
|
||||
$country = $default;
|
||||
$state = '';
|
||||
}
|
||||
} elseif ( 'billing' === $tax_based_on ) {
|
||||
$country = $this->billing_country;
|
||||
$state = $this->billing_state;
|
||||
$postcode = $this->billing_postcode;
|
||||
$city = $this->billing_city;
|
||||
} else {
|
||||
$country = $this->shipping_country;
|
||||
$state = $this->shipping_state;
|
||||
$postcode = $this->shipping_postcode;
|
||||
$city = $this->shipping_city;
|
||||
}
|
||||
|
||||
// Get items
|
||||
foreach ( $this->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) {
|
||||
$product = $this->get_product_from_item( $item );
|
||||
$line_total = isset( $item['line_total'] ) ? $item['line_total'] : 0;
|
||||
$line_subtotal = isset( $item['line_subtotal'] ) ? $item['line_subtotal'] : 0;
|
||||
$tax_class = $item['tax_class'];
|
||||
$item_tax_status = $product ? $product->get_tax_status() : 'taxable';
|
||||
|
||||
if ( '0' !== $tax_class && 'taxable' === $item_tax_status ) {
|
||||
$tax_rates = WC_Tax::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
'city' => $city,
|
||||
'tax_class' => $tax_class
|
||||
) );
|
||||
$line_subtotal_taxes = WC_Tax::calc_tax( $line_subtotal, $tax_rates, false );
|
||||
$line_taxes = WC_Tax::calc_tax( $line_total, $tax_rates, false );
|
||||
$line_subtotal_tax = max( 0, array_sum( $line_subtotal_taxes ) );
|
||||
$line_tax = max( 0, array_sum( $line_taxes ) );
|
||||
$tax_total += $line_tax;
|
||||
|
||||
wc_update_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( $line_subtotal_tax ) );
|
||||
wc_update_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $line_tax ) );
|
||||
|
||||
// Sum the item taxes
|
||||
foreach ( array_keys( $taxes + $line_taxes ) as $key ) {
|
||||
$taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now calculate shipping tax
|
||||
$matched_tax_rates = array();
|
||||
$tax_rates = WC_Tax::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
'city' => $city,
|
||||
'tax_class' => ''
|
||||
) );
|
||||
|
||||
if ( $tax_rates ) {
|
||||
foreach ( $tax_rates as $key => $rate ) {
|
||||
if ( isset( $rate['shipping'] ) && 'yes' === $rate['shipping'] ) {
|
||||
$matched_tax_rates[ $key ] = $rate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$shipping_taxes = WC_Tax::calc_shipping_tax( $this->order_shipping, $matched_tax_rates );
|
||||
$shipping_tax_total = WC_Tax::round( array_sum( $shipping_taxes ) );
|
||||
|
||||
// Save tax totals
|
||||
$this->set_total( $shipping_tax_total, 'shipping_tax' );
|
||||
$this->set_total( $tax_total, 'tax' );
|
||||
|
||||
// Tax rows
|
||||
$this->remove_order_items( 'tax' );
|
||||
|
||||
// Now merge to keep tax rows
|
||||
foreach ( array_keys( $taxes + $shipping_taxes ) as $tax_rate_id ) {
|
||||
$this->add_tax( $tax_rate_id, isset( $taxes[ $tax_rate_id ] ) ? $taxes[ $tax_rate_id ] : 0, isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] : 0 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate totals by looking at the contents of the order. Stores the totals and returns the orders final total.
|
||||
*
|
||||
* @return $total calculated grand total
|
||||
*/
|
||||
public function calculate_totals() {
|
||||
$cart_subtotal = 0;
|
||||
$cart_total = 0;
|
||||
$fee_total = 0;
|
||||
|
||||
$this->calculate_taxes();
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
foreach ( $this->get_fees() as $item ) {
|
||||
$fee_total += $item['line_total'];
|
||||
}
|
||||
|
||||
$grand_total = round( $cart_total + $fee_total + $this->get_total_shipping() - $this->get_order_discount() + $this->get_cart_tax() + $this->get_shipping_tax(), absint( get_option( 'woocommerce_price_num_decimals' ) ) );
|
||||
|
||||
$this->set_total( $cart_subtotal - $cart_total, 'cart_discount' );
|
||||
$this->set_total( $grand_total, 'total' );
|
||||
|
||||
return $grand_total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an order from the database.
|
||||
|
@ -53,7 +407,6 @@ class WC_Order {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populates an order from the loaded post data.
|
||||
*
|
||||
|
@ -160,7 +513,6 @@ class WC_Order {
|
|||
if ( $key == $this->order_key ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -260,7 +612,6 @@ class WC_Order {
|
|||
return $this->formatted_shipping_address;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the shipping address in an array.
|
||||
*
|
||||
|
@ -930,7 +1281,7 @@ class WC_Order {
|
|||
* @return WC_Product
|
||||
*/
|
||||
public function get_product_from_item( $item ) {
|
||||
$_product = get_product( $item['variation_id'] ? $item['variation_id'] : $item['product_id'] );
|
||||
$_product = get_product( ! empty( $item['variation_id'] ) ? $item['variation_id'] : $item['product_id'] );
|
||||
|
||||
return apply_filters( 'woocommerce_get_product_from_item', $_product, $item, $this );
|
||||
}
|
||||
|
@ -1352,6 +1703,9 @@ class WC_Order {
|
|||
|
||||
// Record the completed date of the order
|
||||
update_post_meta( $this->id, '_completed_date', current_time('mysql') );
|
||||
|
||||
// Update reports
|
||||
wc_delete_shop_order_transients( $this->id );
|
||||
break;
|
||||
case 'processing' :
|
||||
case 'on-hold' :
|
||||
|
@ -1360,15 +1714,19 @@ class WC_Order {
|
|||
|
||||
// Increase coupon usage counts
|
||||
$this->increase_coupon_usage_counts();
|
||||
|
||||
// Update reports
|
||||
wc_delete_shop_order_transients( $this->id );
|
||||
break;
|
||||
case 'cancelled' :
|
||||
// If the order is cancelled, restore used coupons
|
||||
$this->decrease_coupon_usage_counts();
|
||||
|
||||
// Update reports
|
||||
wc_delete_shop_order_transients( $this->id );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wc_delete_shop_order_transients( $this->id );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1610,10 +1968,8 @@ class WC_Order {
|
|||
|
||||
$this->add_order_note( __( 'Order item stock reduced successfully.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* send_stock_notifications function.
|
||||
*
|
||||
|
|
|
@ -3,28 +3,24 @@
|
|||
* Performs tax calculations and loads tax rates.
|
||||
*
|
||||
* @class WC_Tax
|
||||
* @version 2.0.0
|
||||
* @version 2.2.0
|
||||
* @package WooCommerce/Classes
|
||||
* @category Class
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_Tax {
|
||||
|
||||
/** @var array */
|
||||
public $matched_rates;
|
||||
|
||||
|
||||
var $log = array();
|
||||
|
||||
public static $precision;
|
||||
public static $round_at_subtotal;
|
||||
|
||||
/**
|
||||
* __construct function.
|
||||
* Load options
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->precision = WC_ROUNDING_PRECISION;
|
||||
$this->dp = (int) get_option( 'woocommerce_price_num_decimals' );
|
||||
$this->round_at_subtotal = get_option('woocommerce_tax_round_at_subtotal') == 'yes';
|
||||
public static function init() {
|
||||
self::$precision = WC_ROUNDING_PRECISION;
|
||||
self::$round_at_subtotal = 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,23 +31,23 @@ class WC_Tax {
|
|||
* @param boolean $suppress_rounding Whether to suppress any rounding from taking place
|
||||
* @return array Array of rates + prices after tax
|
||||
*/
|
||||
public function calc_tax( $price, $rates, $price_includes_tax = false, $suppress_rounding = false ) {
|
||||
public static function calc_tax( $price, $rates, $price_includes_tax = false, $suppress_rounding = false ) {
|
||||
// Work in pence to X precision
|
||||
$price = $this->precision( $price );
|
||||
$price = self::precision( $price );
|
||||
|
||||
if ( $price_includes_tax )
|
||||
$taxes = $this->calc_inclusive_tax( $price, $rates );
|
||||
$taxes = self::calc_inclusive_tax( $price, $rates );
|
||||
else
|
||||
$taxes = $this->calc_exclusive_tax( $price, $rates );
|
||||
$taxes = self::calc_exclusive_tax( $price, $rates );
|
||||
|
||||
// Round to precision
|
||||
if ( ! $this->round_at_subtotal && ! $suppress_rounding ) {
|
||||
if ( ! self::$round_at_subtotal && ! $suppress_rounding ) {
|
||||
$taxes = array_map( 'round', $taxes ); // Round to precision
|
||||
}
|
||||
|
||||
// Remove precision
|
||||
$price = $this->remove_precision( $price );
|
||||
$taxes = array_map( array( $this, 'remove_precision' ), $taxes );
|
||||
$price = self::remove_precision( $price );
|
||||
$taxes = array_map( array( __CLASS__, 'remove_precision' ), $taxes );
|
||||
|
||||
return apply_filters( 'woocommerce_calc_tax', $taxes, $price, $rates, $price_includes_tax, $suppress_rounding );
|
||||
}
|
||||
|
@ -63,8 +59,8 @@ class WC_Tax {
|
|||
* @param array Taxation Rate
|
||||
* @return array
|
||||
*/
|
||||
public function calc_shipping_tax( $price, $rates ) {
|
||||
return $this->calc_exclusive_tax( $price, $rates );
|
||||
public static function calc_shipping_tax( $price, $rates ) {
|
||||
return self::calc_exclusive_tax( $price, $rates );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,8 +68,8 @@ class WC_Tax {
|
|||
* @param float $price
|
||||
* @return float
|
||||
*/
|
||||
private function precision( $price ) {
|
||||
return $price * ( pow( 10, $this->precision ) );
|
||||
private static function precision( $price ) {
|
||||
return $price * ( pow( 10, self::$precision ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,8 +77,8 @@ class WC_Tax {
|
|||
* @param float $price
|
||||
* @return float
|
||||
*/
|
||||
private function remove_precision( $price ) {
|
||||
return $price / ( pow( 10, $this->precision ) );
|
||||
private static function remove_precision( $price ) {
|
||||
return $price / ( pow( 10, self::$precision ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,8 +91,8 @@ class WC_Tax {
|
|||
* }
|
||||
* add_filter( 'woocommerce_tax_round', 'euro_5cent_rounding' );
|
||||
*/
|
||||
public function round( $in ) {
|
||||
return apply_filters( 'woocommerce_tax_round', round( $in, $this->precision ), $in );
|
||||
public static function round( $in ) {
|
||||
return apply_filters( 'woocommerce_tax_round', round( $in, self::$precision ), $in );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +102,7 @@ class WC_Tax {
|
|||
* @param array $rates
|
||||
* @return array
|
||||
*/
|
||||
private function calc_inclusive_tax( $price, $rates ) {
|
||||
private static function calc_inclusive_tax( $price, $rates ) {
|
||||
$taxes = array();
|
||||
|
||||
$regular_tax_rates = $compound_tax_rates = 0;
|
||||
|
@ -150,7 +146,7 @@ class WC_Tax {
|
|||
* @param array $rates
|
||||
* @return array
|
||||
*/
|
||||
private function calc_exclusive_tax( $price, $rates ) {
|
||||
private static function calc_exclusive_tax( $price, $rates ) {
|
||||
$taxes = array();
|
||||
|
||||
// Multiple taxes
|
||||
|
@ -205,7 +201,7 @@ class WC_Tax {
|
|||
* @param array $args
|
||||
* @return array
|
||||
*/
|
||||
public function find_rates( $args = array() ) {
|
||||
public static function find_rates( $args = array() ) {
|
||||
global $wpdb;
|
||||
|
||||
$defaults = array(
|
||||
|
@ -318,7 +314,7 @@ class WC_Tax {
|
|||
* @param string $tax_class
|
||||
* @return array
|
||||
*/
|
||||
public function get_rates( $tax_class = '' ) {
|
||||
public static function get_rates( $tax_class = '' ) {
|
||||
|
||||
$tax_class = sanitize_title( $tax_class );
|
||||
|
||||
|
@ -327,7 +323,7 @@ class WC_Tax {
|
|||
|
||||
list( $country, $state, $postcode, $city ) = WC()->customer->get_taxable_address();
|
||||
|
||||
$matched_tax_rates = $this->find_rates( array(
|
||||
$matched_tax_rates = self::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
|
@ -341,7 +337,7 @@ class WC_Tax {
|
|||
// Prices excluding tax however should just not add any taxes, as they will be added during checkout.
|
||||
// The woocommerce_default_customer_address option (when set to base) is also used here.
|
||||
$matched_tax_rates = get_option( 'woocommerce_prices_include_tax' ) == 'yes' || get_option( 'woocommerce_default_customer_address' ) == 'base'
|
||||
? $this->get_shop_base_rate( $tax_class )
|
||||
? self::get_shop_base_rate( $tax_class )
|
||||
: array();
|
||||
|
||||
}
|
||||
|
@ -355,8 +351,8 @@ class WC_Tax {
|
|||
* @param string Tax Class
|
||||
* @return array
|
||||
*/
|
||||
public function get_shop_base_rate( $tax_class = '' ) {
|
||||
return $this->find_rates( array(
|
||||
public static function get_shop_base_rate( $tax_class = '' ) {
|
||||
return self::find_rates( array(
|
||||
'country' => WC()->countries->get_base_country(),
|
||||
'state' => WC()->countries->get_base_state(),
|
||||
'postcode' => WC()->countries->get_base_postcode(),
|
||||
|
@ -371,7 +367,7 @@ class WC_Tax {
|
|||
* @param string Tax Class
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_shipping_tax_rates( $tax_class = null ) {
|
||||
public static function get_shipping_tax_rates( $tax_class = null ) {
|
||||
|
||||
// See if we have an explicitly set shipping tax class
|
||||
if ( $shipping_tax_class = get_option( 'woocommerce_shipping_tax_class' ) ) {
|
||||
|
@ -403,7 +399,7 @@ class WC_Tax {
|
|||
$matched_tax_rates = array();
|
||||
|
||||
// This will be per item shipping
|
||||
$rates = $this->find_rates( array(
|
||||
$rates = self::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
|
@ -418,7 +414,7 @@ class WC_Tax {
|
|||
|
||||
if ( sizeof( $matched_tax_rates ) == 0 ) {
|
||||
// Get standard rate
|
||||
$rates = $this->find_rates( array(
|
||||
$rates = self::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'city' => $city,
|
||||
|
@ -451,7 +447,7 @@ class WC_Tax {
|
|||
if ( sizeof( $found_tax_classes ) > 1 ) {
|
||||
|
||||
if ( in_array( '', $found_tax_classes ) ) {
|
||||
$rates = $this->find_rates( array(
|
||||
$rates = self::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'city' => $city,
|
||||
|
@ -462,7 +458,7 @@ class WC_Tax {
|
|||
|
||||
foreach ( $tax_classes as $tax_class ) {
|
||||
if ( in_array( $tax_class, $found_tax_classes ) ) {
|
||||
$rates = $this->find_rates( array(
|
||||
$rates = self::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
|
@ -477,7 +473,7 @@ class WC_Tax {
|
|||
// If a single tax class is found, use it
|
||||
} elseif ( sizeof( $found_tax_classes ) == 1 ) {
|
||||
|
||||
$rates = $this->find_rates( array(
|
||||
$rates = self::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
|
@ -489,7 +485,7 @@ class WC_Tax {
|
|||
|
||||
// If no class rate are found, use standard rates
|
||||
if ( ! $rates )
|
||||
$rates = $this->find_rates( array(
|
||||
$rates = self::find_rates( array(
|
||||
'country' => $country,
|
||||
'state' => $state,
|
||||
'postcode' => $postcode,
|
||||
|
@ -513,7 +509,7 @@ class WC_Tax {
|
|||
* @param int key
|
||||
* @return bool
|
||||
*/
|
||||
public function is_compound( $key ) {
|
||||
public static function is_compound( $key ) {
|
||||
global $wpdb;
|
||||
return $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_compound FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) ) ? true : false;
|
||||
}
|
||||
|
@ -524,7 +520,7 @@ class WC_Tax {
|
|||
* @param int key
|
||||
* @return string
|
||||
*/
|
||||
public function get_rate_label( $key ) {
|
||||
public static function get_rate_label( $key ) {
|
||||
global $wpdb;
|
||||
|
||||
$rate_name = $wpdb->get_var( $wpdb->prepare( "SELECT tax_rate_name FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) );
|
||||
|
@ -532,7 +528,7 @@ class WC_Tax {
|
|||
if ( ! $rate_name )
|
||||
$rate_name = WC()->countries->tax_or_vat();
|
||||
|
||||
return apply_filters( 'woocommerce_rate_label', $rate_name, $key, $this );
|
||||
return apply_filters( 'woocommerce_rate_label', $rate_name, $key );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -542,7 +538,7 @@ class WC_Tax {
|
|||
* @param mixed $key
|
||||
* @return string
|
||||
*/
|
||||
public function get_rate_code( $key ) {
|
||||
public static function get_rate_code( $key ) {
|
||||
global $wpdb;
|
||||
|
||||
$rate = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %s", $key ) );
|
||||
|
@ -558,7 +554,7 @@ class WC_Tax {
|
|||
$code[] = $rate->tax_rate_name ? $rate->tax_rate_name : 'TAX';
|
||||
$code[] = absint( $rate->tax_rate_priority );
|
||||
|
||||
return apply_filters( 'woocommerce_rate_code', strtoupper( implode( '-', array_filter( $code ) ) ), $key, $this );
|
||||
return apply_filters( 'woocommerce_rate_code', strtoupper( implode( '-', array_filter( $code ) ) ), $key );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -567,7 +563,8 @@ class WC_Tax {
|
|||
* @param array
|
||||
* @return float
|
||||
*/
|
||||
public function get_tax_total( $taxes ) {
|
||||
return array_sum( array_map( array( $this, 'round' ), $taxes ) );
|
||||
public static function get_tax_total( $taxes ) {
|
||||
return array_sum( array_map( array( __CLASS__, 'round' ), $taxes ) );
|
||||
}
|
||||
}
|
||||
WC_Tax::init();
|
|
@ -42,6 +42,87 @@ add_filter( 'woocommerce_short_description', 'shortcode_unautop' );
|
|||
add_filter( 'woocommerce_short_description', 'prepend_attachment' );
|
||||
add_filter( 'woocommerce_short_description', 'do_shortcode', 11 ); // AFTER wpautop()
|
||||
|
||||
/**
|
||||
* Create a new order programmatically
|
||||
*
|
||||
* Returns a new order object on success which can then be used to add additonal data.
|
||||
*
|
||||
* @return WC_Order on success, WP_Error on failure
|
||||
*/
|
||||
function wc_create_order( $args = array() ) {
|
||||
$default_args = array(
|
||||
'status' => '',
|
||||
'customer_id' => null,
|
||||
'customer_note' => null,
|
||||
'order_id' => 0
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $default_args );
|
||||
$order_data = array();
|
||||
|
||||
if ( $args['order_id'] > 0 ) {
|
||||
$updating = true;
|
||||
$order_data['ID'] = $args['order_id'];
|
||||
} else {
|
||||
$updating = false;
|
||||
$order_data['post_type'] = 'shop_order';
|
||||
$order_data['post_status'] = 'wc-' . apply_filters( 'woocommerce_default_order_status', 'pending' );
|
||||
$order_data['ping_status'] = 'closed';
|
||||
$order_data['post_author'] = 1;
|
||||
$order_data['post_password'] = uniqid( 'order_' );
|
||||
$order_data['post_title'] = sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) );
|
||||
}
|
||||
|
||||
if ( $args['status'] ) {
|
||||
if ( ! in_array( 'wc-' . $args['status'], array_keys( wc_get_order_statuses() ) ) ) {
|
||||
return new WP_Error( __( 'Invalid order status', 'woocommerce' ) );
|
||||
}
|
||||
$order_data['post_status'] = 'wc-' . $args['status'];
|
||||
}
|
||||
|
||||
if ( ! is_null( $args['customer_note'] ) ) {
|
||||
$order_data['post_excerpt'] = $args['customer_note'];
|
||||
}
|
||||
|
||||
if ( $updating ) {
|
||||
$order_id = wp_update_post( $order_data );
|
||||
} else {
|
||||
$order_id = wp_insert_post( apply_filters( 'woocommerce_new_order_data', $order_data ), true );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $order_id ) ) {
|
||||
return $order_id;
|
||||
}
|
||||
|
||||
// Default order meta data.
|
||||
if ( ! $updating ) {
|
||||
update_post_meta( $order_id, '_order_key', 'wc_' . apply_filters( 'woocommerce_generate_order_key', uniqid( 'order_' ) ) );
|
||||
update_post_meta( $order_id, '_order_currency', get_woocommerce_currency() );
|
||||
update_post_meta( $order_id, '_prices_include_tax', get_option( 'woocommerce_prices_include_tax' ) );
|
||||
update_post_meta( $order_id, '_customer_ip_address', isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'] );
|
||||
update_post_meta( $order_id, '_customer_user_agent', isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '' );
|
||||
update_post_meta( $order_id, '_customer_user', 0 );
|
||||
}
|
||||
|
||||
if ( is_numeric( $args['customer_id'] ) ) {
|
||||
update_post_meta( $order_id, '_customer_user', $args['customer_id'] );
|
||||
}
|
||||
|
||||
return new WC_Order( $order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an order. Uses wc_create_order.
|
||||
* @param array $args
|
||||
* @return WC_Error | WC_Order
|
||||
*/
|
||||
function wc_update_order( $args ) {
|
||||
if ( ! $args['order_id'] ) {
|
||||
return new WP_Error( __( 'Invalid order ID', 'woocommerce' ) );
|
||||
}
|
||||
return wc_create_order( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template part (for templates like the shop-loop).
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue