[2.3] Fix - get_total_discount() function with certain tax setups.

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.

#7728
This commit is contained in:
Mike Jolley 2015-03-16 12:17:09 +00:00
parent 7667b5c2cd
commit 70d125ae96
5 changed files with 41 additions and 20 deletions

View File

@ -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 );
}
/**

View File

@ -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 );
}

View File

@ -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.
*

View File

@ -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 );
}

View File

@ -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.