Tax rewrite to deal with coupons before tax calculations

Needs a lot of testing - esp to detect rounding errors.
This commit is contained in:
Mike Jolley 2011-11-19 20:59:16 +00:00
parent de1d59a313
commit fe5651fff5
13 changed files with 327 additions and 166 deletions

View File

@ -89,7 +89,7 @@ function woocommerce_admin_scripts() {
$woocommerce_witepanel_params = array(
'remove_item_notice' => __("Remove this item? If you have previously reduced this item's stock, or this order was submitted by a customer, will need to manually restore the item's stock.", 'woothemes'),
'cart_total' => __("Calc totals based on order items, discount amount, and shipping?", 'woothemes'),
'cart_total' => __("Calculate totals based on order items, discount amount, and shipping? Note, you will need to calculate discounts before tax manually.", 'woothemes'),
'copy_billing' => __("Copy billing information to shipping information? This will remove any currently entered shipping information.", 'woothemes'),
'prices_include_tax' => get_option('woocommerce_prices_include_tax'),
'ID' => __('ID', 'woothemes'),

View File

@ -35,6 +35,9 @@ function woocommerce_coupon_data_meta_box($post) {
// Individual use
woocommerce_wp_checkbox( array( 'id' => 'individual_use', 'label' => __('Individual use', 'woothemes'), 'description' => __('Check this box if the coupon cannot be used in conjunction with other coupons', 'woothemes') ) );
// Apply before tax
woocommerce_wp_checkbox( array( 'id' => 'apply_before_tax', 'label' => __('Apply coupon before tax?', 'woothemes'), 'description' => __('Check this box if the coupon should be applied before calculating a product\'s tax', 'woothemes') ) );
// Product ids
woocommerce_wp_text_input( array( 'id' => 'product_ids', 'label' => __('Product IDs', 'woothemes'), 'placeholder' => __('N/A', 'woothemes'), 'description' => __('(optional) Comma separate IDs which need to be in the cart to use this coupon or, for "Product Discounts", which products are discounted.', 'woothemes') ) );
@ -54,18 +57,6 @@ function woocommerce_coupon_data_meta_box($post) {
<?php
}
/**
* Coupon data meta box
*
* Displays the meta box
*/
add_filter('enter_title_here', 'woocommerce_coupon_enter_title_here', 1, 2);
function woocommerce_coupon_enter_title_here( $text, $post ) {
if ($post->post_type=='shop_coupon') return __('Coupon code', 'woothemes');
return $text;
}
/**
* Coupon Data Save
*
@ -89,6 +80,7 @@ function woocommerce_process_shop_coupon_meta( $post_id, $post ) {
$usage_limit = (isset($_POST['usage_limit']) && $_POST['usage_limit']>0) ? (int) $_POST['usage_limit'] : '';
$individual_use = isset($_POST['individual_use']) ? 'yes' : 'no';
$expiry_date = strip_tags(stripslashes( $_POST['expiry_date'] ));
$apply_before_tax = isset($_POST['apply_before_tax']) ? 'yes' : 'no';
// Save
update_post_meta( $post_id, 'discount_type', $type );
@ -98,6 +90,7 @@ function woocommerce_process_shop_coupon_meta( $post_id, $post ) {
update_post_meta( $post_id, 'exclude_product_ids', $exclude_product_ids );
update_post_meta( $post_id, 'usage_limit', $usage_limit );
update_post_meta( $post_id, 'expiry_date', $expiry_date );
update_post_meta( $post_id, 'apply_before_tax', $apply_before_tax );
do_action('woocommerce_coupon_options');

View File

@ -44,6 +44,17 @@ function woocommerce_meta_boxes() {
add_meta_box('product_variation-parent', __('Product', 'woothemes'), 'variations_product_meta_box', 'product_variation', 'side', 'default');
}
/**
* Title boxes
*/
add_filter('enter_title_here', 'woocommerce_enter_title_here', 1, 2);
function woocommerce_enter_title_here( $text, $post ) {
if ($post->post_type=='shop_coupon') return __('Coupon code', 'woothemes');
if ($post->post_type=='product') return __('Product name', 'woothemes');
return $text;
}
/**
* Let variations have a product as the parent
*/

View File

@ -17,7 +17,6 @@ class woocommerce_cart {
var $applied_coupons;
var $cart_contents_total;
var $cart_contents_total_ex_tax;
var $cart_contents_weight;
var $cart_contents_count;
var $cart_contents_tax;
@ -26,14 +25,20 @@ class woocommerce_cart {
var $subtotal;
var $subtotal_ex_tax;
var $tax_total;
var $discount_product;
var $discount_total;
var $shipping_total;
var $shipping_tax_total;
/* Private variables */
var $tax;
/**
* Constructor
*/
function __construct() {
$this->tax = &new woocommerce_tax();
add_action('init', array(&$this, 'init'), 1); // Get cart on init
add_action('wp', array(&$this, 'calculate_totals'), 1); // Defer calculate totals so we can detect page
}
@ -106,18 +111,7 @@ class woocommerce_cart {
*/
function empty_cart() {
$this->cart_contents = array();
$this->total = 0;
$this->cart_contents_total = 0;
$this->cart_contents_total_ex_tax = 0;
$this->cart_contents_weight = 0;
$this->cart_contents_count = 0;
$this->cart_contents_tax = 0;
$this->tax_total = 0;
$this->shipping_tax_total = 0;
$this->subtotal = 0;
$this->subtotal_ex_tax = 0;
$this->discount_total = 0;
$this->shipping_total = 0;
$this->reset_totals();
unset($_SESSION['cart']);
unset($_SESSION['coupons']);
}
@ -188,8 +182,8 @@ class woocommerce_cart {
$product_data = &new woocommerce_product( $product_id );
endif;
// Type check
if ( $product_data->is_type('external') ) :
// Type/Exists check
if ( $product_data->is_type('external') || !$product_data->exists() ) :
$woocommerce->add_error( __('This product cannot be purchased.', 'woothemes') );
return false;
endif;
@ -308,16 +302,11 @@ class woocommerce_cart {
}
/**
* calculate totals for the items in the cart
* Reset totals
*/
function calculate_totals() {
global $woocommerce;
$_tax = &new woocommerce_tax();
private function reset_totals() {
$this->total = 0;
$this->cart_contents_total = 0;
$this->cart_contents_total_ex_tax = 0;
$this->cart_contents_weight = 0;
$this->cart_contents_count = 0;
$this->cart_contents_tax = 0;
@ -326,86 +315,128 @@ class woocommerce_cart {
$this->subtotal = 0;
$this->subtotal_ex_tax = 0;
$this->discount_total = 0;
$this->discount_product = 0;
$this->shipping_total = 0;
}
/**
* Function to apply discounts to a product and get the discounted price (before tax is applied)
*/
function get_discounted_price( $values, $price ) {
if (sizeof($this->cart_contents)>0) : foreach ($this->cart_contents as $cart_item_key => $values) :
if ($this->applied_coupons) foreach ($this->applied_coupons as $code) :
$coupon = &new woocommerce_coupon( $code );
// Get product from cart data
$_product = $values['data'];
if ( $coupon->apply_before_tax() && $coupon->is_valid() ) :
switch ($coupon->type) :
case "fixed_product" :
case "percent_product" :
$this_item_is_discounted = false;
if ($_product->exists() && $values['quantity']>0) :
$this->cart_contents_count = $this->cart_contents_count + $values['quantity'];
$this->cart_contents_weight = $this->cart_contents_weight + ($_product->get_weight() * $values['quantity']);
$total_item_price = $_product->get_price() * $values['quantity'];
if ( get_option('woocommerce_calc_taxes')=='yes') :
if ( $_product->is_taxable() ) :
$rate = $_tax->get_rate( $_product->get_tax_class() );
// Specific product ID's get the discount
if (sizeof($coupon->product_ids)>0) :
if ((in_array($values['product_id'], $coupon->product_ids) || in_array($values['variation_id'], $coupon->product_ids))) :
$this_item_is_discounted = true;
endif;
if (get_option('woocommerce_prices_include_tax')=='yes') :
// Price incldues tax
$tax_amount = $_tax->calc_tax( $_product->get_price(), $rate, true ) * $values['quantity'];
else :
// Price excludes tax
$tax_amount = $_tax->calc_tax( $_product->get_price(), $rate, false ) * $values['quantity'];
// No product ids - all items discounted
$this_item_is_discounted = true;
endif;
// Specific product ID's excluded from the discount
if (sizeof($coupon->exclude_product_ids)>0) :
if ((in_array($values['product_id'], $coupon->exclude_product_ids) || in_array($values['variation_id'], $coupon->exclude_product_ids))) :
$this_item_is_discounted = false;
endif;
endif;
/**
* Checkout calculations when customer is OUTSIDE the shop base country and price INCLUDE tax
*/
if (get_option('woocommerce_prices_include_tax')=='yes' && $woocommerce->customer->is_customer_outside_base() && defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT ) :
// Get the base rate first
$base_rate = $_tax->get_shop_base_rate( $_product->tax_class );
// Apply filter
$this_item_is_discounted = apply_filters( 'woocommerce_item_is_discounted', $this_item_is_discounted, $values, $before_tax = true );
// Apply the discount
if ($this_item_is_discounted) :
if ($coupon->type=='fixed_product') :
// Calc tax for base country
$base_tax_amount = $_tax->calc_tax( $_product->get_price(), $base_rate, true);
// Now calc tax for user county (which now excludes tax)
$tax_amount = $_tax->calc_tax( ( $_product->get_price() - $base_tax_amount ), $rate, false );
$tax_amount = $tax_amount * $values['quantity'];
// Finally, update $total_item_price to reflect tax amounts
$total_item_price = ($total_item_price - ($base_tax_amount * $values['quantity']) + $tax_amount);
/**
* Checkout calculations when customer is INSIDE the shop base country and price INCLUDE tax
*/
elseif (get_option('woocommerce_prices_include_tax')=='yes' && $_product->get_tax_class() !== $_product->tax_class) :
// Calc tax for original rate
$original_tax_amount = $_tax->calc_tax( $_product->get_price(), $_tax->get_rate( $_product->tax_class ), true);
// Now calc tax for new rate (which now excludes tax)
$tax_amount = $_tax->calc_tax( ( $_product->get_price() - $original_tax_amount ), $rate, false );
$tax_amount = $tax_amount * $values['quantity'];
$total_item_price = ($total_item_price - ($original_tax_amount * $values['quantity']) + $tax_amount);
$this->discount_product = $this->discount_product + ( $coupon->amount * $values['quantity'] );
$price = $price - $coupon->amount;
elseif ($coupon->type=='percent_product') :
$percent_discount = ( $values['data']->get_price_excluding_tax() / 100 ) * $coupon->amount;
$this->discount_product = $this->discount_product + ( $percent_discount * $values['quantity'] );
$price = $price - $percent_discount;
endif;
endif;
endif;
break;
endif;
case "fixed_cart" :
$tax_amount = ( isset($tax_amount) ? $tax_amount : 0 );
$this->cart_contents_tax = $this->cart_contents_tax + $tax_amount;
$this->cart_contents_total = $this->cart_contents_total + $total_item_price;
$this->cart_contents_total_ex_tax = $this->cart_contents_total_ex_tax + ($_product->get_price_excluding_tax()*$values['quantity']);
// Product Discounts
if ($this->applied_coupons) foreach ($this->applied_coupons as $code) :
$coupon = &new woocommerce_coupon( $code );
// Use pence to help prevent rounding errors
$coupon_amount_pence = $coupon->amount * 100;
// Get item discount by dividing by total number of products in the cart
$item_discount = $coupon_amount_pence / $this->cart_contents_count;
// Take discount off of price (in pence)
$price = ( $price * 100 ) - $item_discount;
// Back to pounds
$price = $price / 100;
// Add coupon to discount total (once, since this is a fixed cart discount and we don't want rounding issues)
$this->discount_product = $this->discount_product + (($item_discount*$values['quantity']) / 100);
break;
if ($coupon->type!='fixed_product' && $coupon->type!='percent_product') continue;
case "percent" :
// Get % off each item - this works out the same as doing the whole cart
$percent_discount = ( $values['data']->get_price_excluding_tax() / 100 ) * $coupon->amount;
$this->discount_product = $this->discount_product + ( $percent_discount * $values['quantity'] );
$price = $price - $percent_discount;
break;
endswitch;
endif;
endforeach;
return $price;
}
/**
* Function to apply product discounts after tax
*/
function apply_discount_products_after_tax( $total_item_price ) {
if ($this->applied_coupons) foreach ($this->applied_coupons as $code) :
$coupon = &new woocommerce_coupon( $code );
if ($coupon->type!='fixed_product' && $coupon->type!='percent_product') continue;
if ( !$coupon->apply_before_tax() && $coupon->is_valid() ) :
if (sizeof($this->cart_contents)>0) foreach ($this->cart_contents as $cart_item_key => $values) :
$this_item_is_discounted = false;
// Specific product ID's get the discount
if (sizeof($coupon->product_ids)>0) :
@ -419,7 +450,7 @@ class woocommerce_cart {
$this_item_is_discounted = true;
endif;
// Specific product ID's excluded from the discount
if (sizeof($coupon->exclude_product_ids)>0) :
@ -430,7 +461,7 @@ class woocommerce_cart {
endif;
// Apply filter
$this_item_is_discounted = apply_filters( 'woocommerce_item_is_discounted', $this_item_is_discounted, $values );
$this_item_is_discounted = apply_filters( 'woocommerce_item_is_discounted', $this_item_is_discounted, $values, $before_tax = false );
// Apply the discount
if ($this_item_is_discounted) :
@ -440,65 +471,143 @@ class woocommerce_cart {
$this->discount_total = $this->discount_total + ( $total_item_price / 100 ) * $coupon->amount;
endif;
endif;
endforeach;
endif;
endforeach; endif;
endforeach;
}
/**
* Function to apply cart discounts after tax
*/
function apply_cart_discounts_after_tax() {
// Calculate final totals
$this->tax_total = $this->cart_contents_tax; // Tax Total
$this->subtotal_ex_tax = $this->cart_contents_total_ex_tax; // Subtotal without tax
$this->subtotal = $this->cart_contents_total; // Subtotal
if ($this->applied_coupons) foreach ($this->applied_coupons as $code) :
$coupon = &new woocommerce_coupon( $code );
if ( !$coupon->apply_before_tax() && $coupon->is_valid() ) :
switch ($coupon->type) :
case "fixed_cart" :
$this->discount_total = $this->discount_total + $coupon->amount;
break;
case "percent" :
$percent_discount = round( ( ($this->cart_contents_total + $this->tax_total) / 100) * $coupon->amount , 2);
$this->discount_total = $this->discount_total + $percent_discount;
break;
endswitch;
endif;
endforeach;
}
/**
* calculate totals for the items in the cart
*/
function calculate_totals() {
global $woocommerce;
$this->reset_totals();
// Get count of all items
if (sizeof($this->cart_contents)>0) foreach ($this->cart_contents as $cart_item_key => $values) $this->cart_contents_count = $this->cart_contents_count + $values['quantity'];
// Calc totals for items
if (sizeof($this->cart_contents)>0) foreach ($this->cart_contents as $cart_item_key => $values) :
$_product = $values['data'];
$this->cart_contents_weight = $this->cart_contents_weight + ($_product->get_weight() * $values['quantity']);
// Base Price (i.e. no tax, regardless of region)
$base_price = $_product->get_price_excluding_tax();
// Discounted Price (base price with any pre-tax discounts applied
$discounted_price = $this->get_discounted_price( $values, $base_price );
// Tax Amount (For the line, based on discounted, ex.tax price)
if ( get_option('woocommerce_calc_taxes')=='yes' && $_product->is_taxable() ) :
$tax_rate = $this->tax->get_rate( $_product->get_tax_class() );
$tax_amount = $this->tax->calc_tax( $base_price, $tax_rate, false ) * $values['quantity'];
$discounted_tax_amount = $this->tax->calc_tax( $discounted_price, $tax_rate, false ) * $values['quantity'];
else :
$tax_amount = 0;
$discounted_tax_amount = 0;
endif;
// Total item price (discounted price + tax * quantity)
$total_item_price = ($discounted_price*$values['quantity']) + $discounted_tax_amount;
// Add any product discounts (after tax)
$this->apply_discount_products_after_tax( $total_item_price );
// Sub total is based on base prices (without discounts)
$this->subtotal = $this->subtotal + ($base_price*$values['quantity']) + $tax_amount;
$this->subtotal_ex_tax = $this->subtotal_ex_tax + ($base_price*$values['quantity']);
// Cart contents total is based on discounted prices and is used for the final total calculation
$this->cart_contents_total = $this->cart_contents_total + ($discounted_price*$values['quantity']);
// Cart tax is based on discounted amounts
$this->tax_total = $this->tax_total + $discounted_tax_amount;
endforeach;
// Cart Discounts (after tax)
$this->apply_cart_discounts_after_tax();
// Only go beyond this point if on the cart/checkout
if (!is_checkout() && !is_cart() && !defined('WOOCOMMERCE_CHECKOUT') && !is_ajax()) return;
// Cart Discounts
if ($this->applied_coupons) foreach ($this->applied_coupons as $code) :
$coupon = &new woocommerce_coupon( $code );
if ($coupon->is_valid()) :
if ($coupon->type=='fixed_cart') :
$this->discount_total = $this->discount_total + $coupon->amount;
elseif ($coupon->type=='percent') :
if (get_option('woocommerce_prices_include_tax')=='yes') :
$this->discount_total = $this->discount_total + ( $this->subtotal / 100 ) * $coupon->amount;
else :
$this->discount_total = $this->discount_total + ( ($this->subtotal + $this->cart_contents_tax) / 100 ) * $coupon->amount;
endif;
endif;
endif;
endforeach;
// Cart Shipping
if ($this->needs_shipping()) $woocommerce->shipping->calculate_shipping(); else $woocommerce->shipping->reset_shipping();
if ($this->needs_shipping()) :
$woocommerce->shipping->calculate_shipping();
else :
$woocommerce->shipping->reset_shipping();
endif;
$this->shipping_total = $woocommerce->shipping->shipping_total; // Shipping Total
$this->shipping_tax_total = $woocommerce->shipping->shipping_tax; // Shipping Tax
// VAT excemption done at this point - so all totals are correct before exemption
if ($woocommerce->customer->is_vat_exempt()) :
$this->shipping_tax_total = 0;
$this->tax_total = 0;
$this->shipping_tax_total = $this->tax_total = 0;
endif;
// Allow plugins to hook and alter totals before final total is calculated
do_action('woocommerce_calculate_totals', $this);
// Grand Total
if (get_option('woocommerce_prices_include_tax')=='yes') :
$this->total = $this->subtotal + $this->shipping_tax_total - $this->discount_total + $woocommerce->shipping->shipping_total;
else :
$this->total = $this->subtotal + $this->tax_total + $this->shipping_tax_total - $this->discount_total + $woocommerce->shipping->shipping_total;
endif;
/**
* Grand Total
*
* Based on discounted product prices, discounted tax, shipping cost + tax, and any discounts to be added after tax (e.g. store credit)
*/
$this->total = $this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $woocommerce->shipping->shipping_total - $this->discount_total;
if ($this->total < 0) $this->total = 0;
}
/**
* Get the total of all discounts
*/
function get_discount_total() {
return $this->discount_total + $this->discount_product;
}
/**
*returns whether or not a discount has been applied
*/
@ -547,10 +656,10 @@ class woocommerce_cart {
* Check cart items for errors
*/
function check_cart_items() {
global $woocommerce;
$result = $this->check_cart_item_stock();
if (is_wp_error($result)) $woocommerce->add_error( $result->get_error_message() );
}
/**
@ -720,11 +829,7 @@ class woocommerce_cart {
if (get_option('woocommerce_display_totals_tax')=='excluding' || ( defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT )) :
if (get_option('woocommerce_prices_include_tax')=='yes') :
$return = woocommerce_price($this->subtotal - $this->tax_total);
else :
$return = woocommerce_price($this->subtotal);
endif;
$return = woocommerce_price( $this->subtotal_ex_tax );
if ($this->tax_total>0) :
$return .= ' <small>'.$woocommerce->countries->ex_tax_or_vat().'</small>';
@ -733,11 +838,7 @@ class woocommerce_cart {
else :
if (get_option('woocommerce_prices_include_tax')=='yes') :
$return = woocommerce_price($this->subtotal);
else :
$return = woocommerce_price($this->subtotal + $this->tax_total);
endif;
$return = woocommerce_price( $this->subtotal );
if ($this->tax_total>0) :
$return .= ' <small>'.$woocommerce->countries->inc_tax_or_vat().'</small>';
@ -802,10 +903,34 @@ class woocommerce_cart {
}
/**
* gets the total discount amount
* gets the total (product) discount amount - these are applied before tax
*/
function get_discounts_before_tax() {
if ($this->discount_product) :
return woocommerce_price($this->discount_product);
endif;
return false;
}
/**
* gets the total (product) discount amount - these are applied before tax
*/
function get_discounts_after_tax() {
if ($this->discount_total) :
return woocommerce_price($this->discount_total);
endif;
return false;
}
/**
* gets the total discount amount - both kinds
*/
function get_total_discount() {
if ($this->discount_total) return woocommerce_price($this->discount_total); else return false;
if ($this->discount_total || $this->discount_product) :
return woocommerce_price($this->discount_total + $this->discount_product);
endif;
return false;
}
/**

View File

@ -745,7 +745,7 @@ class woocommerce_checkout {
update_post_meta( $order_id, '_payment_method', $this->posted['payment_method']);
update_post_meta( $order_id, '_order_subtotal', number_format($woocommerce->cart->subtotal_ex_tax, 2, '.', ''));
update_post_meta( $order_id, '_order_shipping', number_format($woocommerce->cart->shipping_total, 2, '.', ''));
update_post_meta( $order_id, '_order_discount', number_format($woocommerce->cart->discount_total, 2, '.', ''));
update_post_meta( $order_id, '_order_discount', number_format($woocommerce->cart->get_discount_total(), 2, '.', ''));
update_post_meta( $order_id, '_order_tax', number_format($woocommerce->cart->tax_total, 2, '.', ''));
update_post_meta( $order_id, '_order_shipping_tax', number_format($woocommerce->cart->shipping_tax_total, 2, '.', ''));
update_post_meta( $order_id, '_order_total', number_format($woocommerce->cart->total, 2, '.', ''));

View File

@ -20,6 +20,7 @@ class woocommerce_coupon {
var $usage_limit;
var $usage_count;
var $expiry_date;
var $apply_before_tax;
/** get coupon with $code */
function woocommerce_coupon( $code ) {
@ -39,6 +40,7 @@ class woocommerce_coupon {
$this->usage_limit = get_post_meta($coupon->ID, 'usage_limit', true);
$this->usage_count = (int) get_post_meta($coupon->ID, 'usage_count', true);
$this->expiry_date = ($expires = get_post_meta($coupon->ID, 'expiry_date', true)) ? strtotime($expires) : '';
$this->apply_before_tax = get_post_meta($coupon->ID, 'apply_before_tax', true);
if (!$this->amount) return false;
@ -49,6 +51,11 @@ class woocommerce_coupon {
return false;
}
/** Check if coupon needs applying before tax **/
function apply_before_tax() {
if ($this->apply_before_tax=='yes') return true; else return false;
}
/** Increase usage count */
function inc_usage_count() {
$this->usage_count++;

View File

@ -166,7 +166,6 @@ class woocommerce_paypal extends woocommerce_payment_gateway {
'upload' => 1,
'return' => $this->get_return_url( $order ),
'cancel_return' => $order->get_cancel_order_url(),
//'cancel_return' => home_url(),
// Order key
'custom' => $order_id,
@ -189,7 +188,7 @@ class woocommerce_paypal extends woocommerce_payment_gateway {
// Payment Info
'invoice' => $order->order_key,
'tax_cart' => $order->get_total_tax(),
'discount_amount_cart' => $order->order_discount
'discount_amount_cart' => $order->get_total_discount()
),
$phone_args
);

View File

@ -145,11 +145,19 @@ class woocommerce_order {
}
/** Gets shipping and product tax */
function get_total_tax() {
return $this->order_tax + $this->order_shipping_tax;
}
/** Gets total discount */
function get_total_discount() {
return $this->order_discount;
}
/** Gets subtotal */
function get_subtotal_to_display() {
global $woocommerce;

View File

@ -505,7 +505,7 @@ class woocommerce_product {
// Round
$price = round( $price * 100 ) / 100;
// Format
$price = number_format($price, 2, '.', '');

View File

@ -235,21 +235,24 @@ class woocommerce_tax {
*/
function calc_tax( $price, $rate, $price_includes_tax = true ) {
$price = round($price * 100, 0); // To avoid float rounding errors, work with integers (pence)
$price = round($price * 10000, 0); // To avoid float rounding errors, work with integers (pence + 2 dp = 4 decimals)
$rate = $rate * 100;
if ($price_includes_tax) :
$rate = ($rate / 100) + 1;
$rate = ($rate / 10000) + 1;
$tax_amount = $price - ( $price / $rate);
else :
$tax_amount = $price * ($rate/100);
$tax_amount = $price * ($rate/10000);
endif;
$tax_amount = round($tax_amount); // Round to the nearest pence
$tax_amount = $tax_amount / 100; // Back to pounds
$tax_amount = round($tax_amount, 0); // Round to the nearest pence
$tax_amount = $tax_amount / 10000; // Back to pounds
return number_format($tax_amount, 2, '.', '');
return $tax_amount;
//return number_format($tax_amount, 2, '.', '');
}
/**

View File

@ -82,8 +82,11 @@ Yes you can! Join in on our GitHub repository :) https://github.com/woothemes/wo
== Changelog ==
= 1.2.5 - 18/11/2011 =
= 1.3 - 18/11/2011 =
* Schema.org markup for products and reviews
* Option to apply coupons before tax
* Rewritten cart calculations to support coupons before tax and after tax (optional)
* 2 lines of discounts on total tables - 1 for product discounts, 1 for after tax discounts (e.g. store credit)
= 1.2.4 - 18/11/2011 =
* More sale price logic fixes for variations. Now correctly compares variation's prices.

View File

@ -15,6 +15,11 @@
<td><?php echo $woocommerce->cart->get_cart_subtotal(); ?></td>
</tr>
<?php if ($woocommerce->cart->get_discounts_before_tax()) : ?><tr class="discount">
<td colspan="2"><?php _e('Product Discounts', 'woothemes'); ?></td>
<td>-<?php echo $woocommerce->cart->get_discounts_before_tax(); ?></td>
</tr><?php endif; ?>
<?php if ($woocommerce->cart->needs_shipping()) : ?>
<td colspan="2"><?php _e('Shipping', 'woothemes'); ?></td>
<td>
@ -66,10 +71,11 @@
<td><?php echo $woocommerce->cart->get_cart_tax(); ?></td>
</tr><?php endif; ?>
<?php if ($woocommerce->cart->get_total_discount()) : ?><tr class="discount">
<?php if ($woocommerce->cart->get_discounts_after_tax()) : ?><tr class="discount">
<td colspan="2"><?php _e('Discount', 'woothemes'); ?></td>
<td>-<?php echo $woocommerce->cart->get_total_discount(); ?></td>
<td>-<?php echo $woocommerce->cart->get_discounts_after_tax(); ?></td>
</tr><?php endif; ?>
<tr>
<td colspan="2"><strong><?php _e('Grand Total', 'woothemes'); ?></strong></td>
<td><strong><?php echo $woocommerce->cart->get_total(); ?></strong></td>

View File

@ -730,6 +730,11 @@ if (!function_exists('woocommerce_cart_totals')) {
<td><?php echo $woocommerce->cart->get_cart_subtotal(); ?></td>
</tr>
<?php if ($woocommerce->cart->get_discounts_before_tax()) : ?><tr class="discount">
<th><?php _e('Product Discounts', 'woothemes'); ?></th>
<td>-<?php echo $woocommerce->cart->get_discounts_before_tax(); ?></td>
</tr><?php endif; ?>
<?php if ($woocommerce->cart->get_cart_shipping_total()) : ?><tr>
<th><?php _e('Shipping', 'woothemes'); ?> <small><?php echo $woocommerce->countries->shipping_to_prefix().' '.__($woocommerce->countries->countries[ $woocommerce->customer->get_shipping_country() ], 'woothemes'); ?></small></th>
<td>
@ -772,7 +777,7 @@ if (!function_exists('woocommerce_cart_totals')) {
?>
</td>
</tr><?php endif; ?>
<?php if ($woocommerce->cart->get_cart_tax()) : ?><tr>
<th><?php _e('Tax', 'woothemes'); ?> <?php if ($woocommerce->customer->is_customer_outside_base()) : ?><small><?php echo sprintf(__('estimated for %s', 'woothemes'), $woocommerce->countries->estimated_for_prefix() . __($woocommerce->countries->countries[ $woocommerce->countries->get_base_country() ], 'woothemes') ); ?></small><?php endif; ?></th>
<td><?php
@ -780,10 +785,11 @@ if (!function_exists('woocommerce_cart_totals')) {
?></td>
</tr><?php endif; ?>
<?php if ($woocommerce->cart->get_total_discount()) : ?><tr class="discount">
<?php if ($woocommerce->cart->get_discounts_after_tax()) : ?><tr class="discount">
<th><?php _e('Discount', 'woothemes'); ?></th>
<td>-<?php echo $woocommerce->cart->get_total_discount(); ?></td>
<td>-<?php echo $woocommerce->cart->get_discounts_after_tax(); ?></td>
</tr><?php endif; ?>
<tr>
<th><strong><?php _e('Total', 'woothemes'); ?></strong></th>
<td><strong><?php echo $woocommerce->cart->get_total(); ?></strong></td>