diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 44fb496800f..6da57186e64 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -828,10 +828,13 @@ abstract class WC_Abstract_Order { $this->customer_note = $result->post_excerpt; $this->post_status = $result->post_status; - // Billing email cam default to user if set + // Billing email can default to user if set if ( empty( $this->billing_email ) && ! empty( $this->customer_user ) && ( $user = get_user_by( 'id', $this->customer_user ) ) ) { $this->billing_email = $user->user_email; } + + // Orders store the state of prices including tax when created + $this->prices_include_tax = metadata_exists( 'post', $this->id, '_prices_include_tax' ) ? get_post_meta( $this->id, '_prices_include_tax', true ) : $this->prices_include_tax; } /** @@ -1263,11 +1266,30 @@ abstract class WC_Abstract_Order { * @return float */ public function get_total_discount( $ex_tax = true ) { - if ( $ex_tax ) { - return apply_filters( 'woocommerce_order_amount_total_discount', (double) $this->cart_discount, $this ); + 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 } else { - return apply_filters( 'woocommerce_order_amount_total_discount', (double) $this->cart_discount + (double) $this->cart_discount_tax, $this ); + if ( $ex_tax ) { + $total_discount = (double) $this->cart_discount; + } else { + $total_discount = (double) $this->cart_discount + (double) $this->cart_discount_tax; + } } + return apply_filters( 'woocommerce_order_amount_total_discount', $total_discount, $this ); } /** diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 71c21d3dad0..89545922b04 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -341,6 +341,9 @@ function wc_save_order_items( $order_id, $items ) { // Set the currency add_post_meta( $order_id, '_order_currency', get_woocommerce_currency(), true ); + // Update version after saving + update_post_meta( $order_id, '_order_version', WC_VERSION ); + // inform other plugins that the items have been saved do_action( 'woocommerce_saved_order_items', $order_id, $items ); } diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index 02b55cf0584..cba8dc4069a 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -1736,17 +1736,9 @@ class WC_Cart { $discount_amount = isset( $this->coupon_discount_amounts[ $code ] ) ? $this->coupon_discount_amounts[ $code ] : 0; if ( $ex_tax ) { - if ( $this->prices_include_tax ) { - return $discount_amount - $this->get_coupon_discount_tax_amount( $code ); - } else { - return $discount_amount; - } + return $discount_amount; } else { - if ( $this->prices_include_tax ) { - return $discount_amount; - } else { - return $discount_amount + $this->get_coupon_discount_tax_amount( $code ); - } + return $discount_amount + $this->get_coupon_discount_tax_amount( $code ); } } @@ -1819,11 +1811,11 @@ class WC_Cart { $total_discount = $discount_amount * $values['quantity']; $total_discount_tax = 0; - if ( $this->prices_include_tax || $this->tax_display_cart === 'incl' ) { - $tax_rates = WC_Tax::get_rates( $product->get_tax_class() ); - $taxes = WC_Tax::calc_tax( $discount_amount, $tax_rates, $this->prices_include_tax ); - $total_discount_tax = WC_Tax::get_tax_total( $taxes ) * $values['quantity']; - } + // Calc discounted tax + $tax_rates = WC_Tax::get_rates( $product->get_tax_class() ); + $taxes = WC_Tax::calc_tax( $discount_amount, $tax_rates, $this->prices_include_tax ); + $total_discount_tax = WC_Tax::get_tax_total( $taxes ) * $values['quantity']; + $total_discount = $this->prices_include_tax ? $total_discount - $total_discount_tax : $total_discount; $this->discount_cart += $total_discount; $this->discount_cart_tax += $total_discount_tax; @@ -2176,7 +2168,6 @@ class WC_Cart { return apply_filters( 'woocommerce_cart_total_discount', $total_discount, $this ); } - /** * Gets the total (product) discount amount - these are applied before tax. * diff --git a/includes/wc-core-functions.php b/includes/wc-core-functions.php index 53bce9f0713..feaea0324d5 100644 --- a/includes/wc-core-functions.php +++ b/includes/wc-core-functions.php @@ -111,6 +111,8 @@ function wc_create_order( $args = array() ) { update_post_meta( $order_id, '_customer_user', $args['customer_id'] ); } + update_post_meta( $order_id, '_order_version', WC_VERSION ); + return new WC_Order( $order_id ); } diff --git a/readme.txt b/readme.txt index 36fee0af427..56e03a7bce8 100644 --- a/readme.txt +++ b/readme.txt @@ -138,6 +138,9 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc == Changelog == +* Fix - get_total_discount() function with certain tax setups. +* Tweak - Revised how discounts/discount taxes are stored for consistency. Always store ex. tax to make data retrieval easier, and to ensure totals are correct after settings changes. Backwards compatibility maintained through use of order versioning. + = 2.3.6 - 13/03/2015 = * Fix - Removal of coupons containing spaces. * Fix - Unclosed div in profile page.