Final tax rounding issues
This commit is contained in:
parent
788744bcb1
commit
f7b4bebacc
|
@ -80,7 +80,7 @@ jQuery( function($){
|
|||
totalItemTax = 0;
|
||||
|
||||
// Calculate tax and discounts
|
||||
cart_discount = parseFloat( cart_discount + itemDiscount );
|
||||
cart_discount = cart_discount + parseFloat( itemDiscount );
|
||||
|
||||
if (itemTax && itemTax>0) {
|
||||
|
||||
|
@ -89,30 +89,43 @@ jQuery( function($){
|
|||
taxRate = ( itemTax/100 ) + 1;
|
||||
|
||||
// Discount worked out from tax inc. price then tax worked out backwards
|
||||
price_in_tax = ( itemCost * taxRate ) * itemQty;
|
||||
price_in_tax = ( itemCost * taxRate );
|
||||
|
||||
discounted_price = price_in_tax - itemDiscount;
|
||||
discounted_price = ( price_in_tax * itemQty ) - itemDiscount;
|
||||
|
||||
totalItemTax = ( discounted_price - ( discounted_price / taxRate ) ) * 100;
|
||||
// Total item tax (after discount)
|
||||
totalItemTax = ( discounted_price - ( discounted_price / taxRate ) );
|
||||
|
||||
totalItemTax = totalItemTax.toFixed(2);
|
||||
if (woocommerce_writepanel_params.round_at_subtotal == 'no') {
|
||||
|
||||
totalItemTax = totalItemTax * 100;
|
||||
totalItemTax = totalItemTax.toFixed(2);
|
||||
totalItemTax = Math.round( totalItemTax ) / 100;
|
||||
|
||||
totalItemTax = Math.round( totalItemTax ) / 100;
|
||||
}
|
||||
|
||||
discounted_price = discounted_price - totalItemTax;
|
||||
|
||||
subtotal = subtotal + parseFloat( price_in_tax - ( Math.round( (itemCost*(itemTax/100))*100 ) / 100 ) * itemQty );
|
||||
|
||||
} else {
|
||||
|
||||
taxRate = ( itemTax/100 );
|
||||
|
||||
// Discount worked out from ex. price and tax worked out forwards
|
||||
discounted_price = ( itemCost * taxRate ) - itemDiscount;
|
||||
discounted_price = (itemCost * itemQty) - itemDiscount;
|
||||
|
||||
totalItemTax = ( discounted_price * taxRate ) * 100;
|
||||
totalItemTax = ( discounted_price * taxRate );
|
||||
|
||||
totalItemTax = totalItemTax.toFixed(2);
|
||||
if (woocommerce_writepanel_params.round_at_subtotal == 'no') {
|
||||
|
||||
totalItemTax = totalItemTax * 100;
|
||||
totalItemTax = totalItemTax.toFixed(2);
|
||||
totalItemTax = Math.round( totalItemTax ) / 100;
|
||||
|
||||
totalItemTax = Math.round( totalItemTax ) / 100;
|
||||
}
|
||||
|
||||
subtotal = subtotal + parseFloat( (itemCost * itemQty) );
|
||||
|
||||
}
|
||||
|
||||
|
@ -121,18 +134,27 @@ jQuery( function($){
|
|||
|
||||
discounted_price = (itemCost * itemQty ) - itemDiscount;
|
||||
|
||||
subtotal = subtotal + parseFloat( (itemCost*itemQty) );
|
||||
|
||||
}
|
||||
|
||||
totalItemCost = parseFloat( discounted_price );
|
||||
|
||||
itemTotal = parseFloat( itemTotal + totalItemCost );
|
||||
|
||||
subtotal = parseFloat( subtotal + (itemCost*itemQty) );
|
||||
itemTotal = itemTotal + parseFloat( totalItemCost );
|
||||
|
||||
tax = parseFloat( tax + totalItemTax );
|
||||
tax = tax + parseFloat( totalItemTax );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (woocommerce_writepanel_params.round_at_subtotal == 'yes') {
|
||||
|
||||
tax = tax * 100;
|
||||
tax = tax.toFixed(2);
|
||||
tax = Math.round( tax ) / 100;
|
||||
|
||||
}
|
||||
|
||||
total = parseFloat(itemTotal) + parseFloat(tax) - parseFloat(discount) + parseFloat(shipping) + parseFloat(shipping_tax);
|
||||
|
||||
if (total < 0 ) total = 0;
|
||||
|
@ -197,18 +219,116 @@ jQuery( function($){
|
|||
return false;
|
||||
});
|
||||
|
||||
$('button.load_customer_billing').live('click', function(){
|
||||
|
||||
var answer = confirm(woocommerce_writepanel_params.load_billing);
|
||||
if (answer){
|
||||
|
||||
// Get user ID to load data for
|
||||
var user_id = $('#customer_user').val();
|
||||
|
||||
if (!user_id) {
|
||||
alert(woocommerce_writepanel_params.no_customer_selected);
|
||||
return false;
|
||||
}
|
||||
|
||||
var data = {
|
||||
user_id: user_id,
|
||||
type_to_load: 'billing',
|
||||
action: 'woocommerce_get_customer_details',
|
||||
security: woocommerce_writepanel_params.get_customer_details_nonce
|
||||
};
|
||||
|
||||
$(this).closest('.edit_address').block({ message: null, overlayCSS: { background: '#fff url(' + woocommerce_writepanel_params.plugin_url + '/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
|
||||
|
||||
$.ajax({
|
||||
url: woocommerce_writepanel_params.ajax_url,
|
||||
data: data,
|
||||
type: 'POST',
|
||||
success: function( response ) {
|
||||
var info = jQuery.parseJSON(response);
|
||||
|
||||
if (info) {
|
||||
$('input#_billing_first_name').val( info.billing_first_name );
|
||||
$('input#_billing_last_name').val( info.billing_last_name );
|
||||
$('input#_billing_company').val( info.billing_company );
|
||||
$('input#_billing_address_1').val( info.billing_address_1 );
|
||||
$('input#_billing_address_2').val( info.billing_address_2 );
|
||||
$('input#_billing_city').val( info.billing_city );
|
||||
$('input#_billing_postcode').val( info.billing_postcode );
|
||||
$('input#_billing_country').val( info.billing_country );
|
||||
$('input#_billing_state').val( info.billing_state );
|
||||
$('input#_billing_email').val( info.billing_email );
|
||||
$('input#_billing_phone').val( info.billing_phone );
|
||||
}
|
||||
|
||||
$('.edit_address').unblock();
|
||||
}
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$('button.load_customer_shipping').live('click', function(){
|
||||
|
||||
var answer = confirm(woocommerce_writepanel_params.load_shipping);
|
||||
if (answer){
|
||||
|
||||
// Get user ID to load data for
|
||||
var user_id = $('#customer_user').val();
|
||||
|
||||
if (!user_id) {
|
||||
alert(woocommerce_writepanel_params.no_customer_selected);
|
||||
return false;
|
||||
}
|
||||
|
||||
var data = {
|
||||
user_id: user_id,
|
||||
type_to_load: 'shipping',
|
||||
action: 'woocommerce_get_customer_details',
|
||||
security: woocommerce_writepanel_params.get_customer_details_nonce
|
||||
};
|
||||
|
||||
$(this).closest('.edit_address').block({ message: null, overlayCSS: { background: '#fff url(' + woocommerce_writepanel_params.plugin_url + '/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
|
||||
|
||||
$.ajax({
|
||||
url: woocommerce_writepanel_params.ajax_url,
|
||||
data: data,
|
||||
type: 'POST',
|
||||
success: function( response ) {
|
||||
var info = jQuery.parseJSON(response);
|
||||
|
||||
if (info) {
|
||||
$('input#_shipping_first_name').val( info.shipping_first_name );
|
||||
$('input#_shipping_last_name').val( info.shipping_last_name );
|
||||
$('input#_shipping_company').val( info.shipping_company );
|
||||
$('input#_shipping_address_1').val( info.shipping_address_1 );
|
||||
$('input#_shipping_address_2').val( info.shipping_address_2 );
|
||||
$('input#_shipping_city').val( info.shipping_city );
|
||||
$('input#_shipping_postcode').val( info.shipping_postcode );
|
||||
$('input#_shipping_country').val( info.shipping_country );
|
||||
$('input#_shipping_state').val( info.shipping_state );
|
||||
}
|
||||
|
||||
$('.edit_address').unblock();
|
||||
}
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$('button.billing-same-as-shipping').live('click', function(){
|
||||
var answer = confirm(woocommerce_writepanel_params.copy_billing);
|
||||
if (answer){
|
||||
$('input#shipping_first_name').val( $('input#billing_first_name').val() );
|
||||
$('input#shipping_last_name').val( $('input#billing_last_name').val() );
|
||||
$('input#shipping_company').val( $('input#billing_company').val() );
|
||||
$('input#shipping_address_1').val( $('input#billing_address_1').val() );
|
||||
$('input#shipping_address_2').val( $('input#billing_address_2').val() );
|
||||
$('input#shipping_city').val( $('input#billing_city').val() );
|
||||
$('input#shipping_postcode').val( $('input#billing_postcode').val() );
|
||||
$('input#shipping_country').val( $('input#billing_country').val() );
|
||||
$('input#shipping_state').val( $('input#billing_state').val() );
|
||||
$('input#_shipping_first_name').val( $('input#_billing_first_name').val() );
|
||||
$('input#_shipping_last_name').val( $('input#_billing_last_name').val() );
|
||||
$('input#_shipping_company').val( $('input#_billing_company').val() );
|
||||
$('input#_shipping_address_1').val( $('input#_billing_address_1').val() );
|
||||
$('input#_shipping_address_2').val( $('input#_billing_address_2').val() );
|
||||
$('input#_shipping_city').val( $('input#_billing_city').val() );
|
||||
$('input#_shipping_postcode').val( $('input#_billing_postcode').val() );
|
||||
$('input#_shipping_country').val( $('input#_billing_country').val() );
|
||||
$('input#_shipping_state').val( $('input#_billing_state').val() );
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -573,37 +573,47 @@ class woocommerce_cart {
|
|||
|
||||
// Base Price (inlusive of tax for now)
|
||||
$base_price = $_product->get_price();
|
||||
$tax_rate = $this->tax->get_shop_base_rate( $_product->tax_class );
|
||||
$tax_amount = 0;
|
||||
|
||||
if ($this->prices_include_tax) :
|
||||
|
||||
if ( get_option('woocommerce_calc_taxes')=='yes' && $_product->is_taxable() ) :
|
||||
|
||||
$tax_rate = $this->tax->get_shop_base_rate( $_product->get_tax_class() );
|
||||
$tax_amount = $this->tax->calc_tax( $base_price * $values['quantity'], $tax_rate, true );
|
||||
$rate = $this->tax->get_rate( $_product->get_tax_class() );
|
||||
|
||||
// Rounding
|
||||
// ADJUST BASE if tax rate is different (different region or modified tax class)
|
||||
if ( $tax_rate !== $rate ) :
|
||||
|
||||
$base_price = ( $base_price / ( 1 + ( $tax_rate / 100 ) ) ) * ( 1 + ( $rate / 100 ) );
|
||||
|
||||
endif;
|
||||
|
||||
$tax_amount = $this->tax->calc_tax( $base_price * $values['quantity'], $rate, true );
|
||||
|
||||
/*// Rounding
|
||||
if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' ) :
|
||||
$tax_amount = round( $tax_amount, 2 );
|
||||
endif;
|
||||
endif;*/
|
||||
|
||||
endif;
|
||||
|
||||
// Sub total is based on base prices (without discounts)
|
||||
$this->subtotal = $this->subtotal + ( $base_price * $values['quantity'] );
|
||||
$this->subtotal_ex_tax = $this->subtotal_ex_tax + ( $base_price * $values['quantity'] ) - round($tax_amount, 2);
|
||||
//$this->subtotal_ex_tax = $this->subtotal_ex_tax + ( $base_price * $values['quantity'] ) - round($tax_amount, 2);
|
||||
$this->subtotal_ex_tax = $this->subtotal_ex_tax + ( ( $base_price * $values['quantity'] ) - $tax_amount);
|
||||
|
||||
else :
|
||||
|
||||
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 * $values['quantity'], $tax_rate, false );
|
||||
$rate = $this->tax->get_rate( $_product->get_tax_class() );
|
||||
$tax_amount = $this->tax->calc_tax( $base_price * $values['quantity'], $rate, false );
|
||||
|
||||
// Rounding
|
||||
/*// Rounding
|
||||
if ( get_option( 'woocommerce_tax_round_at_subtotal' ) == 'no' ) :
|
||||
$tax_amount = round( $tax_amount, 2 );
|
||||
endif;
|
||||
endif;*/
|
||||
|
||||
endif;
|
||||
|
||||
|
@ -646,13 +656,15 @@ class woocommerce_cart {
|
|||
// Base Price Adjustment
|
||||
if ( get_option('woocommerce_calc_taxes')=='yes' && $_product->is_taxable() ) :
|
||||
|
||||
// Get tax rate for base - we will handle customer's outside base later
|
||||
$tax_rate = $this->tax->get_shop_base_rate( $_product->get_tax_class() );
|
||||
// Get tax rate for the store base, ensuring we use the unmodified tax_clas for the product
|
||||
$tax_rate = $this->tax->get_shop_base_rate( $_product->tax_class );
|
||||
|
||||
/**
|
||||
* ADJUST TAX - Checkout calculations when customer is OUTSIDE the shop base country and prices INCLUDE tax
|
||||
* OR
|
||||
* ADJUST TAX - Checkout calculations when a tax class is modified
|
||||
*/
|
||||
if ( $woocommerce->customer->is_customer_outside_base() && defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT ) :
|
||||
if ( ( $woocommerce->customer->is_customer_outside_base() && defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT) || ($_product->get_tax_class() !== $_product->tax_class) ) :
|
||||
|
||||
// Get rate
|
||||
$rate = $this->tax->get_rate( $_product->get_tax_class() );
|
||||
|
@ -664,27 +676,6 @@ class woocommerce_cart {
|
|||
$discounted_price = $this->get_discounted_price( $values, $adjusted_price, true );
|
||||
|
||||
$discounted_tax_amount = $this->tax->calc_tax( $discounted_price * $values['quantity'], $rate, true );
|
||||
|
||||
//$discounted_price = ( $discounted_price / ( 1 + ( $tax_rate / 100 ) ) ) * ( 1 + ( $rate / 100 ) );
|
||||
//$discounted_tax_amount = $this->tax->calc_tax( $discounted_price * $values['quantity'], $rate, true );
|
||||
|
||||
/**
|
||||
* ADJUST TAX - Checkout calculations when a tax class is modified
|
||||
*/
|
||||
elseif ( $_product->get_tax_class() !== $_product->tax_class ) :
|
||||
|
||||
// Get rate
|
||||
$rate = $this->tax->get_rate( $_product->tax_class );
|
||||
|
||||
// Work out new price based on tax class
|
||||
$adjusted_price = ( $base_price / ( 1 + ( $tax_rate / 100 ) ) ) * ( 1 + ( $rate / 100 ) );
|
||||
|
||||
// Apply discounts
|
||||
$discounted_price = $this->get_discounted_price( $values, $adjusted_price, true );
|
||||
$discounted_tax_amount = $this->tax->calc_tax( $discounted_price * $values['quantity'], $rate, true );
|
||||
|
||||
//$discounted_price = ( $discounted_price / ( 1 + ( $tax_rate / 100 ) ) ) * ( 1 + ( $rate / 100 ) );
|
||||
//$discounted_tax_amount = $this->tax->calc_tax( $discounted_price * $values['quantity'], $rate, true );
|
||||
|
||||
/**
|
||||
* Regular tax calculation (customer inside base and the tax class is unmodified
|
||||
|
@ -705,8 +696,7 @@ class woocommerce_cart {
|
|||
|
||||
// Discounted Price (price with any pre-tax discounts applied)
|
||||
$discounted_price = $this->get_discounted_price( $values, $base_price, true );
|
||||
|
||||
$discounted_tax_amount = 0;
|
||||
$discounted_tax_amount = 0;
|
||||
|
||||
endif;
|
||||
|
||||
|
@ -1074,19 +1064,45 @@ class woocommerce_cart {
|
|||
/**
|
||||
* Get the product row subtotal
|
||||
*
|
||||
* Gets the tax etc to avoid rounding issues
|
||||
* Gets the tax etc to avoid rounding issues.
|
||||
*
|
||||
* When on the checkout (review order), this will get the subtotal based on the customer's tax rate rather than the base rate
|
||||
*/
|
||||
function get_product_subtotal( $price, $tax_rate, $quantity ) {
|
||||
function get_product_subtotal( $_product, $quantity ) {
|
||||
global $woocommerce;
|
||||
|
||||
if ( get_option('woocommerce_calc_taxes')=='yes' && $tax_rate>0 && (get_option('woocommerce_display_cart_prices_excluding_tax')=='yes' && $this->prices_include_tax) ) :
|
||||
|
||||
$tax_amount = $this->tax->calc_tax( $price * $quantity, $tax_rate, true );
|
||||
$row_price = ( $price * $quantity ) - round($tax_amount, 2);
|
||||
|
||||
$return = woocommerce_price( $row_price );
|
||||
$return .= ' <small class="tax_label">'.$woocommerce->countries->ex_tax_or_vat().'</small>';
|
||||
|
||||
$price = $_product->get_price();
|
||||
$taxable = $_product->is_taxable();
|
||||
$base_tax_rate = $this->tax->get_shop_base_rate( $_product->tax_class );
|
||||
$tax_rate = $this->tax->get_rate( $_product->get_tax_class() ); // This will get the base rate unless we're on the checkout page
|
||||
|
||||
// Taxable
|
||||
if ( $taxable && get_option('woocommerce_calc_taxes')=='yes' ) :
|
||||
|
||||
if ( $this->display_totals_ex_tax && $this->prices_include_tax ) :
|
||||
|
||||
$base_tax_amount = $this->tax->calc_tax( $price * $quantity, $base_tax_rate, true );
|
||||
//$row_price = ( $price * $quantity ) - round($base_tax_amount, 2); // does show 9.99 price rounded correct at 20%, but not when 0% vat modified rate
|
||||
$row_price = ( $price * $quantity ) - $base_tax_amount;
|
||||
|
||||
$return = woocommerce_price( $row_price );
|
||||
$return .= ' <small class="tax_label">'.$woocommerce->countries->ex_tax_or_vat().'</small>';
|
||||
|
||||
elseif ( !$this->display_totals_ex_tax && $base_tax_rate !== $tax_rate && $this->prices_include_tax ) :
|
||||
|
||||
$row_price = ( ( $price * $quantity ) / ( 1 + ( $base_tax_rate / 100 ) ) ) * ( 1 + ( $tax_rate / 100 ) );
|
||||
|
||||
$return = woocommerce_price( $row_price );
|
||||
$return .= ' <small class="tax_label">'.$woocommerce->countries->inc_tax_or_vat( $tax_rate ).'</small>';
|
||||
|
||||
else :
|
||||
|
||||
$row_price = $price * $quantity;
|
||||
$return = woocommerce_price( $row_price );
|
||||
|
||||
endif;
|
||||
|
||||
// Non taxable
|
||||
else :
|
||||
|
||||
$row_price = $price * $quantity;
|
||||
|
|
|
@ -592,12 +592,18 @@ class woocommerce_countries {
|
|||
return apply_filters('woocommerce_countries_tax_or_vat', $return);
|
||||
}
|
||||
|
||||
function inc_tax_or_vat() {
|
||||
function inc_tax_or_vat( $rate = false ) {
|
||||
global $woocommerce;
|
||||
|
||||
$return = ( in_array($this->get_base_country(), $this->get_european_union_countries()) ) ? __('(inc. VAT)', 'woothemes') : __('(inc. tax)', 'woothemes');
|
||||
if ( $rate > 0 || $rate == 0 ) :
|
||||
$rate = trim(trim($rate, '0'), '.');
|
||||
if (!$rate) $rate = 0;
|
||||
$return = ( in_array($this->get_base_country(), $this->get_european_union_countries()) ) ? sprintf(__('(inc. %s%% VAT)', 'woothemes'), $rate) : sprintf(__('(inc. %s%% tax)', 'woothemes'), $rate);
|
||||
else :
|
||||
$return = ( in_array($this->get_base_country(), $this->get_european_union_countries()) ) ? __('(inc. VAT)', 'woothemes') : __('(inc. tax)', 'woothemes');
|
||||
endif;
|
||||
|
||||
return apply_filters('woocommerce_countries_inc_tax_or_vat', $return);
|
||||
return apply_filters('woocommerce_countries_inc_tax_or_vat', $return, $rate);
|
||||
}
|
||||
|
||||
function ex_tax_or_vat() {
|
||||
|
|
|
@ -133,8 +133,8 @@ function woocommerce_cart( $atts ) {
|
|||
<td class="product-quantity"><div class="quantity"><input name="cart[<?php echo $cart_item_key; ?>][qty]" value="<?php echo esc_attr( $values['quantity'] ); ?>" size="4" title="Qty" class="input-text qty text" maxlength="12" /></div></td>
|
||||
<td class="product-subtotal"><?php
|
||||
|
||||
if ($_product->is_taxable()) $rate = $woocommerce->cart->tax->get_shop_base_rate( $_product->get_tax_class() ); else $rate = 0;
|
||||
echo $woocommerce->cart->get_product_subtotal( $_product->get_price(), $rate, $values['quantity'] );
|
||||
echo $woocommerce->cart->get_product_subtotal( $_product, $values['quantity'] ) ;
|
||||
|
||||
?></td>
|
||||
</tr>
|
||||
<?php
|
||||
|
|
|
@ -91,12 +91,7 @@
|
|||
<tr>
|
||||
<td class="product-name">'.$_product->get_title().$woocommerce->cart->get_item_data( $values ).'</td>
|
||||
<td>'.$values['quantity'].'</td>
|
||||
<td>';
|
||||
|
||||
if ($_product->is_taxable()) $rate = $woocommerce->cart->tax->get_shop_base_rate( $_product->get_tax_class() ); else $rate = 0;
|
||||
echo $woocommerce->cart->get_product_subtotal( $_product->get_price(), $rate, $values['quantity'] );
|
||||
|
||||
echo '</td>
|
||||
<td>' . $woocommerce->cart->get_product_subtotal( $_product, $values['quantity'] ) . '</td>
|
||||
</tr>';
|
||||
endif;
|
||||
endforeach;
|
||||
|
|
Loading…
Reference in New Issue