Final tax logic fixes

Storing base cost/discounted cost instead of row_discount to keep calks
simple and maintain backwards compatibility.
This commit is contained in:
Mike Jolley 2011-11-30 00:30:25 +00:00
parent 4f9dc2335f
commit 6dc4d2add8
8 changed files with 59 additions and 84 deletions

View File

@ -731,7 +731,7 @@ $woocommerce_settings['tax'] = apply_filters('woocommerce_tax_settings', array(
),
array(
'name' => __( 'Frontend Tax display', 'woothemes' ),
'name' => __( 'Tax display (cart totals)', 'woothemes' ),
'desc' => __( 'Always display cart contents excluding tax', 'woothemes' ),
'id' => 'woocommerce_display_cart_prices_excluding_tax',
'std' => 'yes',

View File

@ -168,8 +168,8 @@ function woocommerce_order_items_meta_box($post) {
<th class="meta" width="1%"><?php _e('Item&nbsp;Meta', 'woothemes'); ?></th>
<?php do_action('woocommerce_admin_order_item_headers'); ?>
<th class="quantity"><?php _e('Quantity', 'woothemes'); ?></th>
<th class="cost"><?php _e('Cost', 'woothemes'); ?> <?php echo $woocommerce->countries->ex_tax_or_vat(); ?></th>
<th class="cost"><?php _e('Row Discount', 'woothemes'); ?></th>
<th class="cost"><?php _e('Base&nbsp;Cost', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Cost before discounts', 'woothemes'); ?> <?php echo $woocommerce->countries->ex_tax_or_vat(); ?>" href="#">[?]</a></th>
<th class="cost"><?php _e('Cost', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Final cost after discount', 'woothemes'); ?> <?php echo $woocommerce->countries->ex_tax_or_vat(); ?>" href="#">[?]</a></th>
<th class="tax"><?php _e('Tax Rate', 'woothemes'); ?></th>
<th class="center" width="1%"><?php _e('Remove', 'woothemes'); ?></th>
</tr>
@ -235,11 +235,11 @@ function woocommerce_order_items_meta_box($post) {
</td>
<td class="cost">
<input type="text" name="item_cost[<?php echo $loop; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" value="<?php echo esc_attr( $item['cost'] ); ?>" />
<input type="text" name="base_item_cost[<?php echo $loop; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" value="<?php if (isset($item['base_cost'])) echo esc_attr( $item['base_cost'] ); else echo esc_attr( $item['cost'] ); ?>" />
</td>
<td class="discount">
<input type="text" name="item_discount[<?php echo $loop; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" value="<?php if (isset($item['row_discount'])) echo esc_attr( $item['row_discount'] ); ?>" />
<td class="cost">
<input type="text" name="item_cost[<?php echo $loop; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" value="<?php echo esc_attr( $item['cost'] ); ?>" />
</td>
<td class="tax">
@ -470,7 +470,7 @@ function woocommerce_process_shop_order_meta( $post_id, $post ) {
$item_name = $_POST['item_name'];
$item_quantity = $_POST['item_quantity'];
$item_cost = $_POST['item_cost'];
$item_discount = $_POST['item_discount'];
$base_item_cost = $_POST['base_item_cost'];
$item_tax_rate = $_POST['item_tax_rate'];
$item_meta_names = $_POST['meta_name'];
$item_meta_values = $_POST['meta_value'];
@ -502,8 +502,8 @@ function woocommerce_process_shop_order_meta( $post_id, $post ) {
'variation_id' => (int) $item_variation[$i],
'name' => htmlspecialchars(stripslashes($item_name[$i])),
'qty' => (int) $item_quantity[$i],
'cost' => woocommerce_clean($item_cost[$i]),
'row_discount' => number_format(woocommerce_clean($item_discount[$i]), 4, '.', ''),
'cost' => number_format(woocommerce_clean($item_cost[$i]), 4, '.', ''),
'base_cost' => number_format(woocommerce_clean($base_item_cost[$i]), 4, '.', ''),
'taxrate' => number_format(woocommerce_clean($item_tax_rate[$i]), 4, '.', ''),
'item_meta' => $item_meta->meta
));

View File

@ -69,75 +69,65 @@ jQuery( function($){
itemCost = $('input[name^=item_cost]:eq(' + i + ')').val();
itemQty = parseInt($('input[name^=item_quantity]:eq(' + i + ')').val());
itemDiscount = $('input[name^=item_discount]:eq(' + i + ')').val();
itemBase = $('input[name^=base_item_cost]:eq(' + i + ')').val();
itemTax = $('input[name^=item_tax_rate]:eq(' + i + ')').val();
if (!itemCost) itemCost = 0;
if (!itemTax) itemTax = 0;
if (!itemQty) itemQty = 0;
if (!itemDiscount) itemDiscount = 0;
if (!itemBase) itemBase = 0;
totalItemTax = 0;
// Calculate tax and discounts
cart_discount = cart_discount + parseFloat( itemDiscount );
if (itemTax && itemTax>0) {
if (woocommerce_writepanel_params.prices_include_tax == 'yes') {
taxRate = ( itemTax/100 ) + 1;
// Discount worked out from tax inc. price then tax worked out backwards
price_in_tax = ( itemCost * taxRate );
itemDiscount = (( itemBase * itemQty ) * taxRate) - (( itemCost * itemQty ) * taxRate);
discounted_price = ( price_in_tax * itemQty ) - itemDiscount;
// Tax worked out backwards
totalItemTax = (itemCost * itemQty) * ( itemTax/100 );
// Total item tax (after discount)
totalItemTax = ( discounted_price - ( discounted_price / taxRate ) );
discounted_price = (itemCost * itemQty) * taxRate;
if (woocommerce_writepanel_params.round_at_subtotal == 'no') {
totalItemTax = totalItemTax * 100;
totalItemTax = totalItemTax.toFixed(2);
totalItemTax = Math.round( totalItemTax ) / 100;
}
discounted_price = discounted_price - totalItemTax;
subtotal = subtotal + parseFloat( (itemCost * itemQty) );
} else {
taxRate = ( itemTax/100 );
// Discount worked out from ex. price and tax worked out forwards
discounted_price = (itemCost * itemQty) - itemDiscount;
totalItemTax = ( discounted_price * taxRate );
itemDiscount = ( itemBase * itemQty ) - ( itemCost * itemQty );
// Tax worked out forwards
totalItemTax = (itemCost * itemQty) * taxRate;
discounted_price = (itemCost * itemQty) + totalItemTax;
if (woocommerce_writepanel_params.round_at_subtotal == 'no') {
totalItemTax = totalItemTax * 100;
totalItemTax = totalItemTax.toFixed(2);
totalItemTax = Math.round( totalItemTax ) / 100;
}
subtotal = subtotal + parseFloat( (itemCost * itemQty) );
}
} else {
discounted_price = (itemCost * itemQty ) - itemDiscount;
subtotal = subtotal + parseFloat( (itemCost*itemQty) );
itemDiscount = ( itemBase * itemQty ) - ( itemCost * itemQty );
discounted_price = ( itemCost * itemQty );
}
subtotal = subtotal + parseFloat( (itemBase * itemQty) );
cart_discount = cart_discount + parseFloat( itemDiscount );
totalItemCost = parseFloat( discounted_price );
itemTotal = itemTotal + parseFloat( totalItemCost );
@ -155,7 +145,7 @@ jQuery( function($){
}
total = parseFloat(itemTotal) + parseFloat(tax) - parseFloat(discount) + parseFloat(shipping) + parseFloat(shipping_tax);
total = parseFloat(itemTotal) - parseFloat(discount) + parseFloat(shipping) + parseFloat(shipping_tax);
// Rounding
subtotal = subtotal * 100;

File diff suppressed because one or more lines are too long

View File

@ -686,15 +686,20 @@ class woocommerce_checkout {
endforeach;
endif;
// Calculate discounted price ex. vat
if (get_option('woocommerce_prices_include_tax')=='yes') :
$cost = $woocommerce->cart->get_discounted_price( $values, $_product->get_price() ) / (($rate/100) + 1);
else :
$cost = $woocommerce->cart->get_discounted_price( $values, $_product->get_price() );
endif;
$order_items[] = apply_filters('new_order_item', array(
'id' => $values['product_id'],
'variation_id' => $values['variation_id'],
'name' => $_product->get_title(),
'qty' => (int) $values['quantity'],
'cost' => $_product->get_price_excluding_tax( false ),
'row_discount' => number_format(
( ( $_product->get_price()-$woocommerce->cart->get_discounted_price( $values, $_product->get_price() ) ) * $values['quantity'] )
, 4, '.', '' ),
'base_cost' => $_product->get_price_excluding_tax( false ),
'cost' => trim(trim(number_format($cost, 4, '.', ''), '0'), '.'),
'taxrate' => $rate,
'item_meta' => $item_meta->meta
), $values);

View File

@ -190,37 +190,19 @@ class woocommerce_order {
/** Calculate item cost - useful for gateways */
function get_item_cost( $item, $inc_tax = false ) {
if ($inc_tax) :
if ($this->prices_include_tax) :
return number_format( ($item['cost'] * (1 + ($item['taxrate']/100)) - ( $item['row_discount'] / $item['qty'] )) , 2, '.', '');
else :
return number_format( ($item['cost'] - ( $item['row_discount'] / $item['qty'] )) * (1 + ($item['taxrate']/100)) , 2, '.', '');
endif;
return number_format( $item['cost'] * (1 + ($item['taxrate']/100)) , 2, '.', '');
else :
return number_format( $item['cost'] - ( $item['row_discount'] / $item['qty'] ) );
return number_format( $item['cost'] , 2, '.', '');
endif;
}
/** Calculate row cost - useful for gateways */
function get_row_cost( $item, $inc_tax = false ) {
if ($inc_tax) :
if ($this->prices_include_tax) :
return number_format( ( ($item['cost'] * $item['qty']) * (1 + ($item['taxrate']/100)) - $item['row_discount'] ) , 2, '.', '');
else :
return number_format( (($item['cost'] * $item['qty']) - $item['row_discount']) * (1 + ($item['taxrate']/100)) , 2, '.', '');
endif;
return number_format( ($item['cost'] * $item['qty']) * (1 + ($item['taxrate']/100)) , 2, '.', '');
else :
return number_format( (($item['cost'] * $item['qty']) - $item['row_discount']) );
return number_format( $item['cost'] * $item['qty'] , 2, '.', '');
endif;
}
@ -244,7 +226,9 @@ class woocommerce_order {
foreach ($this->items as $item) :
$subtotal += round(($item['cost']*$item['qty']) * (($item['taxrate']/100) + 1), 2);
if (!isset($item['base_cost'])) $item['base_cost'] = $item['cost'];
$subtotal += round(($item['base_cost']*$item['qty']) * (($item['taxrate']/100) + 1), 2);
endforeach;
@ -383,16 +367,14 @@ class woocommerce_order {
<td style="text-align:left;">'.$item['qty'].'</td>
<td style="text-align:left;">';
if ($this->display_cart_ex_tax || !$this->prices_include_tax) :
if ($this->prices_include_tax) $ex_tax_label = 1; else $ex_tax_label = 0;
$return .= woocommerce_price( $item['cost']*$item['qty'], array('ex_tax_label' => $ex_tax_label ));
else :
$return .= woocommerce_price( round(($item['cost']*$item['qty']) * (($item['taxrate']/100) + 1), 2) );
endif;
if (!isset($item['base_cost'])) $item['base_cost'] = $item['cost'];
if ($this->display_cart_ex_tax || !$this->prices_include_tax) :
if ($this->prices_include_tax) $ex_tax_label = 1; else $ex_tax_label = 0;
$return .= woocommerce_price( $item['base_cost']*$item['qty'], array('ex_tax_label' => $ex_tax_label ));
else :
$return .= woocommerce_price( round(($item['base_cost']*$item['qty']) * (($item['taxrate']/100) + 1), 2) );
endif;
$return .= '
</td>

View File

@ -280,8 +280,8 @@ function woocommerce_add_order_item() {
</td>
<?php do_action('woocommerce_admin_order_item_values', $_product); ?>
<td class="quantity"><input type="text" name="item_quantity[<?php echo $index; ?>]" placeholder="<?php _e('0', 'woothemes'); ?>" value="1" /></td>
<td class="cost"><input type="text" name="base_item_cost[<?php echo $index; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" value="<?php echo esc_attr( $_product->get_price_excluding_tax( false ) ); ?>" /></td>
<td class="cost"><input type="text" name="item_cost[<?php echo $index; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" value="<?php echo esc_attr( $_product->get_price_excluding_tax( false ) ); ?>" /></td>
<td class="discount"><input type="text" name="item_discount[<?php echo $index; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" /></td>
<td class="tax"><input type="text" name="item_tax_rate[<?php echo $index; ?>]" placeholder="<?php _e('0.0000', 'woothemes'); ?>" value="<?php echo esc_attr( $_product->get_tax_base_rate() ); ?>" /></td>
<td class="center">
<input type="hidden" name="item_id[<?php echo $index; ?>]" value="<?php echo esc_attr( $_product->id ); ?>" />

View File

@ -1323,16 +1323,14 @@ function woocommerce_order_details_table( $order_id ) {
echo ' </td>
<td>'.$item['qty'].'</td>
<td>';
if (!isset($item['base_cost'])) $item['base_cost'] = $item['cost'];
if ($order->display_cart_ex_tax || !$order->prices_include_tax) :
if ($order->display_cart_ex_tax || !$order->prices_include_tax) :
if ($order->prices_include_tax) $ex_tax_label = 1; else $ex_tax_label = 0;
echo woocommerce_price( $item['cost']*$item['qty'], array('ex_tax_label' => $ex_tax_label ));
echo woocommerce_price( $item['base_cost']*$item['qty'], array('ex_tax_label' => $ex_tax_label ));
else :
echo woocommerce_price( round(($item['cost']*$item['qty']) * (($item['taxrate']/100) + 1), 2) );
echo woocommerce_price( round(($item['base_cost']*$item['qty']) * (($item['taxrate']/100) + 1), 2) );
endif;
echo '</td>