2014-06-13 13:35:53 +00:00
< ? php
/**
* Abstract Order
*
* The WooCommerce order class handles order data .
*
2014-08-31 05:49:58 +00:00
* @ class WC_Order
* @ version 2.2 . 0
* @ package WooCommerce / Classes
* @ category Class
* @ author WooThemes
2015-01-20 13:01:19 +00:00
*
2015-01-20 11:06:15 +00:00
* @ property string $billing_first_name The billing address first name
2015-01-20 11:23:17 +00:00
* @ property string $billing_last_name The billing address last name
* @ property string $billing_company The billing address company
* @ property string $billing_address_1 The first line of the billing address
* @ property string $billing_address_2 The second line of the billing address
* @ property string $billing_city The city of the billing address
* @ property string $billing_state The state of the billing address
* @ property string $billing_postcode The postcode of the billing address
* @ property string $billing_country The country of the billing address
* @ property string $billing_phone The billing phone number
* @ property string $billing_email The billing email
* @ property string $shipping_first_name The shipping address first name
* @ property string $shipping_last_name The shipping address last name
* @ property string $shipping_company The shipping address company
* @ property string $shipping_address_1 The first line of the shipping address
* @ property string $shipping_address_2 The second line of the shipping address
* @ property string $shipping_city The city of the shipping address
* @ property string $shipping_state The state of the shipping address
* @ property string $shipping_postcode The postcode of the shipping address
* @ property string $shipping_country The country of the shipping address
2015-01-20 12:07:33 +00:00
* @ property string $cart_discount Total amount of discount
* @ property string $cart_discount_tax Total amount of discount applied to taxes
2015-01-20 12:34:40 +00:00
* @ property string $shipping_method_title < 2.1 was used for shipping method title . Now @ deprecated .
2015-02-03 12:57:08 +00:00
* @ property int $customer_user User ID who the order belongs to . 0 for guests .
* @ property string $order_key Random key / password unqique to each order .
2015-02-03 13:13:07 +00:00
* @ property string $order_discount Stored after tax discounts pre - 2.3 . Now @ deprecated .
2015-02-03 12:57:08 +00:00
* @ property string $order_tax Stores order tax total .
* @ property string $order_shipping_tax Stores shipping tax total .
* @ property string $order_shipping Stores shipping total .
* @ property string $order_total Stores order total .
* @ property string $order_currency Stores currency code used for the order .
2015-02-03 14:38:42 +00:00
* @ property string $payment_method method ID .
2015-02-03 12:57:08 +00:00
* @ property string $payment_method_title Name of the payment method used .
2015-02-03 14:38:42 +00:00
* @ property string $customer_ip_address Customer IP Address
* @ property string $customer_user_agent Customer User agent
2014-06-13 13:35:53 +00:00
*/
abstract class WC_Abstract_Order {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
/** @public int Order (post) ID */
2015-01-20 12:07:33 +00:00
public $id = 0 ;
2014-10-07 10:00:10 +00:00
2015-02-03 12:28:15 +00:00
/** @var $post WP_Post */
2015-01-20 12:07:33 +00:00
public $post = null ;
2014-06-13 13:35:53 +00:00
/** @public string Order type */
2015-07-15 15:02:26 +00:00
public $order_type = false ;
2015-01-20 12:07:33 +00:00
/** @public string Order Date */
public $order_date = '' ;
/** @public string Order Modified Date */
public $modified_date = '' ;
/** @public string Customer Message (excerpt) */
public $customer_message = '' ;
/** @public string Customer Note */
public $customer_note = '' ;
/** @public string Order Status */
public $post_status = '' ;
2014-06-13 13:35:53 +00:00
2014-10-07 10:00:10 +00:00
/** @public bool Do prices include tax? */
2015-01-20 12:07:33 +00:00
public $prices_include_tax = false ;
2014-10-07 10:00:10 +00:00
/** @public string Display mode for taxes in cart */
2015-01-20 12:34:40 +00:00
public $tax_display_cart = '' ;
2014-10-07 10:00:10 +00:00
/** @public bool Do totals display ex tax? */
2015-01-20 12:07:33 +00:00
public $display_totals_ex_tax = false ;
2014-10-07 10:00:10 +00:00
/** @public bool Do cart prices display ex tax? */
2015-01-20 12:07:33 +00:00
public $display_cart_ex_tax = false ;
2015-01-20 13:01:19 +00:00
/** @protected string Formatted address. Accessed via get_formatted_billing_address() */
protected $formatted_billing_address = '' ;
2015-01-20 12:07:33 +00:00
2015-01-20 13:01:19 +00:00
/** @protected string Formatted address. Accessed via get_formatted_shipping_address() */
protected $formatted_shipping_address = '' ;
2015-01-20 12:07:33 +00:00
2014-06-13 13:35:53 +00:00
/**
* Get the order if ID is passed , otherwise the order is new and empty .
2014-06-14 21:36:20 +00:00
* This class should NOT be instantiated , but the get_order function or new WC_Order_Factory
* should be used . It is possible , but the aforementioned are preferred and are the only
* methods that will be maintained going forward .
2015-01-20 13:20:22 +00:00
*
2015-01-20 14:00:30 +00:00
* @ param int $order
2014-06-13 13:35:53 +00:00
*/
2015-01-20 13:20:22 +00:00
public function __construct ( $order = 0 ) {
2014-10-07 10:00:10 +00:00
$this -> prices_include_tax = get_option ( 'woocommerce_prices_include_tax' ) == 'yes' ? true : false ;
$this -> tax_display_cart = get_option ( 'woocommerce_tax_display_cart' );
2014-06-13 13:35:53 +00:00
$this -> display_totals_ex_tax = $this -> tax_display_cart == 'excl' ? true : false ;
$this -> display_cart_ex_tax = $this -> tax_display_cart == 'excl' ? true : false ;
2014-10-14 13:25:48 +00:00
$this -> init ( $order );
}
2014-08-31 05:49:58 +00:00
2014-10-14 13:25:48 +00:00
/**
2014-11-11 20:32:06 +00:00
* Init / load the order object . Called from the constructor .
2014-10-14 13:25:48 +00:00
*
2015-02-03 13:13:07 +00:00
* @ param int | object | WC_Order $order Order to init
2014-10-14 13:25:48 +00:00
*/
protected function init ( $order ) {
if ( is_numeric ( $order ) ) {
2014-10-07 10:00:10 +00:00
$this -> id = absint ( $order );
2014-06-13 13:35:53 +00:00
$this -> post = get_post ( $order );
2014-06-13 13:38:24 +00:00
$this -> get_order ( $this -> id );
2014-06-13 13:35:53 +00:00
} elseif ( $order instanceof WC_Order ) {
2014-10-07 10:00:10 +00:00
$this -> id = absint ( $order -> id );
2014-06-13 13:35:53 +00:00
$this -> post = $order -> post ;
2014-06-13 13:38:24 +00:00
$this -> get_order ( $this -> id );
2015-02-03 13:16:41 +00:00
} elseif ( isset ( $order -> ID ) ) {
2014-10-07 10:00:10 +00:00
$this -> id = absint ( $order -> ID );
2014-06-13 13:35:53 +00:00
$this -> post = $order ;
2014-06-13 13:38:24 +00:00
$this -> get_order ( $this -> id );
2014-06-13 13:35:53 +00:00
}
}
2014-07-03 11:38:55 +00:00
/**
* Remove all line items ( products , coupons , shipping , taxes ) from the order .
2014-08-31 05:49:58 +00:00
*
* @ param string $type Order item type . Default null .
2014-07-03 11:38:55 +00:00
*/
public function remove_order_items ( $type = null ) {
global $wpdb ;
2015-03-27 15:15:40 +00:00
if ( ! empty ( $type ) ) {
2014-11-21 07:18:31 +00:00
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM itemmeta USING { $wpdb -> prefix } woocommerce_order_itemmeta itemmeta INNER JOIN { $wpdb -> prefix } woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id AND items.order_id = %d AND items.order_item_type = %s " , $this -> id , $type ) );
2014-07-03 11:38:55 +00:00
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_order_items WHERE order_id = %d AND order_item_type = %s " , $this -> id , $type ) );
} else {
2015-02-11 22:14:24 +00:00
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM itemmeta USING { $wpdb -> prefix } woocommerce_order_itemmeta itemmeta INNER JOIN { $wpdb -> prefix } woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id and items.order_id = %d " , $this -> id ) );
2014-07-03 11:38:55 +00:00
$wpdb -> query ( $wpdb -> prepare ( " DELETE FROM { $wpdb -> prefix } woocommerce_order_items WHERE order_id = %d " , $this -> id ) );
}
}
/**
* Set the payment method for the order
2014-08-31 05:49:58 +00:00
*
2014-07-03 11:38:55 +00:00
* @ param WC_Payment_Gateway
2014-09-07 23:37:55 +00:00
* @ param WC_Payment_Gateway $payment_method
2014-07-03 11:38:55 +00:00
*/
public function set_payment_method ( $payment_method ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
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
2014-08-31 05:49:58 +00:00
*
2014-07-03 11:38:55 +00:00
* @ param array $address Address data
* @ param string $type billing or shipping
*/
public function set_address ( $address , $type = 'billing' ) {
2014-08-31 05:49:58 +00:00
2014-09-11 20:12:17 +00:00
foreach ( $address as $key => $value ) {
2014-07-03 11:38:55 +00:00
update_post_meta ( $this -> id , " _ { $type } _ " . $key , $value );
}
2014-07-28 03:23:59 +00:00
}
2014-07-03 11:38:55 +00:00
2015-06-19 00:43:31 +00:00
/**
* Returns the requested address in raw , non - formatted way
2015-06-19 12:43:18 +00:00
* @ since 2.4 . 0
2015-06-19 00:43:31 +00:00
* @ param string $type Billing or shipping . Anything else besides 'billing' will return shipping address
* @ return array The stored address after filter
*/
public function get_address ( $type = 'billing' ) {
if ( 'billing' === $type ) {
$address = array (
'first_name' => $this -> billing_first_name ,
'last_name' => $this -> billing_last_name ,
'company' => $this -> billing_company ,
'address_1' => $this -> billing_address_1 ,
'address_2' => $this -> billing_address_2 ,
'city' => $this -> billing_city ,
'state' => $this -> billing_state ,
'postcode' => $this -> billing_postcode ,
'country' => $this -> billing_country ,
'email' => $this -> billing_email ,
'phone' => $this -> billing_phone ,
);
} else {
$address = array (
'first_name' => $this -> shipping_first_name ,
'last_name' => $this -> shipping_last_name ,
'company' => $this -> shipping_company ,
'address_1' => $this -> shipping_address_1 ,
'address_2' => $this -> shipping_address_2 ,
'city' => $this -> shipping_city ,
'state' => $this -> shipping_state ,
'postcode' => $this -> shipping_postcode ,
'country' => $this -> shipping_country ,
);
}
return apply_filters ( 'woocommerce_get_order_address' , $address , $type , $this );
}
2014-07-03 11:38:55 +00:00
/**
* Add a product line item to the order
2014-07-28 03:23:59 +00:00
*
* @ since 2.2
* @ param \WC_Product $product
2014-07-03 11:38:55 +00:00
* @ param int $qty Line item quantity
2014-07-28 03:23:59 +00:00
* @ param array $args
2014-07-03 11:38:55 +00:00
* @ return int | bool Item ID or false
*/
public function add_product ( $product , $qty = 1 , $args = array () ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$default_args = array (
'variation' => array (),
'totals' => array ()
);
$args = wp_parse_args ( $args , $default_args );
2014-07-19 03:15:41 +00:00
$item_id = wc_add_order_item ( $this -> id , array (
2014-07-03 11:38:55 +00:00
'order_item_name' => $product -> get_title (),
'order_item_type' => 'line_item'
2014-07-19 03:15:41 +00:00
) );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
if ( ! $item_id ) {
return false ;
}
2014-07-03 11:38:55 +00:00
2014-08-31 05:49:58 +00:00
wc_add_order_item_meta ( $item_id , '_qty' , wc_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 );
2014-07-19 03:15:41 +00:00
wc_add_order_item_meta ( $item_id , '_variation_id' , isset ( $product -> variation_id ) ? $product -> variation_id : 0 );
2014-07-28 03:23:59 +00:00
2014-07-19 03:15:41 +00:00
// Set line item totals, either passed in or from the product
2014-08-31 05:49:58 +00:00
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 [ 'totals' ][ 'total' ] : $product -> get_price_excluding_tax ( $qty ) ) );
2014-07-19 03:15:41 +00:00
wc_add_order_item_meta ( $item_id , '_line_subtotal_tax' , wc_format_decimal ( isset ( $args [ 'totals' ][ 'subtotal_tax' ] ) ? $args [ 'totals' ][ 'subtotal_tax' ] : 0 ) );
2014-08-31 05:49:58 +00:00
wc_add_order_item_meta ( $item_id , '_line_tax' , wc_format_decimal ( isset ( $args [ 'totals' ][ 'tax' ] ) ? $args [ 'totals' ][ 'tax' ] : 0 ) );
2014-07-03 11:38:55 +00:00
2014-07-19 04:08:02 +00:00
// Save tax data - Since 2.2
if ( isset ( $args [ 'totals' ][ 'tax_data' ] ) ) {
2014-08-31 05:49:58 +00:00
2014-07-19 04:08:02 +00:00
$tax_data = array ();
$tax_data [ 'total' ] = array_map ( 'wc_format_decimal' , $args [ 'totals' ][ 'tax_data' ][ 'total' ] );
$tax_data [ 'subtotal' ] = array_map ( 'wc_format_decimal' , $args [ 'totals' ][ 'tax_data' ][ 'subtotal' ] );
2014-07-03 11:38:55 +00:00
2014-07-19 04:08:02 +00:00
wc_add_order_item_meta ( $item_id , '_line_tax_data' , $tax_data );
} else {
wc_add_order_item_meta ( $item_id , '_line_tax_data' , array ( 'total' => array (), 'subtotal' => array () ) );
}
2014-07-19 03:15:41 +00:00
// Add variation meta
if ( ! empty ( $args [ 'variation' ] ) ) {
foreach ( $args [ 'variation' ] as $key => $value ) {
wc_add_order_item_meta ( $item_id , str_replace ( 'attribute_' , '' , $key ), $value );
}
}
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
// 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 () ) );
2014-07-03 11:38:55 +00:00
}
do_action ( 'woocommerce_order_add_product' , $this -> id , $item_id , $product , $qty , $args );
return $item_id ;
}
2014-07-28 03:28:25 +00:00
/**
* Update a line item for the order
*
* Note this does not update order totals
*
* @ since 2.2
* @ param int $item_id order item ID
* @ param array $args data to update
2015-01-23 14:37:20 +00:00
* @ param WC_Product $product
2014-07-28 03:28:25 +00:00
* @ return bool
*/
public function update_product ( $item_id , $product , $args ) {
if ( ! $item_id || ! is_object ( $product ) ) {
return false ;
}
// quantity
if ( isset ( $args [ 'qty' ] ) ) {
wc_update_order_item_meta ( $item_id , '_qty' , wc_stock_amount ( $args [ 'qty' ] ) );
}
// tax class
if ( isset ( $args [ 'tax_class' ] ) ) {
wc_update_order_item_meta ( $item_id , '_tax_class' , $args [ 'tax_class' ] );
}
// set item totals, either provided or from product
if ( isset ( $args [ 'qty' ] ) ) {
wc_update_order_item_meta ( $item_id , '_line_subtotal' , wc_format_decimal ( isset ( $args [ 'totals' ][ 'subtotal' ] ) ? $args [ 'totals' ][ 'subtotal' ] : $product -> get_price_excluding_tax ( $args [ 'qty' ] ) ) );
wc_update_order_item_meta ( $item_id , '_line_total' , wc_format_decimal ( isset ( $args [ 'totals' ][ 'total' ] ) ? $args [ 'totals' ][ 'total' ] : $product -> get_price_excluding_tax ( $args [ 'qty' ] ) ) );
}
// set item tax totals
wc_update_order_item_meta ( $item_id , '_line_subtotal_tax' , wc_format_decimal ( isset ( $args [ 'totals' ][ 'subtotal_tax' ] ) ? $args [ 'totals' ][ 'subtotal_tax' ] : 0 ) );
wc_update_order_item_meta ( $item_id , '_line_tax' , wc_format_decimal ( isset ( $args [ 'totals' ][ 'tax' ] ) ? $args [ 'totals' ][ 'tax' ] : 0 ) );
// variation meta
if ( isset ( $args [ 'variation' ] ) && is_array ( $args [ 'variation' ] ) ) {
2014-08-31 05:49:58 +00:00
2014-07-28 03:28:25 +00:00
foreach ( $args [ 'variation' ] as $key => $value ) {
wc_update_order_item_meta ( $item_id , str_replace ( 'attribute_' , '' , $key ), $value );
}
}
// backorders
if ( isset ( $args [ 'qty' ] ) && $product -> backorders_require_notification () && $product -> is_on_backorder ( $args [ 'qty' ] ) ) {
wc_update_order_item_meta ( $item_id , apply_filters ( 'woocommerce_backordered_item_meta_name' , __ ( 'Backordered' , 'woocommerce' ) ), $args [ 'qty' ] - max ( 0 , $product -> get_total_stock () ) );
}
do_action ( 'woocommerce_order_edit_product' , $this -> id , $item_id , $args , $product );
return true ;
}
2014-07-03 11:38:55 +00:00
/**
* Add coupon code to the order
2014-07-28 03:23:59 +00:00
*
* @ param string $code
2014-09-07 23:37:55 +00:00
* @ param integer $discount_amount
2014-11-25 13:05:03 +00:00
* @ param integer $discount_amount_tax " Discounted " tax - used for tax inclusive prices
2014-07-03 11:38:55 +00:00
* @ return int | bool Item ID or false
*/
2014-11-25 13:05:03 +00:00
public function add_coupon ( $code , $discount_amount = 0 , $discount_amount_tax = 0 ) {
2014-07-03 11:38:55 +00:00
$item_id = wc_add_order_item ( $this -> id , array (
'order_item_name' => $code ,
'order_item_type' => 'coupon'
2014-07-19 03:15:41 +00:00
) );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
if ( ! $item_id ) {
return false ;
}
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
wc_add_order_item_meta ( $item_id , 'discount_amount' , $discount_amount );
2014-11-25 13:05:03 +00:00
wc_add_order_item_meta ( $item_id , 'discount_amount_tax' , $discount_amount_tax );
2014-07-03 11:38:55 +00:00
2014-11-25 13:05:03 +00:00
do_action ( 'woocommerce_order_add_coupon' , $this -> id , $item_id , $code , $discount_amount , $discount_amount_tax );
2014-07-03 11:38:55 +00:00
return $item_id ;
}
2014-07-28 03:28:25 +00:00
/**
* Update coupon for order
*
* Note this does not update order totals
*
* @ since 2.2
* @ param int $item_id
* @ param array $args
* @ return bool
*/
public function update_coupon ( $item_id , $args ) {
if ( ! $item_id ) {
return false ;
}
// code
if ( isset ( $args [ 'code' ] ) ) {
wc_update_order_item ( $item_id , array ( 'order_item_name' => $args [ 'code' ] ) );
}
// amount
if ( isset ( $args [ 'discount_amount' ] ) ) {
wc_update_order_item_meta ( $item_id , 'discount_amount' , wc_format_decimal ( $args [ 'discount_amount' ] ) );
}
2014-11-25 13:05:03 +00:00
if ( isset ( $args [ 'discount_amount_tax' ] ) ) {
wc_add_order_item_meta ( $item_id , 'discount_amount_tax' , wc_format_decimal ( $args [ 'discount_amount_tax' ] ) );
}
2014-07-28 03:28:25 +00:00
do_action ( 'woocommerce_order_update_coupon' , $this -> id , $item_id , $args );
return true ;
}
2014-07-03 11:38:55 +00:00
/**
* Add a tax row to the order
2014-07-28 03:23:59 +00:00
*
* @ since 2.2
2014-07-03 11:38:55 +00:00
* @ 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 ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$code = WC_Tax :: get_rate_code ( $tax_rate_id );
if ( ! $code ) {
return false ;
}
2014-07-28 03:23:59 +00:00
2014-07-03 11:38:55 +00:00
$item_id = wc_add_order_item ( $this -> id , array (
'order_item_name' => $code ,
'order_item_type' => 'tax'
2014-07-19 03:15:41 +00:00
) );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
if ( ! $item_id ) {
return false ;
}
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
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 ) );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
do_action ( 'woocommerce_order_add_tax' , $this -> id , $item_id , $tax_rate_id , $tax_amount , $shipping_tax_amount );
2014-07-03 11:38:55 +00:00
return $item_id ;
}
/**
* Add a shipping row to the order
2014-08-31 05:49:58 +00:00
*
2014-07-03 11:38:55 +00:00
* @ param WC_Shipping_Rate shipping_rate
* @ return int | bool Item ID or false
*/
public function add_shipping ( $shipping_rate ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$item_id = wc_add_order_item ( $this -> id , array (
2014-07-19 03:15:41 +00:00
'order_item_name' => $shipping_rate -> label ,
'order_item_type' => 'shipping'
) );
2014-07-03 11:38:55 +00:00
if ( ! $item_id ) {
2014-07-19 03:15:41 +00:00
return false ;
}
2014-07-03 11:38:55 +00:00
wc_add_order_item_meta ( $item_id , 'method_id' , $shipping_rate -> id );
2014-07-19 03:15:41 +00:00
wc_add_order_item_meta ( $item_id , 'cost' , wc_format_decimal ( $shipping_rate -> cost ) );
2014-07-03 11:38:55 +00:00
2014-07-20 03:32:52 +00:00
// Save shipping taxes - Since 2.2
$taxes = array_map ( 'wc_format_decimal' , $shipping_rate -> taxes );
wc_add_order_item_meta ( $item_id , 'taxes' , $taxes );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
do_action ( 'woocommerce_order_add_shipping' , $this -> id , $item_id , $shipping_rate );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
// Update total
$this -> set_total ( $this -> order_shipping + wc_format_decimal ( $shipping_rate -> cost ), 'shipping' );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
return $item_id ;
2014-07-03 11:38:55 +00:00
}
2014-07-28 03:28:25 +00:00
/**
* Update shipping method for order
*
* Note this does not update the order total
*
* @ since 2.2
* @ param int $item_id
* @ param array $args
* @ return bool
*/
public function update_shipping ( $item_id , $args ) {
if ( ! $item_id ) {
return false ;
}
// method title
if ( isset ( $args [ 'method_title' ] ) ) {
wc_update_order_item ( $item_id , array ( 'order_item_name' => $args [ 'method_title' ] ) );
}
// method ID
if ( isset ( $args [ 'method_id' ] ) ) {
wc_update_order_item_meta ( $item_id , 'method_id' , $args [ 'method_id' ] );
}
// method cost
if ( isset ( $args [ 'cost' ] ) ) {
2015-07-09 15:48:34 +00:00
// Get old cost before updating
$old_cost = wc_get_order_item_meta ( $item_id , 'cost' );
// Update
2014-07-28 03:28:25 +00:00
wc_update_order_item_meta ( $item_id , 'cost' , wc_format_decimal ( $args [ 'cost' ] ) );
2015-07-09 15:48:34 +00:00
// Update total
$this -> set_total ( $this -> order_shipping - wc_format_decimal ( $old_cost ) + wc_format_decimal ( $args [ 'cost' ] ), 'shipping' );
2014-07-28 03:28:25 +00:00
}
do_action ( 'woocommerce_order_update_shipping' , $this -> id , $item_id , $args );
return true ;
}
2014-07-03 11:38:55 +00:00
/**
* Add a fee to the order
2014-08-31 05:49:58 +00:00
*
2014-07-03 11:38:55 +00:00
* @ param object $fee
* @ return int | bool Item ID or false
*/
public function add_fee ( $fee ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$item_id = wc_add_order_item ( $this -> id , array (
'order_item_name' => $fee -> name ,
'order_item_type' => 'fee'
2014-07-19 03:15:41 +00:00
) );
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
if ( ! $item_id ) {
return false ;
}
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
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' );
}
2014-07-03 11:38:55 +00:00
2014-07-19 03:15:41 +00:00
wc_add_order_item_meta ( $item_id , '_line_total' , wc_format_decimal ( $fee -> amount ) );
2014-07-03 11:38:55 +00:00
wc_add_order_item_meta ( $item_id , '_line_tax' , wc_format_decimal ( $fee -> tax ) );
2014-07-20 04:28:16 +00:00
// Save tax data - Since 2.2
$tax_data = array_map ( 'wc_format_decimal' , $fee -> tax_data );
wc_add_order_item_meta ( $item_id , '_line_tax_data' , array ( 'total' => $tax_data ) );
2014-07-03 11:38:55 +00:00
do_action ( 'woocommerce_order_add_fee' , $this -> id , $item_id , $fee );
return $item_id ;
}
2014-07-28 03:28:25 +00:00
/**
* Update fee for order
*
* Note this does not update order totals
*
* @ since 2.2
* @ param int $item_id
* @ param array $args
* @ return bool
*/
public function update_fee ( $item_id , $args ) {
if ( ! $item_id ) {
return false ;
}
// name
if ( isset ( $args [ 'name' ] ) ) {
wc_update_order_item ( $item_id , array ( 'order_item_name' => $args [ 'name' ] ) );
}
// tax class
if ( isset ( $args [ 'tax_class' ] ) ) {
wc_update_order_item_meta ( $item_id , '_tax_class' , $args [ 'tax_class' ] );
}
// total
if ( isset ( $args [ 'line_total' ] ) ) {
wc_update_order_item_meta ( $item_id , '_line_total' , wc_format_decimal ( $args [ 'line_total' ] ) );
}
// total tax
if ( isset ( $args [ 'line_tax' ] ) ) {
wc_update_order_item_meta ( $item_id , '_line_tax' , wc_format_decimal ( $args [ 'line_tax' ] ) );
}
do_action ( 'woocommerce_order_update_fee' , $this -> id , $item_id , $args );
return true ;
}
2014-07-03 11:38:55 +00:00
/**
* Set an order total
2014-08-31 05:49:58 +00:00
*
2014-07-03 11:38:55 +00:00
* @ param float $amount
* @ param string $total_type
2014-11-21 21:09:46 +00:00
*
* @ return bool
2014-07-03 11:38:55 +00:00
*/
public function set_total ( $amount , $total_type = 'total' ) {
2014-08-31 05:49:58 +00:00
2014-11-25 13:05:03 +00:00
if ( ! in_array ( $total_type , array ( 'shipping' , 'tax' , 'shipping_tax' , 'total' , 'cart_discount' , 'cart_discount_tax' ) ) ) {
2014-07-03 11:38:55 +00:00
return false ;
}
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
switch ( $total_type ) {
case 'total' :
$key = '_order_total' ;
2015-01-23 11:50:32 +00:00
$amount = wc_format_decimal ( $amount , wc_get_price_decimals () );
2014-07-03 11:38:55 +00:00
break ;
case 'cart_discount' :
2014-11-25 13:05:03 +00:00
case 'cart_discount_tax' :
2014-07-03 11:38:55 +00:00
$key = '_' . $total_type ;
$amount = wc_format_decimal ( $amount );
break ;
default :
$key = '_order_' . $total_type ;
$amount = wc_format_decimal ( $amount );
break ;
}
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
update_post_meta ( $this -> id , $key , $amount );
2014-11-21 21:09:46 +00:00
return true ;
2014-07-03 11:38:55 +00:00
}
/**
* 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 .
2014-07-28 03:23:59 +00:00
*
2014-07-03 11:38:55 +00:00
* @ return bool success or fail
*/
public function calculate_taxes () {
2014-11-18 14:56:13 +00:00
$tax_total = 0 ;
$taxes = array ();
$tax_based_on = get_option ( 'woocommerce_tax_based_on' );
2014-07-28 03:23:59 +00:00
2015-03-27 10:42:24 +00:00
if ( 'billing' === $tax_based_on ) {
2014-11-18 14:56:13 +00:00
$country = $this -> billing_country ;
$state = $this -> billing_state ;
$postcode = $this -> billing_postcode ;
$city = $this -> billing_city ;
2015-03-27 10:42:24 +00:00
} elseif ( 'shipping' === $tax_based_on ) {
2014-11-18 14:56:13 +00:00
$country = $this -> shipping_country ;
$state = $this -> shipping_state ;
$postcode = $this -> shipping_postcode ;
$city = $this -> shipping_city ;
2015-03-27 10:42:24 +00:00
}
2014-08-31 05:49:58 +00:00
2015-03-27 10:42:24 +00:00
// Default to base
if ( 'base' === $tax_based_on || empty ( $country ) ) {
$default = wc_get_base_location ();
$country = $default [ 'country' ];
$state = $default [ 'state' ];
$postcode = '' ;
$city = '' ;
2014-07-03 11:38:55 +00:00
}
// Get items
foreach ( $this -> get_items ( array ( 'line_item' , 'fee' ) ) as $item_id => $item ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$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 ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$tax_rates = WC_Tax :: find_rates ( array (
'country' => $country ,
'state' => $state ,
'postcode' => $postcode ,
'city' => $city ,
'tax_class' => $tax_class
) );
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$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 ) );
2014-07-19 03:15:41 +00:00
wc_update_order_item_meta ( $item_id , '_line_tax' , wc_format_decimal ( $line_tax ) );
2015-03-31 12:21:10 +00:00
wc_update_order_item_meta ( $item_id , '_line_tax_data' , array ( 'total' => $line_taxes , 'subtotal' => $line_subtotal_taxes ) );
2014-07-03 11:38:55 +00:00
// 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' => ''
) );
2015-03-27 15:15:40 +00:00
if ( ! empty ( $tax_rates ) ) {
2014-07-03 11:38:55 +00:00
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 ;
}
2014-07-28 03:29:40 +00:00
/**
* Calculate shipping total
*
* @ since 2.2
* @ return float
*/
public function calculate_shipping () {
$shipping_total = 0 ;
foreach ( $this -> get_shipping_methods () as $shipping ) {
$shipping_total += $shipping [ 'cost' ];
}
$this -> set_total ( $shipping_total , 'shipping' );
return $this -> get_total_shipping ();
}
2014-07-24 14:34:14 +00:00
/**
* 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 ) {
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
$line_tax_data = maybe_unserialize ( $item [ 'line_tax_data' ] );
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
if ( isset ( $line_tax_data [ 'total' ] ) ) {
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
foreach ( $line_tax_data [ 'total' ] as $tax_rate_id => $tax ) {
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
if ( ! isset ( $order_taxes [ $tax_rate_id ] ) ) {
$order_taxes [ $tax_rate_id ] = 0 ;
}
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
$order_taxes [ $tax_rate_id ] += $tax ;
}
}
}
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
foreach ( $this -> get_items ( array ( 'shipping' ) ) as $item_id => $item ) {
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
$line_tax_data = maybe_unserialize ( $item [ 'taxes' ] );
2014-08-31 05:49:58 +00:00
2014-11-14 12:52:40 +00:00
if ( isset ( $line_tax_data ) ) {
foreach ( $line_tax_data as $tax_rate_id => $tax ) {
2014-07-24 14:34:14 +00:00
if ( ! isset ( $order_shipping_taxes [ $tax_rate_id ] ) ) {
$order_shipping_taxes [ $tax_rate_id ] = 0 ;
}
2014-08-31 05:49:58 +00:00
2014-07-24 14:34:14 +00:00
$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 ;
}
2014-07-03 11:38:55 +00:00
/**
* Calculate totals by looking at the contents of the order . Stores the totals and returns the orders final total .
2014-07-28 03:23:59 +00:00
*
* @ since 2.2
2014-07-24 14:34:14 +00:00
* @ param $and_taxes bool Calc taxes if true
2014-07-28 03:23:59 +00:00
* @ return float calculated grand total
2014-07-03 11:38:55 +00:00
*/
2014-07-24 14:34:14 +00:00
public function calculate_totals ( $and_taxes = true ) {
2014-11-25 13:05:03 +00:00
$cart_subtotal = 0 ;
$cart_total = 0 ;
$fee_total = 0 ;
$cart_subtotal_tax = 0 ;
$cart_total_tax = 0 ;
2014-07-03 11:38:55 +00:00
2015-06-23 12:29:38 +00:00
if ( $and_taxes && wc_tax_enabled () ) {
2014-07-24 14:34:14 +00:00
$this -> calculate_taxes ();
}
2014-07-03 11:38:55 +00:00
2014-07-28 03:29:40 +00:00
// line items
2014-07-03 11:38:55 +00:00
foreach ( $this -> get_items () as $item ) {
2014-11-25 13:05:03 +00:00
$cart_subtotal += wc_format_decimal ( isset ( $item [ 'line_subtotal' ] ) ? $item [ 'line_subtotal' ] : 0 );
$cart_total += wc_format_decimal ( isset ( $item [ 'line_total' ] ) ? $item [ 'line_total' ] : 0 );
$cart_subtotal_tax += wc_format_decimal ( isset ( $item [ 'line_subtotal_tax' ] ) ? $item [ 'line_subtotal_tax' ] : 0 );
2015-04-18 12:44:39 +00:00
$cart_total_tax += wc_format_decimal ( isset ( $item [ 'line_tax' ] ) ? $item [ 'line_tax' ] : 0 );
2014-07-03 11:38:55 +00:00
}
2014-07-28 03:29:40 +00:00
$this -> calculate_shipping ();
2014-07-03 11:38:55 +00:00
foreach ( $this -> get_fees () as $item ) {
$fee_total += $item [ 'line_total' ];
}
2015-02-23 17:39:54 +00:00
$this -> set_total ( $cart_subtotal - $cart_total , 'cart_discount' );
2014-11-25 13:05:03 +00:00
$this -> set_total ( $cart_subtotal_tax - $cart_total_tax , 'cart_discount_tax' );
2014-07-28 03:29:40 +00:00
2015-01-23 11:50:32 +00:00
$grand_total = round ( $cart_total + $fee_total + $this -> get_total_shipping () + $this -> get_cart_tax () + $this -> get_shipping_tax (), wc_get_price_decimals () );
2014-07-03 11:38:55 +00:00
$this -> set_total ( $grand_total , 'total' );
return $grand_total ;
}
2014-06-13 13:35:53 +00:00
/**
* Gets an order from the database .
*
* @ param int $id ( default : 0 )
* @ return bool
*/
public function get_order ( $id = 0 ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( ! $id ) {
return false ;
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( $result = get_post ( $id ) ) {
$this -> populate ( $result );
return true ;
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return false ;
}
/**
* Populates an order from the loaded post data .
*
* @ param mixed $result
*/
public function populate ( $result ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
// Standard post data
$this -> id = $result -> ID ;
$this -> order_date = $result -> post_date ;
$this -> modified_date = $result -> post_modified ;
$this -> customer_message = $result -> post_excerpt ;
$this -> customer_note = $result -> post_excerpt ;
$this -> post_status = $result -> post_status ;
2015-03-16 12:17:09 +00:00
// Billing email can default to user if set
2015-01-19 14:50:03 +00:00
if ( empty ( $this -> billing_email ) && ! empty ( $this -> customer_user ) && ( $user = get_user_by ( 'id' , $this -> customer_user ) ) ) {
2014-06-13 13:35:53 +00:00
$this -> billing_email = $user -> user_email ;
}
2015-03-16 12:17:09 +00:00
// Orders store the state of prices including tax when created
2015-03-23 13:35:36 +00:00
$this -> prices_include_tax = metadata_exists ( 'post' , $this -> id , '_prices_include_tax' ) ? get_post_meta ( $this -> id , '_prices_include_tax' , true ) === 'yes' : $this -> prices_include_tax ;
2014-06-13 13:35:53 +00:00
}
/**
* __isset function .
*
* @ param mixed $key
* @ return bool
*/
public function __isset ( $key ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( ! $this -> id ) {
return false ;
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return metadata_exists ( 'post' , $this -> id , '_' . $key );
}
/**
* __get function .
*
* @ param mixed $key
* @ return mixed
*/
public function __get ( $key ) {
// Get values or default if not set
if ( 'completed_date' === $key ) {
$value = ( $value = get_post_meta ( $this -> id , '_completed_date' , true ) ) ? $value : $this -> modified_date ;
} elseif ( 'user_id' === $key ) {
$value = ( $value = get_post_meta ( $this -> id , '_customer_user' , true ) ) ? absint ( $value ) : '' ;
} elseif ( 'status' === $key ) {
$value = $this -> get_status ();
} else {
$value = get_post_meta ( $this -> id , '_' . $key , true );
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return $value ;
}
/**
2015-01-26 13:07:29 +00:00
* Return the order statuses without wc - internal prefix .
*
* Queries get_post_status () directly to avoid having out of date statuses , if updated elsewhere .
2014-08-31 05:49:58 +00:00
*
2014-06-13 13:35:53 +00:00
* @ return string
*/
public function get_status () {
2015-01-26 13:07:29 +00:00
$this -> post_status = get_post_status ( $this -> id );
2014-06-13 13:35:53 +00:00
return apply_filters ( 'woocommerce_order_get_status' , 'wc-' === substr ( $this -> post_status , 0 , 3 ) ? substr ( $this -> post_status , 3 ) : $this -> post_status , $this );
}
/**
* Checks the order status against a passed in status .
*
* @ return bool
*/
public function has_status ( $status ) {
return apply_filters ( 'woocommerce_order_has_status' , ( is_array ( $status ) && in_array ( $this -> get_status (), $status ) ) || $this -> get_status () === $status ? true : false , $this , $status );
}
/**
* Gets the user ID associated with the order . Guests are 0.
2014-08-31 05:49:58 +00:00
*
2014-06-13 13:35:53 +00:00
* @ since 2.2
2015-01-26 16:41:19 +00:00
* @ return int
2014-06-13 13:35:53 +00:00
*/
public function get_user_id () {
2015-01-26 16:41:19 +00:00
return $this -> customer_user ? intval ( $this -> customer_user ) : 0 ;
2014-06-13 13:35:53 +00:00
}
/**
* Get the user associated with the order . False for guests .
2014-08-31 05:49:58 +00:00
*
2014-06-13 13:35:53 +00:00
* @ since 2.2
* @ return WP_User | false
*/
public function get_user () {
2014-07-28 03:30:21 +00:00
return $this -> get_user_id () ? get_user_by ( 'id' , $this -> get_user_id () ) : false ;
2014-06-13 13:35:53 +00:00
}
2014-07-07 10:43:06 +00:00
/**
* Get transaction id for the order
2014-08-31 05:49:58 +00:00
*
2014-07-19 03:15:41 +00:00
* @ return string
2014-07-07 10:43:06 +00:00
*/
public function get_transaction_id () {
return get_post_meta ( $this -> id , '_transaction_id' , true );
}
2014-06-13 13:35:53 +00:00
/**
* Check if an order key is valid .
*
* @ param mixed $key
* @ return bool
*/
public function key_is_valid ( $key ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( $key == $this -> order_key ) {
return true ;
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return false ;
}
/**
* get_order_number function .
*
* Gets the order number for display ( by default , order ID )
*
* @ return string
*/
public function get_order_number () {
2014-10-24 13:53:40 +00:00
return apply_filters ( 'woocommerce_order_number' , $this -> id , $this );
2014-06-13 13:35:53 +00:00
}
/**
* Get a formatted billing address for the order .
*
* @ return string
*/
public function get_formatted_billing_address () {
if ( ! $this -> formatted_billing_address ) {
// Formatted Addresses
$address = apply_filters ( 'woocommerce_order_formatted_billing_address' , array (
2014-08-31 05:49:58 +00:00
'first_name' => $this -> billing_first_name ,
'last_name' => $this -> billing_last_name ,
'company' => $this -> billing_company ,
'address_1' => $this -> billing_address_1 ,
'address_2' => $this -> billing_address_2 ,
'city' => $this -> billing_city ,
'state' => $this -> billing_state ,
'postcode' => $this -> billing_postcode ,
'country' => $this -> billing_country
2014-06-13 13:35:53 +00:00
), $this );
$this -> formatted_billing_address = WC () -> countries -> get_formatted_address ( $address );
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return $this -> formatted_billing_address ;
}
/**
* Get a formatted shipping address for the order .
*
* @ return string
*/
public function get_formatted_shipping_address () {
if ( ! $this -> formatted_shipping_address ) {
2014-08-31 05:49:58 +00:00
2015-01-12 12:34:53 +00:00
if ( $this -> shipping_address_1 || $this -> shipping_address_2 ) {
2014-06-13 13:35:53 +00:00
// Formatted Addresses
$address = apply_filters ( 'woocommerce_order_formatted_shipping_address' , array (
2014-08-31 05:49:58 +00:00
'first_name' => $this -> shipping_first_name ,
'last_name' => $this -> shipping_last_name ,
'company' => $this -> shipping_company ,
'address_1' => $this -> shipping_address_1 ,
'address_2' => $this -> shipping_address_2 ,
'city' => $this -> shipping_city ,
'state' => $this -> shipping_state ,
'postcode' => $this -> shipping_postcode ,
'country' => $this -> shipping_country
2014-06-13 13:35:53 +00:00
), $this );
$this -> formatted_shipping_address = WC () -> countries -> get_formatted_address ( $address );
}
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return $this -> formatted_shipping_address ;
}
2015-01-20 13:31:02 +00:00
/**
* Get a formatted shipping address for the order .
*
* @ return string
*/
public function get_shipping_address_map_url () {
$address = apply_filters ( 'woocommerce_shipping_address_map_url_parts' , array (
'address_1' => $this -> shipping_address_1 ,
'address_2' => $this -> shipping_address_2 ,
'city' => $this -> shipping_city ,
'state' => $this -> shipping_state ,
'postcode' => $this -> shipping_postcode ,
'country' => $this -> shipping_country
), $this );
return apply_filters ( 'woocommerce_shipping_address_map_url' , 'http://maps.google.com/maps?&q=' . urlencode ( implode ( ', ' , $address ) ) . '&z=16' , $this );
}
2015-01-20 12:39:21 +00:00
/**
* Get the billing address in an array .
* @ deprecated 2.3
* @ return string
*/
public function get_billing_address () {
_deprecated_function ( 'get_billing_address' , '2.3' , 'get_formatted_billing_address' );
return $this -> get_formatted_billing_address ();
}
2014-06-13 13:35:53 +00:00
/**
* Get the shipping address in an array .
2015-01-20 12:39:21 +00:00
* @ deprecated 2.3
* @ return string
2014-06-13 13:35:53 +00:00
*/
public function get_shipping_address () {
2015-01-20 12:39:21 +00:00
_deprecated_function ( 'get_shipping_address' , '2.3' , 'get_formatted_shipping_address' );
return $this -> get_formatted_shipping_address ();
2014-06-13 13:35:53 +00:00
}
2015-07-08 21:00:19 +00:00
/**
* Get a formatted billing full name .
*
* @ since 2.4 . 0
*
* @ return string
*/
public function get_formatted_billing_full_name () {
return sprintf ( _x ( '%1$s %2$s' , 'full name' , 'woocommerce' ), $this -> billing_first_name , $this -> billing_last_name );
}
/**
* Get a formatted shipping full name .
*
* @ since 2.4 . 0
*
* @ return string
*/
public function get_formatted_shipping_full_name () {
return sprintf ( _x ( '%1$s %2$s' , 'full name' , 'woocommerce' ), $this -> shipping_first_name , $this -> shipping_last_name );
}
2014-06-13 13:35:53 +00:00
/**
* Return an array of items / products within this order .
*
* @ param string | array $type Types of line items to get ( array or string )
* @ return array
*/
public function get_items ( $type = '' ) {
global $wpdb ;
if ( empty ( $type ) ) {
$type = array ( 'line_item' );
}
if ( ! is_array ( $type ) ) {
$type = array ( $type );
}
$type = array_map ( 'esc_attr' , $type );
$line_items = $wpdb -> get_results ( $wpdb -> prepare ( "
2014-08-31 05:49:58 +00:00
SELECT order_item_id , order_item_name , order_item_type
FROM { $wpdb -> prefix } woocommerce_order_items
WHERE order_id = % d
AND order_item_type IN ( '" . implode( "' , '", $type ) . "' )
ORDER BY order_item_id
2014-06-13 13:35:53 +00:00
" , $this->id ) );
$items = array ();
2015-08-03 12:21:44 +00:00
// Loop items
foreach ( $line_items as $item ) {
$items [ $item -> order_item_id ][ 'name' ] = $item -> order_item_name ;
$items [ $item -> order_item_id ][ 'type' ] = $item -> order_item_type ;
$items [ $item -> order_item_id ][ 'item_meta' ] = $this -> get_item_meta ( $item -> order_item_id );
$items [ $item -> order_item_id ][ 'item_meta_array' ] = $this -> get_item_meta_array ( $item -> order_item_id );
$items [ $item -> order_item_id ] = $this -> expand_item_meta ( $items [ $item -> order_item_id ] );
}
return apply_filters ( 'woocommerce_order_get_items' , $items , $this );
}
/**
* Expand item meta into the $item array .
* @ since 2.4 . 0
* @ param array $item before expansion
* @ return array
*/
public function expand_item_meta ( $item ) {
2014-06-13 13:35:53 +00:00
// Reserved meta keys
$reserved_item_meta_keys = array (
'name' ,
'type' ,
'item_meta' ,
2015-05-01 11:42:29 +00:00
'item_meta_array' ,
2014-06-13 13:35:53 +00:00
'qty' ,
'tax_class' ,
'product_id' ,
'variation_id' ,
'line_subtotal' ,
'line_total' ,
'line_tax' ,
'line_subtotal_tax'
);
2015-08-03 12:21:44 +00:00
// Expand item meta if set
if ( ! empty ( $item [ 'item_meta' ] ) ) {
foreach ( $item [ 'item_meta' ] as $name => $value ) {
if ( in_array ( $name , $reserved_item_meta_keys ) ) {
continue ;
}
if ( '_' === substr ( $name , 0 , 1 ) ) {
$item [ substr ( $name , 1 ) ] = $value [ 0 ];
} elseif ( ! in_array ( $name , $reserved_item_meta_keys ) ) {
$item [ $name ] = make_clickable ( $value [ 0 ] );
2014-06-13 13:35:53 +00:00
}
}
}
2015-08-03 12:21:44 +00:00
return $item ;
2014-06-13 13:35:53 +00:00
}
/**
2015-07-29 12:13:41 +00:00
* Gets the count of order items of a certain type .
2014-11-21 21:12:03 +00:00
*
2015-07-29 12:13:41 +00:00
* @ param string $item_type
2014-06-13 13:35:53 +00:00
* @ return string
*/
2015-07-29 12:13:41 +00:00
public function get_item_count ( $item_type = '' ) {
if ( empty ( $item_type ) ) {
$item_type = array ( 'line_item' );
2014-06-13 13:35:53 +00:00
}
2015-07-29 12:13:41 +00:00
if ( ! is_array ( $item_type ) ) {
$item_type = array ( $item_type );
2014-06-13 13:35:53 +00:00
}
2015-07-29 12:13:41 +00:00
$items = $this -> get_items ( $item_type );
2014-06-13 13:35:53 +00:00
$count = 0 ;
foreach ( $items as $item ) {
2015-07-29 12:13:41 +00:00
$count += empty ( $item [ 'qty' ] ) ? 1 : $item [ 'qty' ];
2014-06-13 13:35:53 +00:00
}
2015-07-29 12:13:41 +00:00
return apply_filters ( 'woocommerce_get_item_count' , $count , $item_type , $this );
2014-06-13 13:35:53 +00:00
}
/**
* Return an array of fees within this order .
*
* @ return array
*/
public function get_fees () {
return $this -> get_items ( 'fee' );
}
/**
* Return an array of taxes within this order .
*
* @ return array
*/
public function get_taxes () {
return $this -> get_items ( 'tax' );
}
/**
* Return an array of shipping costs within this order .
*
* @ return array
*/
public function get_shipping_methods () {
return $this -> get_items ( 'shipping' );
}
/**
* Check whether this order has a specific shipping method or not
2014-08-31 05:49:58 +00:00
*
2014-06-13 13:35:53 +00:00
* @ param string $method_id
2014-11-21 21:12:37 +00:00
*
* @ return bool
2014-06-13 13:35:53 +00:00
*/
public function has_shipping_method ( $method_id ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$shipping_methods = $this -> get_shipping_methods ();
$has_method = false ;
2015-03-27 15:15:40 +00:00
if ( empty ( $shipping_methods ) ) {
2014-06-13 13:35:53 +00:00
return false ;
}
foreach ( $shipping_methods as $shipping_method ) {
if ( $shipping_method [ 'method_id' ] == $method_id ) {
$has_method = true ;
}
}
return $has_method ;
}
/**
* Get taxes , merged by code , formatted ready for output .
*
* @ return array
*/
public function get_tax_totals () {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$taxes = $this -> get_items ( 'tax' );
$tax_totals = array ();
foreach ( $taxes as $key => $tax ) {
$code = $tax [ 'name' ];
if ( ! isset ( $tax_totals [ $code ] ) ) {
$tax_totals [ $code ] = new stdClass ();
$tax_totals [ $code ] -> amount = 0 ;
}
2014-07-28 03:31:02 +00:00
$tax_totals [ $code ] -> id = $key ;
$tax_totals [ $code ] -> rate_id = $tax [ 'rate_id' ];
2014-06-13 13:35:53 +00:00
$tax_totals [ $code ] -> is_compound = $tax [ 'compound' ];
$tax_totals [ $code ] -> label = isset ( $tax [ 'label' ] ) ? $tax [ 'label' ] : $tax [ 'name' ];
$tax_totals [ $code ] -> amount += $tax [ 'tax_amount' ] + $tax [ 'shipping_tax_amount' ];
$tax_totals [ $code ] -> formatted_amount = wc_price ( wc_round_tax_total ( $tax_totals [ $code ] -> amount ), array ( 'currency' => $this -> get_order_currency ()) );
}
return apply_filters ( 'woocommerce_order_tax_totals' , $tax_totals , $this );
}
/**
* has_meta function for order items .
2014-08-31 05:49:58 +00:00
*
2014-06-13 13:35:53 +00:00
* @ param string $order_item_id
* @ return array of meta data
*/
public function has_meta ( $order_item_id ) {
global $wpdb ;
return $wpdb -> get_results ( $wpdb -> prepare ( " SELECT meta_key, meta_value, meta_id, order_item_id
FROM { $wpdb -> prefix } woocommerce_order_itemmeta WHERE order_item_id = % d
ORDER BY meta_id " , absint( $order_item_id ) ), ARRAY_A );
}
2015-05-01 11:42:29 +00:00
/**
* Get all item meta data in array format in the order it was saved . Does not group meta by key like get_item_meta ()
*
* @ param mixed $order_item_id
* @ return array of objects
*/
public function get_item_meta_array ( $order_item_id ) {
global $wpdb ;
$item_meta_array = array ();
$metadata = $wpdb -> get_results ( $wpdb -> prepare ( " SELECT meta_key, meta_value, meta_id FROM { $wpdb -> prefix } woocommerce_order_itemmeta WHERE order_item_id = %d ORDER BY meta_id " , absint ( $order_item_id ) ) );
foreach ( $metadata as $metadata_row ) {
$item_meta_array [ $metadata_row -> meta_id ] = ( object ) array ( 'key' => $metadata_row -> meta_key , 'value' => $metadata_row -> meta_value );
}
return $item_meta_array ;
}
/**
* Display meta data belonging to an item
* @ param array $item
*/
public function display_item_meta ( $item ) {
$product = $this -> get_product_from_item ( $item );
$item_meta = new WC_Order_Item_Meta ( $item , $product );
$item_meta -> display ();
}
2014-06-13 13:35:53 +00:00
/**
* Get order item meta .
*
* @ param mixed $order_item_id
* @ param string $key ( default : '' )
* @ param bool $single ( default : false )
* @ return array | string
*/
public function get_item_meta ( $order_item_id , $key = '' , $single = false ) {
return get_metadata ( 'order_item' , $order_item_id , $key , $single );
}
/** Total Getters *******************************************************/
/**
2014-11-25 13:05:03 +00:00
* Gets the total discount amount
* @ param $ex_tax Show discount excl any tax .
* @ return float
*/
public function get_total_discount ( $ex_tax = true ) {
2015-03-16 12:17:09 +00:00
if ( ! $this -> order_version || version_compare ( $this -> order_version , '2.3.7' , '<' ) ) {
// Backwards compatible total calculation - totals were not stored consistently in old versions.
if ( $ex_tax ) {
if ( $this -> prices_include_tax ) {
$total_discount = ( double ) $this -> cart_discount - ( double ) $this -> cart_discount_tax ;
} else {
$total_discount = ( double ) $this -> cart_discount ;
}
} else {
if ( $this -> prices_include_tax ) {
$total_discount = ( double ) $this -> cart_discount ;
} else {
$total_discount = ( double ) $this -> cart_discount + ( double ) $this -> cart_discount_tax ;
}
}
// New logic - totals are always stored exclusive of tax, tax total is stored in cart_discount_tax
2015-02-23 17:39:54 +00:00
} else {
2015-03-16 12:17:09 +00:00
if ( $ex_tax ) {
$total_discount = ( double ) $this -> cart_discount ;
} else {
$total_discount = ( double ) $this -> cart_discount + ( double ) $this -> cart_discount_tax ;
}
2014-11-25 13:05:03 +00:00
}
2015-03-16 12:17:09 +00:00
return apply_filters ( 'woocommerce_order_amount_total_discount' , $total_discount , $this );
2014-11-25 13:05:03 +00:00
}
/**
* Gets the discount amount
* @ deprecated in favour of get_total_discount () since we now only have one discount type .
2014-06-13 13:35:53 +00:00
* @ return float
*/
public function get_cart_discount () {
2014-11-25 13:05:03 +00:00
_deprecated_function ( 'get_cart_discount' , '2.3' , 'get_total_discount' );
return apply_filters ( 'woocommerce_order_amount_cart_discount' , $this -> get_total_discount (), $this );
2014-06-13 13:35:53 +00:00
}
/**
2014-11-25 13:05:03 +00:00
* Get cart discount ( formatted ) .
2014-06-13 13:35:53 +00:00
*
2014-11-25 11:05:14 +00:00
* @ deprecated order ( after tax ) discounts removed in 2.3 . 0
2014-11-25 13:05:03 +00:00
* @ return string
2014-06-13 13:35:53 +00:00
*/
2014-11-25 13:05:03 +00:00
public function get_order_discount_to_display () {
_deprecated_function ( 'get_order_discount_to_display' , '2.3' );
2014-06-13 13:35:53 +00:00
}
/**
2014-11-25 13:05:03 +00:00
* Gets the total ( order ) discount amount - these are applied after tax .
2014-06-13 13:35:53 +00:00
*
2014-11-25 13:05:03 +00:00
* @ deprecated order ( after tax ) discounts removed in 2.3 . 0
2014-06-13 13:35:53 +00:00
* @ return float
*/
2014-11-25 13:05:03 +00:00
public function get_order_discount () {
_deprecated_function ( 'get_order_discount' , '2.3' );
return apply_filters ( 'woocommerce_order_amount_order_discount' , ( double ) $this -> order_discount , $this );
2014-06-13 13:35:53 +00:00
}
/**
2014-09-29 15:11:34 +00:00
* Gets cart tax amount .
2014-06-13 13:35:53 +00:00
*
* @ return float
*/
public function get_cart_tax () {
return apply_filters ( 'woocommerce_order_amount_cart_tax' , ( double ) $this -> order_tax , $this );
}
/**
* Gets shipping tax amount .
*
* @ return float
*/
public function get_shipping_tax () {
return apply_filters ( 'woocommerce_order_amount_shipping_tax' , ( double ) $this -> order_shipping_tax , $this );
}
/**
* Gets shipping and product tax .
*
* @ return float
*/
public function get_total_tax () {
return apply_filters ( 'woocommerce_order_amount_total_tax' , wc_round_tax_total ( $this -> get_cart_tax () + $this -> get_shipping_tax () ), $this );
}
/**
* Gets shipping total .
*
* @ return float
*/
public function get_total_shipping () {
return apply_filters ( 'woocommerce_order_amount_total_shipping' , ( double ) $this -> order_shipping , $this );
}
/**
* Gets order total .
*
* @ return float
*/
public function get_total () {
return apply_filters ( 'woocommerce_order_amount_total' , ( double ) $this -> order_total , $this );
}
2014-07-28 03:31:26 +00:00
/**
* Gets order subtotal .
*
* @ return mixed | void
*/
public function get_subtotal () {
$subtotal = 0 ;
foreach ( $this -> get_items () as $item ) {
$subtotal += ( isset ( $item [ 'line_subtotal' ] ) ) ? $item [ 'line_subtotal' ] : 0 ;
}
return apply_filters ( 'woocommerce_order_amount_subtotal' , ( double ) $subtotal , $this );
}
2014-06-13 13:35:53 +00:00
/**
* Get item subtotal - this is the cost before discount .
*
* @ param mixed $item
* @ param bool $inc_tax ( default : false )
* @ param bool $round ( default : true )
* @ return float
*/
public function get_item_subtotal ( $item , $inc_tax = false , $round = true ) {
if ( $inc_tax ) {
2014-07-03 11:38:55 +00:00
$price = ( $item [ 'line_subtotal' ] + $item [ 'line_subtotal_tax' ] ) / max ( 1 , $item [ 'qty' ] );
2014-06-13 13:35:53 +00:00
} else {
2015-03-06 22:46:31 +00:00
$price = ( $item [ 'line_subtotal' ] / max ( 1 , $item [ 'qty' ] ) );
2014-06-13 13:35:53 +00:00
}
2015-01-05 11:42:10 +00:00
$price = $round ? number_format ( ( float ) $price , 2 , '.' , '' ) : $price ;
2014-06-13 13:35:53 +00:00
2015-03-13 10:03:08 +00:00
return apply_filters ( 'woocommerce_order_amount_item_subtotal' , $price , $this , $item , $inc_tax , $round );
2014-06-13 13:35:53 +00:00
}
/**
* Get line subtotal - this is the cost before discount .
*
* @ param mixed $item
* @ param bool $inc_tax ( default : false )
* @ param bool $round ( default : true )
* @ return float
*/
public function get_line_subtotal ( $item , $inc_tax = false , $round = true ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( $inc_tax ) {
$price = $item [ 'line_subtotal' ] + $item [ 'line_subtotal_tax' ];
} else {
$price = $item [ 'line_subtotal' ];
}
$price = $round ? round ( $price , 2 ) : $price ;
2015-03-13 10:03:08 +00:00
return apply_filters ( 'woocommerce_order_amount_line_subtotal' , $price , $this , $item , $inc_tax , $round );
2014-06-13 13:35:53 +00:00
}
/**
* Calculate item cost - useful for gateways .
*
* @ param mixed $item
* @ param bool $inc_tax ( default : false )
* @ param bool $round ( default : true )
* @ return float
*/
public function get_item_total ( $item , $inc_tax = false , $round = true ) {
2014-08-31 05:49:58 +00:00
2014-09-10 01:23:46 +00:00
$qty = ( ! empty ( $item [ 'qty' ] ) ) ? $item [ 'qty' ] : 1 ;
2014-06-13 13:35:53 +00:00
if ( $inc_tax ) {
2014-09-10 01:23:46 +00:00
$price = ( $item [ 'line_total' ] + $item [ 'line_tax' ] ) / max ( 1 , $qty );
2014-06-13 13:35:53 +00:00
} else {
2015-03-06 22:46:31 +00:00
$price = $item [ 'line_total' ] / max ( 1 , $qty );
2014-06-13 13:35:53 +00:00
}
$price = $round ? round ( $price , 2 ) : $price ;
2015-03-13 10:03:08 +00:00
return apply_filters ( 'woocommerce_order_amount_item_total' , $price , $this , $item , $inc_tax , $round );
2014-06-13 13:35:53 +00:00
}
/**
* Calculate line total - useful for gateways .
*
* @ param mixed $item
* @ param bool $inc_tax ( default : false )
2015-03-09 17:06:31 +00:00
* @ param bool $round ( default : true )
2014-06-13 13:35:53 +00:00
* @ return float
*/
2015-03-09 17:06:31 +00:00
public function get_line_total ( $item , $inc_tax = false , $round = true ) {
// Check if we need to add line tax to the line total
2015-03-09 17:10:49 +00:00
$line_total = $inc_tax ? $item [ 'line_total' ] + $item [ 'line_tax' ] : $item [ 'line_total' ];
2014-08-31 05:49:58 +00:00
2015-03-09 17:06:31 +00:00
// Check if we need to round
2015-03-09 17:10:49 +00:00
$line_total = $round ? round ( $line_total , 2 ) : $line_total ;
2014-08-31 05:49:58 +00:00
2015-03-13 10:03:08 +00:00
return apply_filters ( 'woocommerce_order_amount_line_total' , $line_total , $this , $item , $inc_tax , $round );
2014-06-13 13:35:53 +00:00
}
/**
* Calculate item tax - useful for gateways .
*
* @ param mixed $item
* @ param bool $round ( default : true )
* @ return float
*/
public function get_item_tax ( $item , $round = true ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
$price = $item [ 'line_tax' ] / max ( 1 , $item [ 'qty' ] );
2014-06-13 13:35:53 +00:00
$price = $round ? wc_round_tax_total ( $price ) : $price ;
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return apply_filters ( 'woocommerce_order_amount_item_tax' , $price , $item , $round , $this );
}
/**
* Calculate line tax - useful for gateways .
*
* @ param mixed $item
* @ return float
*/
public function get_line_tax ( $item ) {
return apply_filters ( 'woocommerce_order_amount_line_tax' , wc_round_tax_total ( $item [ 'line_tax' ] ), $item , $this );
}
/** End Total Getters *******************************************************/
/**
* Gets formatted shipping method title .
*
* @ return string
*/
public function get_shipping_method () {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$labels = array ();
// Backwards compat < 2.1 - get shipping title stored in meta
if ( $this -> shipping_method_title ) {
$labels [] = $this -> shipping_method_title ;
} else {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
// 2.1+ get line items for shipping
$shipping_methods = $this -> get_shipping_methods ();
foreach ( $shipping_methods as $shipping ) {
$labels [] = $shipping [ 'name' ];
}
}
return apply_filters ( 'woocommerce_order_shipping_method' , implode ( ', ' , $labels ), $this );
}
/**
* Gets line subtotal - formatted for display .
*
* @ param array $item
* @ param string $tax_display
* @ return string
*/
public function get_formatted_line_subtotal ( $item , $tax_display = '' ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( ! $tax_display ) {
$tax_display = $this -> tax_display_cart ;
}
if ( ! isset ( $item [ 'line_subtotal' ] ) || ! isset ( $item [ 'line_subtotal_tax' ] ) ) {
return '' ;
}
if ( 'excl' == $tax_display ) {
$ex_tax_label = $this -> prices_include_tax ? 1 : 0 ;
$subtotal = wc_price ( $this -> get_line_subtotal ( $item ), array ( 'ex_tax_label' => $ex_tax_label , 'currency' => $this -> get_order_currency () ) );
} else {
$subtotal = wc_price ( $this -> get_line_subtotal ( $item , true ), array ( 'currency' => $this -> get_order_currency ()) );
}
return apply_filters ( 'woocommerce_order_formatted_line_subtotal' , $subtotal , $item , $this );
}
/**
* Gets order currency
*
* @ return string
*/
public function get_order_currency () {
2014-10-06 12:39:49 +00:00
return apply_filters ( 'woocommerce_get_order_currency' , $this -> order_currency , $this );
2014-06-13 13:35:53 +00:00
}
/**
* Gets order total - formatted for display .
*
* @ return string
*/
public function get_formatted_order_total () {
2014-10-06 12:39:49 +00:00
$formatted_total = wc_price ( $this -> get_total (), array ( 'currency' => $this -> get_order_currency () ) );
2014-06-13 13:35:53 +00:00
return apply_filters ( 'woocommerce_get_formatted_order_total' , $formatted_total , $this );
}
/**
* Gets subtotal - subtotal is shown before discounts , but with localised taxes .
*
* @ param bool $compound ( default : false )
* @ param string $tax_display ( default : the tax_display_cart value )
* @ return string
*/
public function get_subtotal_to_display ( $compound = false , $tax_display = '' ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( ! $tax_display ) {
$tax_display = $this -> tax_display_cart ;
}
$subtotal = 0 ;
if ( ! $compound ) {
foreach ( $this -> get_items () as $item ) {
if ( ! isset ( $item [ 'line_subtotal' ] ) || ! isset ( $item [ 'line_subtotal_tax' ] ) ) {
return '' ;
}
$subtotal += $item [ 'line_subtotal' ];
if ( 'incl' == $tax_display ) {
$subtotal += $item [ 'line_subtotal_tax' ];
}
}
$subtotal = wc_price ( $subtotal , array ( 'currency' => $this -> get_order_currency ()) );
if ( $tax_display == 'excl' && $this -> prices_include_tax ) {
2015-05-27 15:17:33 +00:00
$subtotal .= ' <small class="tax_label">' . WC () -> countries -> ex_tax_or_vat () . '</small>' ;
2014-06-13 13:35:53 +00:00
}
} else {
if ( 'incl' == $tax_display ) {
return '' ;
}
foreach ( $this -> get_items () as $item ) {
$subtotal += $item [ 'line_subtotal' ];
}
// Add Shipping Costs
$subtotal += $this -> get_total_shipping ();
// Remove non-compound taxes
foreach ( $this -> get_taxes () as $tax ) {
if ( ! empty ( $tax [ 'compound' ] ) ) {
continue ;
}
$subtotal = $subtotal + $tax [ 'tax_amount' ] + $tax [ 'shipping_tax_amount' ];
}
// Remove discounts
2014-11-25 13:05:03 +00:00
$subtotal = $subtotal - $this -> get_total_discount ();
2014-06-13 13:35:53 +00:00
$subtotal = wc_price ( $subtotal , array ( 'currency' => $this -> get_order_currency ()) );
}
return apply_filters ( 'woocommerce_order_subtotal_to_display' , $subtotal , $compound , $this );
}
/**
* Gets shipping ( formatted ) .
*
* @ return string
*/
public function get_shipping_to_display ( $tax_display = '' ) {
if ( ! $tax_display ) {
$tax_display = $this -> tax_display_cart ;
}
2015-04-17 10:38:08 +00:00
if ( $this -> order_shipping != 0 ) {
2014-06-13 13:35:53 +00:00
$tax_text = '' ;
if ( $tax_display == 'excl' ) {
// Show shipping excluding tax
$shipping = wc_price ( $this -> order_shipping , array ( 'currency' => $this -> get_order_currency ()) );
2015-04-17 10:45:32 +00:00
if ( $this -> order_shipping_tax != 0 && $this -> prices_include_tax ) {
2014-06-13 13:35:53 +00:00
$tax_text = WC () -> countries -> ex_tax_or_vat () . ' ' ;
}
} else {
// Show shipping including tax
$shipping = wc_price ( $this -> order_shipping + $this -> order_shipping_tax , array ( 'currency' => $this -> get_order_currency ()) );
2015-04-17 10:45:32 +00:00
if ( $this -> order_shipping_tax != 0 && ! $this -> prices_include_tax ) {
2014-06-13 13:35:53 +00:00
$tax_text = WC () -> countries -> inc_tax_or_vat () . ' ' ;
}
}
$shipping .= sprintf ( __ ( ' <small>%svia %s</small>' , 'woocommerce' ), $tax_text , $this -> get_shipping_method () );
} elseif ( $this -> get_shipping_method () ) {
$shipping = $this -> get_shipping_method ();
} else {
$shipping = __ ( 'Free!' , 'woocommerce' );
}
return apply_filters ( 'woocommerce_order_shipping_to_display' , $shipping , $this );
}
/**
2014-11-25 13:05:03 +00:00
* Get the discount amount ( formatted ) .
* @ since 2.3 . 0
2015-02-03 12:57:08 +00:00
* @ return string
2014-06-13 13:35:53 +00:00
*/
2014-11-25 13:05:03 +00:00
public function get_discount_to_display ( $tax_display = '' ) {
if ( ! $tax_display ) {
$tax_display = $this -> tax_display_cart ;
}
2015-02-23 17:39:54 +00:00
return apply_filters ( 'woocommerce_order_discount_to_display' , wc_price ( $this -> get_total_discount ( $tax_display === 'excl' && $this -> display_totals_ex_tax ), array ( 'currency' => $this -> get_order_currency () ) ), $this );
2014-06-13 13:35:53 +00:00
}
/**
* Get cart discount ( formatted ) .
2014-11-25 13:05:03 +00:00
* @ deprecated
2015-02-03 12:57:08 +00:00
* @ return string
2014-06-13 13:35:53 +00:00
*/
2014-11-25 13:05:03 +00:00
public function get_cart_discount_to_display ( $tax_display = '' ) {
_deprecated_function ( 'get_cart_discount_to_display' , '2.3' , 'get_discount_to_display' );
2015-02-03 12:57:08 +00:00
return apply_filters ( 'woocommerce_order_cart_discount_to_display' , $this -> get_discount_to_display ( $tax_display ), $this );
2014-06-13 13:35:53 +00:00
}
/**
* Get a product ( either product or variation ) .
*
* @ param mixed $item
* @ return WC_Product
*/
public function get_product_from_item ( $item ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
if ( ! empty ( $item [ 'variation_id' ] ) && 'product_variation' === get_post_type ( $item [ 'variation_id' ] ) ) {
2014-08-19 10:09:29 +00:00
$_product = wc_get_product ( $item [ 'variation_id' ] );
2014-07-24 14:34:14 +00:00
} elseif ( ! empty ( $item [ 'product_id' ] ) ) {
2014-08-19 10:09:29 +00:00
$_product = wc_get_product ( $item [ 'product_id' ] );
2014-07-24 14:34:14 +00:00
} else {
$_product = false ;
2014-07-03 11:38:55 +00:00
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
return apply_filters ( 'woocommerce_get_product_from_item' , $_product , $item , $this );
}
/**
* Get totals for display on pages and in emails .
*
* @ return array
*/
public function get_order_item_totals ( $tax_display = '' ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( ! $tax_display ) {
$tax_display = $this -> tax_display_cart ;
}
$total_rows = array ();
2014-07-04 18:29:17 +00:00
if ( $subtotal = $this -> get_subtotal_to_display ( false , $tax_display ) ) {
2014-06-13 13:35:53 +00:00
$total_rows [ 'cart_subtotal' ] = array (
2015-03-10 16:57:43 +00:00
'label' => __ ( 'Subtotal:' , 'woocommerce' ),
2014-06-13 13:35:53 +00:00
'value' => $subtotal
);
}
2014-11-25 13:05:03 +00:00
if ( $this -> get_total_discount () > 0 ) {
$total_rows [ 'discount' ] = array (
'label' => __ ( 'Discount:' , 'woocommerce' ),
'value' => '-' . $this -> get_discount_to_display ()
2014-06-13 13:35:53 +00:00
);
}
if ( $this -> get_shipping_method () ) {
$total_rows [ 'shipping' ] = array (
'label' => __ ( 'Shipping:' , 'woocommerce' ),
'value' => $this -> get_shipping_to_display ()
);
}
if ( $fees = $this -> get_fees () )
2014-08-31 05:49:58 +00:00
2015-01-29 20:50:08 +00:00
foreach ( $fees as $id => $fee ) {
2014-08-31 05:49:58 +00:00
2014-07-03 11:38:55 +00:00
if ( apply_filters ( 'woocommerce_get_order_item_totals_excl_free_fees' , $fee [ 'line_total' ] + $fee [ 'line_tax' ] == 0 , $id ) ) {
2014-06-13 13:35:53 +00:00
continue ;
}
if ( 'excl' == $tax_display ) {
$total_rows [ 'fee_' . $id ] = array (
2015-07-28 10:32:53 +00:00
'label' => ( $fee [ 'name' ] ? $fee [ 'name' ] : __ ( 'Fee' , 'woocommerce' ) ) . ':' ,
2014-06-13 13:35:53 +00:00
'value' => wc_price ( $fee [ 'line_total' ], array ( 'currency' => $this -> get_order_currency ()) )
);
} else {
$total_rows [ 'fee_' . $id ] = array (
'label' => $fee [ 'name' ] . ':' ,
'value' => wc_price ( $fee [ 'line_total' ] + $fee [ 'line_tax' ], array ( 'currency' => $this -> get_order_currency ()) )
);
}
}
// Tax for tax exclusive prices
if ( 'excl' == $tax_display ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( get_option ( 'woocommerce_tax_total_display' ) == 'itemized' ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
foreach ( $this -> get_tax_totals () as $code => $tax ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$total_rows [ sanitize_title ( $code ) ] = array (
'label' => $tax -> label . ':' ,
'value' => $tax -> formatted_amount
);
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
} else {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$total_rows [ 'tax' ] = array (
'label' => WC () -> countries -> tax_or_vat () . ':' ,
2015-01-29 20:50:08 +00:00
'value' => wc_price ( $this -> get_total_tax (), array ( 'currency' => $this -> get_order_currency () ) )
2014-06-13 13:35:53 +00:00
);
}
}
2015-03-02 10:03:27 +00:00
if ( $this -> get_total () > 0 && $this -> payment_method_title ) {
2014-06-13 13:35:53 +00:00
$total_rows [ 'payment_method' ] = array (
'label' => __ ( 'Payment Method:' , 'woocommerce' ),
'value' => $this -> payment_method_title
);
}
2015-05-01 13:50:18 +00:00
$total_rows [ 'order_total' ] = array (
'label' => __ ( 'Total:' , 'woocommerce' ),
2015-07-16 09:15:45 +00:00
'value' => $this -> get_formatted_order_total ( $tax_display )
2015-05-01 13:50:18 +00:00
);
2014-06-13 13:35:53 +00:00
return apply_filters ( 'woocommerce_get_order_item_totals' , $total_rows , $this );
}
/**
* Output items for display in html emails .
*
* @ param bool $show_download_links ( default : false )
* @ param bool $show_sku ( default : false )
* @ param bool $show_purchase_note ( default : false )
* @ param bool $show_image ( default : false )
* @ param array $image_size ( default : array ( 32 , 32 )
* @ param bool plain text
* @ return string
*/
public function email_order_items_table ( $show_download_links = false , $show_sku = false , $show_purchase_note = false , $show_image = false , $image_size = array ( 32 , 32 ), $plain_text = false ) {
ob_start ();
$template = $plain_text ? 'emails/plain/email-order-items.php' : 'emails/email-order-items.php' ;
wc_get_template ( $template , array (
2014-08-31 05:49:58 +00:00
'order' => $this ,
'items' => $this -> get_items (),
'show_download_links' => $show_download_links ,
'show_sku' => $show_sku ,
'show_purchase_note' => $show_purchase_note ,
'show_image' => $show_image ,
'image_size' => $image_size
2014-06-13 13:35:53 +00:00
) );
2015-07-09 08:09:29 +00:00
return apply_filters ( 'woocommerce_email_order_items_table' , ob_get_clean (), $this );
2014-06-13 13:35:53 +00:00
}
/**
* Checks if product download is permitted
*
* @ return bool
*/
public function is_download_permitted () {
return apply_filters ( 'woocommerce_order_is_download_permitted' , $this -> has_status ( 'completed' ) || ( get_option ( 'woocommerce_downloads_grant_access_after_payment' ) == 'yes' && $this -> has_status ( 'processing' ) ), $this );
}
/**
* Returns true if the order contains a downloadable product .
*
* @ return bool
*/
public function has_downloadable_item () {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$has_downloadable_item = false ;
foreach ( $this -> get_items () as $item ) {
$_product = $this -> get_product_from_item ( $item );
if ( $_product && $_product -> exists () && $_product -> is_downloadable () && $_product -> has_file () ) {
$has_downloadable_item = true ;
}
}
return $has_downloadable_item ;
}
/**
* Generates a URL so that a customer can pay for their ( unpaid - pending ) order . Pass 'true' for the checkout version which doesn ' t offer gateway choices .
*
* @ param boolean $on_checkout
* @ return string
*/
public function get_checkout_payment_url ( $on_checkout = false ) {
2015-02-15 19:13:22 +00:00
$pay_url = wc_get_endpoint_url ( 'order-pay' , $this -> id , wc_get_page_permalink ( 'checkout' ) );
2014-06-13 13:35:53 +00:00
if ( 'yes' == get_option ( 'woocommerce_force_ssl_checkout' ) || is_ssl () ) {
$pay_url = str_replace ( 'http:' , 'https:' , $pay_url );
}
if ( $on_checkout ) {
$pay_url = add_query_arg ( 'key' , $this -> order_key , $pay_url );
} else {
$pay_url = add_query_arg ( array ( 'pay_for_order' => 'true' , 'key' => $this -> order_key ), $pay_url );
}
return apply_filters ( 'woocommerce_get_checkout_payment_url' , $pay_url , $this );
}
/**
* Generates a URL for the thanks page ( order received )
*
* @ return string
*/
public function get_checkout_order_received_url () {
2015-02-15 19:13:22 +00:00
$order_received_url = wc_get_endpoint_url ( 'order-received' , $this -> id , wc_get_page_permalink ( 'checkout' ) );
2014-06-13 13:35:53 +00:00
if ( 'yes' == get_option ( 'woocommerce_force_ssl_checkout' ) || is_ssl () ) {
$order_received_url = str_replace ( 'http:' , 'https:' , $order_received_url );
}
$order_received_url = add_query_arg ( 'key' , $this -> order_key , $order_received_url );
return apply_filters ( 'woocommerce_get_checkout_order_received_url' , $order_received_url , $this );
}
/**
* Generates a URL so that a customer can cancel their ( unpaid - pending ) order .
*
2014-11-21 21:14:13 +00:00
* @ param string $redirect
*
2014-06-13 13:35:53 +00:00
* @ return string
*/
public function get_cancel_order_url ( $redirect = '' ) {
2015-03-03 07:01:17 +00:00
2015-03-06 14:06:24 +00:00
// Get cancel endpoint
2015-03-03 07:01:17 +00:00
$cancel_endpoint = $this -> get_cancel_endpoint ();
2015-03-06 14:06:24 +00:00
return apply_filters ( 'woocommerce_get_cancel_order_url' , wp_nonce_url ( add_query_arg ( array (
'cancel_order' => 'true' ,
'order' => $this -> order_key ,
'order_id' => $this -> id ,
'redirect' => $redirect
), $cancel_endpoint ), 'woocommerce-cancel_order' ) );
2015-03-03 07:01:17 +00:00
}
/**
* Generates a raw ( unescaped ) cancel - order URL for use by payment gateways
*
* @ param string $redirect
*
* @ return string The unescaped cancel - order URL
*/
public function get_cancel_order_url_raw ( $redirect = '' ) {
2015-03-06 14:06:24 +00:00
// Get cancel endpoint
2015-03-03 07:01:17 +00:00
$cancel_endpoint = $this -> get_cancel_endpoint ();
2015-03-06 14:06:24 +00:00
return apply_filters ( 'woocommerce_get_cancel_order_url_raw' , add_query_arg ( array (
'cancel_order' => 'true' ,
'order' => $this -> order_key ,
'order_id' => $this -> id ,
'redirect' => $redirect ,
'_wpnonce' => wp_create_nonce ( 'woocommerce-cancel_order' )
), $cancel_endpoint ) );
2015-03-03 07:01:17 +00:00
}
/**
2015-03-06 14:06:24 +00:00
* Helper method to return the cancel endpoint
2015-03-03 07:01:17 +00:00
*
* @ return string the cancel endpoint ; either the cart page or the home page
*/
public function get_cancel_endpoint () {
2015-02-15 19:13:22 +00:00
$cancel_endpoint = wc_get_page_permalink ( 'cart' );
2014-06-13 13:35:53 +00:00
if ( ! $cancel_endpoint ) {
$cancel_endpoint = home_url ();
}
if ( false === strpos ( $cancel_endpoint , '?' ) ) {
$cancel_endpoint = trailingslashit ( $cancel_endpoint );
}
2015-03-03 07:01:17 +00:00
return $cancel_endpoint ;
2014-06-13 13:35:53 +00:00
}
2015-03-03 07:01:17 +00:00
2014-06-13 13:35:53 +00:00
/**
* Generates a URL to view an order from the my account page
*
* @ return string
*/
public function get_view_order_url () {
2014-08-31 05:49:58 +00:00
2015-02-15 19:13:22 +00:00
$view_order_url = wc_get_endpoint_url ( 'view-order' , $this -> id , wc_get_page_permalink ( 'myaccount' ) );
2014-06-13 13:35:53 +00:00
return apply_filters ( 'woocommerce_get_view_order_url' , $view_order_url , $this );
}
/**
* Get the downloadable files for an item in this order
2014-08-31 05:49:58 +00:00
*
2014-06-13 13:35:53 +00:00
* @ param array $item
* @ return array
*/
public function get_item_downloads ( $item ) {
global $wpdb ;
$product_id = $item [ 'variation_id' ] > 0 ? $item [ 'variation_id' ] : $item [ 'product_id' ];
2014-08-19 10:09:29 +00:00
$product = wc_get_product ( $product_id );
2015-06-29 13:08:16 +00:00
if ( ! $product ) {
/**
* $product can be `false` . Example : checking an old order , when a product or variation has been deleted
* @ see \WC_Product_Factory :: get_product
*/
return array ();
}
2014-06-13 13:35:53 +00:00
$download_ids = $wpdb -> get_col ( $wpdb -> prepare ( "
SELECT download_id
FROM { $wpdb -> prefix } woocommerce_downloadable_product_permissions
WHERE user_email = % s
AND order_key = % s
AND product_id = % s
ORDER BY permission_id
" , $this->billing_email , $this->order_key , $product_id ) );
$files = array ();
foreach ( $download_ids as $download_id ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( $product -> has_file ( $download_id ) ) {
$files [ $download_id ] = $product -> get_file ( $download_id );
$files [ $download_id ][ 'download_url' ] = $this -> get_download_url ( $product_id , $download_id );
}
}
return apply_filters ( 'woocommerce_get_item_downloads' , $files , $item , $this );
}
2015-05-01 11:42:29 +00:00
/**
* Display download links for an order item
* @ param array $item
*/
public function display_item_downloads ( $item ) {
$product = $this -> get_product_from_item ( $item );
if ( $product && $product -> exists () && $product -> is_downloadable () && $this -> is_download_permitted () ) {
$download_files = $this -> get_item_downloads ( $item );
$i = 0 ;
$links = array ();
foreach ( $download_files as $download_id => $file ) {
$links [] = '<small><a href="' . esc_url ( $file [ 'download_url' ] ) . '">' . sprintf ( __ ( 'Download file%s' , 'woocommerce' ), ( count ( $download_files ) > 1 ? ' ' . ( $i ++ ) . ': ' : ': ' ) ) . esc_html ( $file [ 'name' ] ) . '</a></small>' ;
}
echo '<br/>' . implode ( '<br/>' , $links );
}
}
2014-06-13 13:35:53 +00:00
/**
* Get the Download URL
2014-08-31 05:49:58 +00:00
*
2014-06-13 13:35:53 +00:00
* @ param int $product_id
* @ param int $download_id
* @ return string
*/
public function get_download_url ( $product_id , $download_id ) {
return add_query_arg ( array (
'download_file' => $product_id ,
'order' => $this -> order_key ,
'email' => urlencode ( $this -> billing_email ),
'key' => $download_id
), trailingslashit ( home_url () ) );
}
/**
* Adds a note ( comment ) to the order
*
* @ param string $note Note to add
* @ param int $is_customer_note ( default : 0 ) Is this a note for the customer ?
2015-04-17 10:23:09 +00:00
* @ param bool added_by_user Was the note added by a user ?
2015-01-23 14:35:15 +00:00
* @ return int Comment ID
2014-06-13 13:35:53 +00:00
*/
2015-04-17 10:23:09 +00:00
public function add_order_note ( $note , $is_customer_note = 0 , $added_by_user = false ) {
if ( is_user_logged_in () && current_user_can ( 'edit_shop_order' , $this -> id ) && $added_by_user ) {
2014-06-13 13:35:53 +00:00
$user = get_user_by ( 'id' , get_current_user_id () );
$comment_author = $user -> display_name ;
$comment_author_email = $user -> user_email ;
} else {
$comment_author = __ ( 'WooCommerce' , 'woocommerce' );
$comment_author_email = strtolower ( __ ( 'WooCommerce' , 'woocommerce' ) ) . '@' ;
$comment_author_email .= isset ( $_SERVER [ 'HTTP_HOST' ] ) ? str_replace ( 'www.' , '' , $_SERVER [ 'HTTP_HOST' ] ) : 'noreply.com' ;
$comment_author_email = sanitize_email ( $comment_author_email );
}
2014-08-31 05:49:58 +00:00
$comment_post_ID = $this -> id ;
$comment_author_url = '' ;
$comment_content = $note ;
$comment_agent = 'WooCommerce' ;
$comment_type = 'order_note' ;
$comment_parent = 0 ;
$comment_approved = 1 ;
$commentdata = apply_filters ( 'woocommerce_new_order_note_data' , compact ( 'comment_post_ID' , 'comment_author' , 'comment_author_email' , 'comment_author_url' , 'comment_content' , 'comment_agent' , 'comment_type' , 'comment_parent' , 'comment_approved' ), array ( 'order_id' => $this -> id , 'is_customer_note' => $is_customer_note ) );
2014-06-13 13:35:53 +00:00
$comment_id = wp_insert_comment ( $commentdata );
if ( $is_customer_note ) {
2015-04-23 10:50:09 +00:00
add_comment_meta ( $comment_id , 'is_customer_note' , 1 );
2015-02-10 16:44:28 +00:00
do_action ( 'woocommerce_new_customer_note' , array ( 'order_id' => $this -> id , 'customer_note' => $commentdata [ 'comment_content' ] ) );
2014-06-13 13:35:53 +00:00
}
return $comment_id ;
}
/**
* Updates status of order
*
* @ param string $new_status Status to change the order to . No internal wc - prefix is required .
* @ param string $note ( default : '' ) Optional note to add
*/
public function update_status ( $new_status , $note = '' ) {
2014-09-17 11:24:05 +00:00
if ( ! $this -> id ) {
return ;
}
// Standardise status names.
2014-06-13 13:35:53 +00:00
$new_status = 'wc-' === substr ( $new_status , 0 , 3 ) ? substr ( $new_status , 3 ) : $new_status ;
2014-09-17 11:24:05 +00:00
$old_status = $this -> get_status ();
2014-07-28 03:23:59 +00:00
2014-09-17 11:24:05 +00:00
// Only update if they differ - and ensure post_status is a 'wc' status.
if ( $new_status !== $old_status || ! in_array ( $this -> post_status , array_keys ( wc_get_order_statuses () ) ) ) {
2014-07-28 03:23:59 +00:00
2014-06-13 13:35:53 +00:00
// Update the order
wp_update_post ( array ( 'ID' => $this -> id , 'post_status' => 'wc-' . $new_status ) );
$this -> post_status = 'wc-' . $new_status ;
2014-09-09 17:00:37 +00:00
2014-09-12 13:01:49 +00:00
$this -> add_order_note ( trim ( $note . ' ' . sprintf ( __ ( 'Order status changed from %s to %s.' , 'woocommerce' ), wc_get_order_status_name ( $old_status ), wc_get_order_status_name ( $new_status ) ) ) );
2014-06-13 13:35:53 +00:00
// Status was changed
do_action ( 'woocommerce_order_status_' . $new_status , $this -> id );
do_action ( 'woocommerce_order_status_' . $old_status . '_to_' . $new_status , $this -> id );
do_action ( 'woocommerce_order_status_changed' , $this -> id , $old_status , $new_status );
switch ( $new_status ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
case 'completed' :
// Record the sales
$this -> record_product_sales ();
// Increase coupon usage counts
$this -> increase_coupon_usage_counts ();
// Record the completed date of the order
update_post_meta ( $this -> id , '_completed_date' , current_time ( 'mysql' ) );
2014-07-03 11:38:55 +00:00
// Update reports
wc_delete_shop_order_transients ( $this -> id );
2014-06-13 13:35:53 +00:00
break ;
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
case 'processing' :
case 'on-hold' :
// Record the sales
$this -> record_product_sales ();
// Increase coupon usage counts
$this -> increase_coupon_usage_counts ();
2014-07-03 11:38:55 +00:00
// Update reports
wc_delete_shop_order_transients ( $this -> id );
2014-06-13 13:35:53 +00:00
break ;
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
case 'cancelled' :
// If the order is cancelled, restore used coupons
$this -> decrease_coupon_usage_counts ();
2014-07-03 11:38:55 +00:00
// Update reports
wc_delete_shop_order_transients ( $this -> id );
2014-06-13 13:35:53 +00:00
break ;
}
}
}
/**
* Cancel the order and restore the cart ( before payment )
*
* @ param string $note ( default : '' ) Optional note to add
*/
public function cancel_order ( $note = '' ) {
2015-02-03 12:57:08 +00:00
WC () -> session -> set ( 'order_awaiting_payment' , false );
2014-06-13 13:35:53 +00:00
$this -> update_status ( 'cancelled' , $note );
}
/**
* When a payment is complete this function is called
*
* Most of the time this should mark an order as 'processing' so that admin can process / post the items
* If the cart contains only downloadable items then the order is 'completed' since the admin needs to take no action
* Stock levels are reduced at this point
* Sales are also recorded for products
* Finally , record the date of payment
*
* @ param $transaction_id string Optional transaction id to store in post meta
*/
public function payment_complete ( $transaction_id = '' ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
do_action ( 'woocommerce_pre_payment_complete' , $this -> id );
2015-02-11 00:55:47 +00:00
if ( null !== WC () -> session ) {
WC () -> session -> set ( 'order_awaiting_payment' , false );
}
2014-06-13 13:35:53 +00:00
2014-12-10 16:54:08 +00:00
$valid_order_statuses = apply_filters ( 'woocommerce_valid_order_statuses_for_payment_complete' , array ( 'on-hold' , 'pending' , 'failed' , 'cancelled' ), $this );
2014-06-13 13:35:53 +00:00
if ( $this -> id && $this -> has_status ( $valid_order_statuses ) ) {
$order_needs_processing = true ;
if ( sizeof ( $this -> get_items () ) > 0 ) {
2014-07-29 18:08:08 +00:00
foreach ( $this -> get_items () as $item ) {
2014-06-13 13:35:53 +00:00
if ( $item [ 'product_id' ] > 0 ) {
$_product = $this -> get_product_from_item ( $item );
2014-07-29 18:08:08 +00:00
if ( false !== $_product && ! apply_filters ( 'woocommerce_order_item_needs_processing' , ! ( $_product -> is_downloadable () && $_product -> is_virtual () ), $_product , $this -> id ) ) {
2014-06-13 13:35:53 +00:00
$order_needs_processing = false ;
continue ;
}
}
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$order_needs_processing = true ;
break ;
}
}
$new_order_status = $order_needs_processing ? 'processing' : 'completed' ;
$new_order_status = apply_filters ( 'woocommerce_payment_complete_order_status' , $new_order_status , $this -> id );
$this -> update_status ( $new_order_status );
add_post_meta ( $this -> id , '_paid_date' , current_time ( 'mysql' ), true );
if ( ! empty ( $transaction_id ) ) {
2014-07-07 10:43:06 +00:00
add_post_meta ( $this -> id , '_transaction_id' , $transaction_id , true );
2014-06-13 13:35:53 +00:00
}
$this_order = array (
'ID' => $this -> id ,
'post_date' => current_time ( 'mysql' , 0 ),
'post_date_gmt' => current_time ( 'mysql' , 1 )
);
wp_update_post ( $this_order );
if ( apply_filters ( 'woocommerce_payment_complete_reduce_order_stock' , true , $this -> id ) ) {
$this -> reduce_order_stock (); // Payment is complete so reduce stock levels
}
do_action ( 'woocommerce_payment_complete' , $this -> id );
} else {
do_action ( 'woocommerce_payment_complete_order_status_' . $this -> get_status (), $this -> id );
}
}
/**
* Record sales
*/
public function record_product_sales () {
if ( 'yes' == get_post_meta ( $this -> id , '_recorded_sales' , true ) ) {
return ;
}
if ( sizeof ( $this -> get_items () ) > 0 ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
foreach ( $this -> get_items () as $item ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( $item [ 'product_id' ] > 0 ) {
$sales = ( int ) get_post_meta ( $item [ 'product_id' ], 'total_sales' , true );
$sales += ( int ) $item [ 'qty' ];
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( $sales ) {
update_post_meta ( $item [ 'product_id' ], 'total_sales' , $sales );
}
}
}
}
update_post_meta ( $this -> id , '_recorded_sales' , 'yes' );
}
/**
* Get coupon codes only .
*
* @ return array
*/
public function get_used_coupons () {
$codes = array ();
$coupons = $this -> get_items ( 'coupon' );
foreach ( $coupons as $item_id => $item ) {
$codes [] = trim ( $item [ 'name' ] );
}
return $codes ;
}
/**
* Increase applied coupon counts
*/
public function increase_coupon_usage_counts () {
if ( 'yes' == get_post_meta ( $this -> id , '_recorded_coupon_usage_counts' , true ) ) {
return ;
}
if ( sizeof ( $this -> get_used_coupons () ) > 0 ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
foreach ( $this -> get_used_coupons () as $code ) {
if ( ! $code ) {
continue ;
}
$coupon = new WC_Coupon ( $code );
2015-01-26 18:48:03 +00:00
$used_by = $this -> get_user_id ();
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( ! $used_by ) {
$used_by = $this -> billing_email ;
}
$coupon -> inc_usage_count ( $used_by );
}
2015-01-30 14:14:34 +00:00
update_post_meta ( $this -> id , '_recorded_coupon_usage_counts' , 'yes' );
}
2014-06-13 13:35:53 +00:00
}
/**
* Decrease applied coupon counts
*/
public function decrease_coupon_usage_counts () {
if ( 'yes' != get_post_meta ( $this -> id , '_recorded_coupon_usage_counts' , true ) ) {
return ;
}
if ( sizeof ( $this -> get_used_coupons () ) > 0 ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
foreach ( $this -> get_used_coupons () as $code ) {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
if ( ! $code ) {
continue ;
}
$coupon = new WC_Coupon ( $code );
2015-01-26 18:48:03 +00:00
$used_by = $this -> get_user_id ();
2014-06-13 13:35:53 +00:00
if ( ! $used_by ) {
$used_by = $this -> billing_email ;
}
$coupon -> dcr_usage_count ( $used_by );
}
2015-01-30 14:14:34 +00:00
delete_post_meta ( $this -> id , '_recorded_coupon_usage_counts' );
}
2014-06-13 13:35:53 +00:00
}
/**
2015-08-03 09:37:56 +00:00
* Reduce stock levels for all line items in the order .
* Runs if stock management is enabled , but can be disabled on per - order basis by extensions @ since 2.4 . 0 via woocommerce_can_reduce_order_stock hook .
2014-06-13 13:35:53 +00:00
*/
public function reduce_order_stock () {
2015-08-03 09:37:56 +00:00
if ( 'yes' === get_option ( 'woocommerce_manage_stock' ) && apply_filters ( 'woocommerce_can_reduce_order_stock' , true , $this ) && sizeof ( $this -> get_items () ) > 0 ) {
2014-06-13 13:35:53 +00:00
foreach ( $this -> get_items () as $item ) {
if ( $item [ 'product_id' ] > 0 ) {
$_product = $this -> get_product_from_item ( $item );
if ( $_product && $_product -> exists () && $_product -> managing_stock () ) {
$qty = apply_filters ( 'woocommerce_order_item_quantity' , $item [ 'qty' ], $this , $item );
$new_stock = $_product -> reduce_stock ( $qty );
2014-12-23 11:01:11 +00:00
if ( isset ( $item [ 'variation_id' ] ) && $item [ 'variation_id' ] ) {
2015-08-03 09:37:56 +00:00
$this -> add_order_note ( sprintf ( __ ( 'Item #%s variation #%s stock reduced from %s to %s.' , 'woocommerce' ), $item [ 'product_id' ], $item [ 'variation_id' ], $new_stock + $qty , $new_stock ) );
2014-12-23 11:01:11 +00:00
} else {
$this -> add_order_note ( sprintf ( __ ( 'Item #%s stock reduced from %s to %s.' , 'woocommerce' ), $item [ 'product_id' ], $new_stock + $qty , $new_stock ) );
}
2014-06-13 13:35:53 +00:00
$this -> send_stock_notifications ( $_product , $new_stock , $item [ 'qty' ] );
}
}
}
do_action ( 'woocommerce_reduce_order_stock' , $this );
}
}
/**
2014-11-21 21:16:15 +00:00
* Send the stock notifications
2014-06-13 13:35:53 +00:00
*
2014-09-07 23:37:55 +00:00
* @ param WC_Product $product
2014-06-13 13:35:53 +00:00
* @ param int $new_stock
* @ param int $qty_ordered
*/
public function send_stock_notifications ( $product , $new_stock , $qty_ordered ) {
// Backorders
if ( $new_stock < 0 ) {
do_action ( 'woocommerce_product_on_backorder' , array ( 'product' => $product , 'order_id' => $this -> id , 'quantity' => $qty_ordered ) );
}
// stock status notifications
$notification_sent = false ;
2014-11-18 12:42:54 +00:00
if ( 'yes' == get_option ( 'woocommerce_notify_no_stock' ) && get_option ( 'woocommerce_notify_no_stock_amount' ) >= $new_stock ) {
2014-06-13 13:35:53 +00:00
do_action ( 'woocommerce_no_stock' , $product );
$notification_sent = true ;
}
2014-08-31 05:49:58 +00:00
2014-11-18 12:42:54 +00:00
if ( ! $notification_sent && 'yes' == get_option ( 'woocommerce_notify_low_stock' ) && get_option ( 'woocommerce_notify_low_stock_amount' ) >= $new_stock ) {
2014-06-13 13:35:53 +00:00
do_action ( 'woocommerce_low_stock' , $product );
}
}
/**
* List order notes ( public ) for the customer
*
* @ return array
*/
public function get_customer_order_notes () {
$notes = array ();
2015-04-23 10:50:09 +00:00
$args = array (
2014-06-13 13:35:53 +00:00
'post_id' => $this -> id ,
'approve' => 'approve' ,
2015-04-23 10:50:09 +00:00
'type' => ''
2014-06-13 13:35:53 +00:00
);
remove_filter ( 'comments_clauses' , array ( 'WC_Comments' , 'exclude_order_comments' ) );
$comments = get_comments ( $args );
foreach ( $comments as $comment ) {
2015-04-23 10:50:09 +00:00
if ( ! get_comment_meta ( $comment -> comment_ID , 'is_customer_note' , true ) ) {
continue ;
2014-06-13 13:35:53 +00:00
}
2015-04-23 10:50:09 +00:00
$comment -> comment_content = make_clickable ( $comment -> comment_content );
$notes [] = $comment ;
2014-06-13 13:35:53 +00:00
}
add_filter ( 'comments_clauses' , array ( 'WC_Comments' , 'exclude_order_comments' ) );
2015-04-23 10:50:09 +00:00
return $notes ;
2014-06-13 13:35:53 +00:00
}
/**
* Checks if an order needs payment , based on status and order total
*
* @ return bool
*/
public function needs_payment () {
2014-08-31 05:49:58 +00:00
2014-06-13 13:35:53 +00:00
$valid_order_statuses = apply_filters ( 'woocommerce_valid_order_statuses_for_payment' , array ( 'pending' , 'failed' ), $this );
if ( $this -> has_status ( $valid_order_statuses ) && $this -> get_total () > 0 ) {
$needs_payment = true ;
} else {
$needs_payment = false ;
}
return apply_filters ( 'woocommerce_order_needs_payment' , $needs_payment , $this , $valid_order_statuses );
}
/**
* Checks if an order needs display the shipping address , based on shipping method
*
2014-09-11 10:11:22 +00:00
* @ return boolean
2014-06-13 13:35:53 +00:00
*/
public function needs_shipping_address () {
2015-05-01 13:50:18 +00:00
if ( 'no' === get_option ( 'woocommerce_calc_shipping' ) ) {
return false ;
}
2014-06-13 13:35:53 +00:00
$hide = apply_filters ( 'woocommerce_order_hide_shipping_address' , array ( 'local_pickup' ), $this );
2015-05-28 14:48:37 +00:00
$needs_address = false ;
2014-06-13 13:35:53 +00:00
foreach ( $this -> get_shipping_methods () as $shipping_method ) {
if ( ! in_array ( $shipping_method [ 'method_id' ], $hide ) ) {
2015-05-28 14:48:37 +00:00
$needs_address = true ;
2014-06-13 13:35:53 +00:00
break ;
}
}
2014-09-11 10:11:22 +00:00
2015-05-28 14:48:37 +00:00
return apply_filters ( 'woocommerce_order_needs_shipping_address' , $needs_address , $hide , $this );
2014-06-13 13:35:53 +00:00
}
2014-09-02 18:47:56 +00:00
/**
* Checks if an order can be edited , specifically for use on the Edit Order screen
*
* @ return bool
*/
public function is_editable () {
2015-01-20 12:07:33 +00:00
return apply_filters ( 'wc_order_is_editable' , in_array ( $this -> get_status (), array ( 'pending' , 'on-hold' , 'auto-draft' ) ), $this );
2014-09-02 18:47:56 +00:00
}
2014-07-28 03:31:26 +00:00
}