Fixes, subtotals, some backwards compat

This commit is contained in:
Mike Jolley 2012-01-04 23:01:47 +00:00
parent fb5bb626e8
commit a3f633e3a3
11 changed files with 184 additions and 213 deletions

View File

@ -166,16 +166,18 @@ function woocommerce_order_items_meta_box($post) {
<?php do_action('woocommerce_admin_order_item_headers'); ?> <?php do_action('woocommerce_admin_order_item_headers'); ?>
<th class="cost"><?php _e('Unit&nbsp;Cost', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Unit cost before discounts', 'woothemes'); ?> <?php echo $woocommerce->countries->ex_tax_or_vat(); ?>." href="#">[?]</a></th> <th class="cost"><?php _e('Unit&nbsp;Cost', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Unit cost before discounts', 'woothemes'); ?> <?php echo $woocommerce->countries->ex_tax_or_vat(); ?>." href="#">[?]</a></th>
<th class="tax"><?php _e('Unit&nbsp;Tax', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Unit tax before discounts', 'woothemes'); ?>." href="#">[?]</a></th>
<th class="tax_status"><?php _e('Taxable', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Whether the item is taxable or not', 'woothemes'); ?>." href="#">[?]</a></th> <th class="tax_status"><?php _e('Taxable', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Whether the item is taxable or not', 'woothemes'); ?>." href="#">[?]</a></th>
<th class="tax_class"><?php _e('Tax&nbsp;Class', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('The items tax class for this order', 'woothemes'); ?>." href="#">[?]</a></th> <th class="tax_class"><?php _e('Tax&nbsp;Class', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('The items tax class for this order', 'woothemes'); ?>." href="#">[?]</a></th>
<th class="quantity"><?php _e('Quantity', 'woothemes'); ?></th> <th class="quantity"><?php _e('Quantity', 'woothemes'); ?></th>
<th class="cost"><?php _e('Line&nbsp;Cost', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Line cost after discount', 'woothemes'); ?> <?php echo $woocommerce->countries->ex_tax_or_vat(); ?>." href="#">[?]</a></th> <th class="line_cost"><?php _e('Line&nbsp;Cost', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Line cost after discount', 'woothemes'); ?> <?php echo $woocommerce->countries->ex_tax_or_vat(); ?>." href="#">[?]</a></th>
<th class="tax"><?php _e('Line&nbsp;Tax', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Line tax after discount', 'woothemes'); ?>." href="#">[?]</a></th> <th class="line_tax"><?php _e('Line&nbsp;Tax', 'woothemes'); ?>&nbsp;<a class="tips" tip="<?php _e('Line tax after discount', 'woothemes'); ?>." href="#">[?]</a></th>
</tr> </tr>
</thead> </thead>
@ -189,10 +191,11 @@ function woocommerce_order_items_meta_box($post) {
$_product = &new woocommerce_product( $item['id'] ); $_product = &new woocommerce_product( $item['id'] );
endif; endif;
// Totals // Totals - Backwards Compatibility
if (!isset($item['line_cost']) && isset($item['taxrate']) && isset($item['cost'])) : if (!isset($item['line_cost']) && isset($item['taxrate']) && isset($item['cost'])) :
$item['line_tax'] = number_format(($item['cost'] * $item['qty'])*($item['taxrate']/100), 2, '.', ''); $item['line_tax'] = number_format(($item['cost'] * $item['qty'])*($item['taxrate']/100), 2, '.', '');
$item['line_cost'] = ($item['cost'] * $item['qty']); $item['line_cost'] = ($item['cost'] * $item['qty']);
$item['base_tax'] = number_format( $item['cost'] * ($item['taxrate']/100), 4, '.', '');
endif; endif;
?> ?>
@ -255,6 +258,10 @@ function woocommerce_order_items_meta_box($post) {
<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'] ); ?>" /> <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'] ); ?>" />
</td> </td>
<td class="tax">
<input type="text" name="base_item_tax[<?php echo $loop; ?>]" placeholder="<?php _e('0.00', 'woothemes'); ?>" value="<?php if (isset($item['base_tax'])) echo esc_attr( $item['base_tax'] ); ?>" />
</td>
<td class="tax_status"> <td class="tax_status">
<select name="item_tax_status[<?php echo $loop; ?>]"> <select name="item_tax_status[<?php echo $loop; ?>]">
<?php <?php
@ -595,6 +602,7 @@ function woocommerce_process_shop_order_meta( $post_id, $post ) {
$item_quantity = $_POST['item_quantity']; $item_quantity = $_POST['item_quantity'];
$item_line_cost = $_POST['line_cost']; $item_line_cost = $_POST['line_cost'];
$base_item_cost = $_POST['base_item_cost']; $base_item_cost = $_POST['base_item_cost'];
$base_item_tax = $_POST['base_item_tax'];
$item_line_tax = $_POST['line_tax']; $item_line_tax = $_POST['line_tax'];
$item_meta_names = (isset($_POST['meta_name'])) ? $_POST['meta_name'] : ''; $item_meta_names = (isset($_POST['meta_name'])) ? $_POST['meta_name'] : '';
$item_meta_values = (isset($_POST['meta_value'])) ? $_POST['meta_value'] : ''; $item_meta_values = (isset($_POST['meta_value'])) ? $_POST['meta_value'] : '';
@ -633,6 +641,7 @@ function woocommerce_process_shop_order_meta( $post_id, $post ) {
'qty' => (int) $item_quantity[$i], 'qty' => (int) $item_quantity[$i],
'line_cost' => rtrim(rtrim(number_format(woocommerce_clean($item_line_cost[$i]), 4, '.', ''), '0'), '.'), 'line_cost' => rtrim(rtrim(number_format(woocommerce_clean($item_line_cost[$i]), 4, '.', ''), '0'), '.'),
'base_cost' => rtrim(rtrim(number_format(woocommerce_clean($base_item_cost[$i]), 4, '.', ''), '0'), '.'), 'base_cost' => rtrim(rtrim(number_format(woocommerce_clean($base_item_cost[$i]), 4, '.', ''), '0'), '.'),
'base_tax' => rtrim(rtrim(number_format(woocommerce_clean($base_item_tax[$i]), 4, '.', ''), '0'), '.'),
'line_tax' => rtrim(rtrim(number_format(woocommerce_clean($item_line_tax[$i]), 4, '.', ''), '0'), '.'), 'line_tax' => rtrim(rtrim(number_format(woocommerce_clean($item_line_tax[$i]), 4, '.', ''), '0'), '.'),
'item_meta' => $item_meta->meta, 'item_meta' => $item_meta->meta,
'tax_status' => woocommerce_clean($item_tax_status[$i]), 'tax_status' => woocommerce_clean($item_tax_status[$i]),

View File

@ -975,7 +975,10 @@ function woocommerce_top_earners() {
foreach ($orders as $order) : foreach ($orders as $order) :
$order_items = (array) get_post_meta( $order->ID, '_order_items', true ); $order_items = (array) get_post_meta( $order->ID, '_order_items', true );
foreach ($order_items as $item) : foreach ($order_items as $item) :
$found_products[$item['id']] = isset($found_products[$item['id']]) ? $found_products[$item['id']] + ($item['qty'] + $item['cost']) : ($item['qty'] + $item['cost']); if (isset($item['line_cost'])) $row_cost = $item['line_cost'];
else $row_cost = $item['cost'] * $item['qty'];
$found_products[$item['id']] = isset($found_products[$item['id']]) ? $found_products[$item['id']] + $row_cost : $row_cost;
endforeach; endforeach;
endforeach; endforeach;
endif; endif;
@ -1079,7 +1082,11 @@ function woocommerce_product_sales() {
foreach ($order_items as $item) : foreach ($order_items as $item) :
if ($item['id']!=$chosen_product_id && !in_array($item['id'], $child_ids)) continue; if ($item['id']!=$chosen_product_id && !in_array($item['id'], $child_ids)) continue;
$product_sales[$date] = isset($product_sales[$date]) ? $product_sales[$date] + $item['qty'] : $item['qty']; $product_sales[$date] = isset($product_sales[$date]) ? $product_sales[$date] + $item['qty'] : $item['qty'];
$product_totals[$date] = isset($product_totals[$date]) ? $product_totals[$date] + ($item['qty'] * $item['cost']) : ($item['qty'] * $item['cost']);
if (isset($item['line_cost'])) $row_cost = $item['line_cost'];
else $row_cost = $item['cost'] * $item['qty'];
$product_totals[$date] = isset($product_totals[$date]) ? $product_totals[$date] + $row_cost : $row_cost;
if ($product_sales[$date] > $max_sales) $max_sales = $product_sales[$date]; if ($product_sales[$date] > $max_sales) $max_sales = $product_sales[$date];
if ($product_totals[$date] > $max_totals) $max_totals = $product_totals[$date]; if ($product_totals[$date] > $max_totals) $max_totals = $product_totals[$date];

View File

@ -118,7 +118,7 @@ class woocommerce_cart {
*/ */
function empty_cart() { function empty_cart() {
$this->cart_contents = array(); $this->cart_contents = array();
$this->reset_totals(); $this->reset();
unset($_SESSION['cart']); unset($_SESSION['cart']);
unset($_SESSION['coupons']); unset($_SESSION['coupons']);
} }
@ -437,7 +437,7 @@ class woocommerce_cart {
/** /**
* Reset totals * Reset totals
*/ */
private function reset_totals() { private function reset() {
$this->total = 0; $this->total = 0;
$this->cart_contents_total = 0; $this->cart_contents_total = 0;
$this->cart_contents_weight = 0; $this->cart_contents_weight = 0;
@ -692,7 +692,7 @@ class woocommerce_cart {
function calculate_totals() { function calculate_totals() {
global $woocommerce; global $woocommerce;
$this->reset_totals(); $this->reset();
do_action('woocommerce_before_calculate_totals', $this); do_action('woocommerce_before_calculate_totals', $this);
// Get count of all items + weights + subtotal (we may need this for discounts) // Get count of all items + weights + subtotal (we may need this for discounts)
if (sizeof($this->cart_contents)>0) foreach ($this->cart_contents as $cart_item_key => $values) : if (sizeof($this->cart_contents)>0) foreach ($this->cart_contents as $cart_item_key => $values) :
@ -703,7 +703,7 @@ class woocommerce_cart {
$this->cart_contents_count = $this->cart_contents_count + $values['quantity']; $this->cart_contents_count = $this->cart_contents_count + $values['quantity'];
// Base Price (inlusive of tax for now) // Base Price (inlusive of tax for now)
$base_price = $_product->get_price(); $row_base_price = $_product->get_price() * $values['quantity'];
$base_tax_rates = $this->tax->get_shop_base_rate( $_product->tax_class ); $base_tax_rates = $this->tax->get_shop_base_rate( $_product->tax_class );
$tax_amount = 0; $tax_amount = 0;
@ -715,34 +715,34 @@ class woocommerce_cart {
// ADJUST BASE if tax rate is different (different region or modified tax class) // ADJUST BASE if tax rate is different (different region or modified tax class)
if ( $tax_rates !== $base_tax_rates ) : if ( $tax_rates !== $base_tax_rates ) :
$base_taxes = $this->tax->calc_tax( $base_price, $base_tax_rates, true ); $base_taxes = $this->tax->calc_tax( $row_base_price, $base_tax_rates, true );
$modded_taxes = $this->tax->calc_tax( $base_price - array_sum($base_taxes), $tax_rates, false ); $modded_taxes = $this->tax->calc_tax( $row_base_price - array_sum($base_taxes), $tax_rates, false );
$base_price = ($base_price - array_sum($base_taxes)) + array_sum($modded_taxes); $row_base_price = ($row_base_price - array_sum($base_taxes)) + array_sum($modded_taxes);
endif; endif;
$taxes = $this->tax->calc_tax( $base_price * $values['quantity'], $tax_rates, true ); $taxes = $this->tax->calc_tax( $row_base_price, $tax_rates, true );
$tax_amount = $this->tax->get_tax_total($taxes); $tax_amount = $this->tax->get_tax_total($taxes);
endif; endif;
// Sub total is based on base prices (without discounts) // Sub total is based on base prices (without discounts)
$this->subtotal = $this->subtotal + ( $base_price * $values['quantity'] ); $this->subtotal = $this->subtotal + $row_base_price;
$this->subtotal_ex_tax = $this->subtotal_ex_tax + ( ( $base_price * $values['quantity'] ) - $tax_amount); $this->subtotal_ex_tax = $this->subtotal_ex_tax + ( $row_base_price - $tax_amount);
else : else :
if ( $_product->is_taxable() ) : if ( $_product->is_taxable() ) :
$tax_rates = $this->tax->get_rates( $_product->get_tax_class() ); $tax_rates = $this->tax->get_rates( $_product->get_tax_class() );
$taxes = $this->tax->calc_tax( $base_price * $values['quantity'], $tax_rates, false ); $taxes = $this->tax->calc_tax( $row_base_price, $tax_rates, false );
$tax_amount = $this->tax->get_tax_total($taxes); $tax_amount = $this->tax->get_tax_total($taxes);
endif; endif;
// Sub total is based on base prices (without discounts) // Sub total is based on base prices (without discounts)
$this->subtotal = $this->subtotal + ( $base_price * $values['quantity'] ) + $tax_amount; $this->subtotal = $this->subtotal + $row_base_price + $tax_amount;
$this->subtotal_ex_tax = $this->subtotal_ex_tax + ($base_price * $values['quantity']); $this->subtotal_ex_tax = $this->subtotal_ex_tax + $row_base_price;
endif; endif;
@ -781,10 +781,7 @@ class woocommerce_cart {
// Get rates // Get rates
$tax_rates = $this->tax->get_rates( $_product->get_tax_class() ); $tax_rates = $this->tax->get_rates( $_product->get_tax_class() );
// Get tax rate for the store base, ensuring we use the unmodified tax_class for the product
$base_tax_rates = $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 * ADJUST TAX - Checkout calculations when customer is OUTSIDE the shop base country and prices INCLUDE tax
* OR * OR
@ -792,11 +789,18 @@ class woocommerce_cart {
*/ */
if ( ( $woocommerce->customer->is_customer_outside_base() && defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT) || ($_product->get_tax_class() !== $_product->tax_class) ) : if ( ( $woocommerce->customer->is_customer_outside_base() && defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT) || ($_product->get_tax_class() !== $_product->tax_class) ) :
// Get tax rate for the store base, ensuring we use the unmodified tax_class for the product
$base_tax_rates = $this->tax->get_shop_base_rate( $_product->tax_class );
// Work out new price based on region // Work out new price based on region
$base_taxes = $this->tax->calc_tax( $base_price, $base_tax_rates, true ); $row_base_price = $base_price * $values['quantity'];
$modded_taxes = $this->tax->calc_tax( $base_price - array_sum($base_taxes), $tax_rates, false ); $base_taxes = $this->tax->calc_tax( $row_base_price, $base_tax_rates, true );
$adjusted_price = ( $base_price - array_sum($base_taxes) ) + array_sum($modded_taxes); $modded_taxes = $this->tax->calc_tax( $row_base_price - array_sum($base_taxes), $tax_rates, false );
$adjusted_price = ($row_base_price - array_sum($base_taxes) + array_sum($modded_taxes)) / $values['quantity'];
// Calc base tax (for a single unit) - we will store this in the order data
$base_tax = array_sum($modded_taxes) / $values['quantity'];
// Apply discounts // Apply discounts
$discounted_price = $this->get_discounted_price( $values, $adjusted_price, true ); $discounted_price = $this->get_discounted_price( $values, $adjusted_price, true );
@ -808,6 +812,10 @@ class woocommerce_cart {
*/ */
else : else :
// Calc base tax (for a single unit) - we will store this in the order data
$base_tax = array_sum($this->tax->calc_tax( $base_price, $tax_rates, true ));
// Calc prices and tax (discounted)
$discounted_price = $this->get_discounted_price( $values, $base_price, true ); $discounted_price = $this->get_discounted_price( $values, $base_price, true );
$discounted_taxes = $this->tax->calc_tax( $discounted_price * $values['quantity'], $tax_rates, true ); $discounted_taxes = $this->tax->calc_tax( $discounted_price * $values['quantity'], $tax_rates, true );
$discounted_tax_amount = $this->tax->get_tax_total($discounted_taxes); // Sum taxes - round also to prevent rounding errors $discounted_tax_amount = $this->tax->get_tax_total($discounted_taxes); // Sum taxes - round also to prevent rounding errors
@ -824,17 +832,25 @@ class woocommerce_cart {
// Discounted Price (price with any pre-tax discounts applied) // Discounted Price (price with any pre-tax discounts applied)
$discounted_price = $this->get_discounted_price( $values, $base_price, true ); $discounted_price = $this->get_discounted_price( $values, $base_price, true );
$discounted_tax_amount = 0; $discounted_tax_amount = 0;
$base_tax = 0;
endif; endif;
// Total item price (price, discount and quantity) - round tax so price is correctly calculated // Lines prices - round tax so price is correctly calculated
$total_item_price = ($discounted_price * $values['quantity']) - round($discounted_tax_amount, 2); $line_tax = round($discounted_tax_amount, 2);
$line_cost = ($discounted_price * $values['quantity']) - $line_tax;
// Add any product discounts (after tax) // Add any product discounts (after tax)
$this->apply_product_discounts_after_tax( $values, $total_item_price + $discounted_tax_amount ); $this->apply_product_discounts_after_tax( $values, $line_cost + $discounted_tax_amount );
// Cart contents total is based on discounted prices and is used for the final total calculation // Cart contents total is based on discounted prices and is used for the final total calculation
$this->cart_contents_total = $this->cart_contents_total + $total_item_price; $this->cart_contents_total = $this->cart_contents_total + $line_cost;
// Store unit/line cost + tax
$this->cart_contents[$cart_item_key]['line_cost'] = $line_cost;
$this->cart_contents[$cart_item_key]['line_tax'] = $line_tax;
$this->cart_contents[$cart_item_key]['base_cost'] = $_product->get_price_excluding_tax( false );
$this->cart_contents[$cart_item_key]['base_tax'] = $base_tax;
endforeach; endif; endforeach; endif;
@ -858,8 +874,13 @@ class woocommerce_cart {
// Tax Amount (For the line, based on discounted, ex.tax price) // Tax Amount (For the line, based on discounted, ex.tax price)
if ( $_product->is_taxable() ) : if ( $_product->is_taxable() ) :
// Now calc product rates // Get tax rates
$tax_rates = $this->tax->get_rates( $_product->get_tax_class() ); $tax_rates = $this->tax->get_rates( $_product->get_tax_class() );
// Calc base tax (for a single unit) - we will store this in the order data
$base_tax = array_sum($this->tax->calc_tax( $base_price, $tax_rates, false ));
// Now calc product rates
$discounted_taxes = $this->tax->calc_tax( $discounted_price * $values['quantity'], $tax_rates, false ); $discounted_taxes = $this->tax->calc_tax( $discounted_price * $values['quantity'], $tax_rates, false );
$discounted_tax_amount = array_sum( $discounted_taxes ); $discounted_tax_amount = array_sum( $discounted_taxes );
@ -869,17 +890,25 @@ class woocommerce_cart {
} }
else : else :
$discounted_tax_amount = 0; $discounted_tax_amount = 0;
$base_tax = 0;
endif; endif;
// Total item price (price, discount and quantity) // Lines prices
$total_item_price = $discounted_price * $values['quantity']; $line_tax = $discounted_tax_amount;
$line_cost = $discounted_price * $values['quantity'];
// Add any product discounts (after tax) // Add any product discounts (after tax)
$this->apply_product_discounts_after_tax( $values, $total_item_price + $discounted_tax_amount ); $this->apply_product_discounts_after_tax( $values, $line_cost + $line_tax );
// Cart contents total is based on discounted prices and is used for the final total calculation // Cart contents total is based on discounted prices and is used for the final total calculation
$this->cart_contents_total = $this->cart_contents_total + $total_item_price; $this->cart_contents_total = $this->cart_contents_total + $line_cost;
// Store unit, line cost + tax
$this->cart_contents[$cart_item_key]['line_cost'] = $line_cost;
$this->cart_contents[$cart_item_key]['line_tax'] = $line_tax;
$this->cart_contents[$cart_item_key]['base_cost'] = $_product->get_price();
$this->cart_contents[$cart_item_key]['base_tax'] = $base_tax;
endforeach; endif; endforeach; endif;
@ -1229,7 +1258,9 @@ class woocommerce_cart {
$row_price = (( $price * $quantity ) - array_sum( $base_taxes )) + array_sum( $modded_taxes ); $row_price = (( $price * $quantity ) - array_sum( $base_taxes )) + array_sum( $modded_taxes );
$return = woocommerce_price( $row_price ); $return = woocommerce_price( $row_price );
$return .= ' <small class="tax_label">'.$woocommerce->countries->inc_tax_or_vat().'</small>'; if (!$this->prices_include_tax) :
$return .= ' <small class="tax_label">'.$woocommerce->countries->inc_tax_or_vat().'</small>';
endif;
else : else :

View File

@ -382,27 +382,6 @@ class woocommerce_checkout {
foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) : foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) :
$_product = $values['data']; $_product = $values['data'];
// Get the line tax and the line cost excluding tax
$line_tax = 0;
$line_cost = $woocommerce->cart->get_discounted_price( $values, $_product->get_price() ) * $values['quantity'];
// Calc item tax to store if taxable
if ( $_product->is_taxable()) :
$tax_rates = $_tax->get_rates( $_product->get_tax_class() );
if ($woocommerce->cart->prices_include_tax) :
$line_taxes = $woocommerce->cart->tax->calc_tax( $line_cost, $tax_rates, true );
else :
$line_taxes = $woocommerce->cart->tax->calc_tax( $line_cost, $tax_rates, false );
endif;
$line_tax = $_tax->get_tax_total( $line_taxes );
if ($woocommerce->cart->prices_include_tax) $line_cost = $line_cost - $line_tax;
endif;
// Store any item meta data - item meta class lets plugins add item meta in a standardized way // Store any item meta data - item meta class lets plugins add item meta in a standardized way
$item_meta = &new order_item_meta(); $item_meta = &new order_item_meta();
@ -417,16 +396,17 @@ class woocommerce_checkout {
endif; endif;
$order_items[] = apply_filters('new_order_item', array( $order_items[] = apply_filters('new_order_item', array(
'id' => $values['product_id'], 'id' => $values['product_id'],
'variation_id' => $values['variation_id'], 'variation_id' => $values['variation_id'],
'name' => $_product->get_title(), 'name' => $_product->get_title(),
'qty' => (int) $values['quantity'], 'qty' => (int) $values['quantity'],
'item_meta' => $item_meta->meta, 'item_meta' => $item_meta->meta,
'base_cost' => $_product->get_price_excluding_tax(), // Base price 'base_tax' => number_format($values['base_tax'], 2, '.', ''), // Base tax (unit, before discounts)
'line_cost' => number_format($line_cost, 2, '.', ''), // Discounted line cost 'base_cost' => number_format($values['base_cost'], 2, '.', ''), // Base price (unit, before discounts)
'line_tax' => number_format($line_tax, 2, '.', ''), // Tax for the line (total) 'line_cost' => number_format($values['line_cost'], 2, '.', ''), // Discounted line cost
'tax_status' => $_product->get_tax_status(), // Taxble, shipping, none 'line_tax' => number_format($values['line_tax'], 2, '.', ''), // Tax for the line (total)
'tax_class' => $_product->get_tax_class() // Tax class (adjusted by filters) 'tax_status' => $_product->get_tax_status(), // Taxble, shipping, none
'tax_class' => $_product->get_tax_class() // Tax class (adjusted by filters)
), $values); ), $values);
// Check cart items for errors // Check cart items for errors

View File

@ -229,13 +229,13 @@ class woocommerce_paypal extends woocommerce_payment_gateway {
// Don't pass items - paypal borks tax due to prices including tax. PayPal has no option for tax inclusive pricing sadly. Pass 1 item for the order items overall // Don't pass items - paypal borks tax due to prices including tax. PayPal has no option for tax inclusive pricing sadly. Pass 1 item for the order items overall
$paypal_args['item_name_1'] = sprintf(__('Order #%s' , 'woothemes'), $order->id); $paypal_args['item_name_1'] = sprintf(__('Order #%s' , 'woothemes'), $order->id);
$paypal_args['quantity_1'] = 1; $paypal_args['quantity_1'] = 1;
$paypal_args['amount_1'] = number_format($order->order_total - $order->order_shipping - $order->get_total_tax() + $order->get_order_discount(), 2, '.', ''); $paypal_args['amount_1'] = number_format($order->get_order_total() - $order->get_shipping() - $order->get_total_tax() + $order->get_order_discount(), 2, '.', '');
// Shipping Cost // Shipping Cost
if ($order->order_shipping>0) : if ($order->get_shipping()>0) :
$paypal_args['item_name_2'] = __('Shipping cost', 'woothemes'); $paypal_args['item_name_2'] = __('Shipping cost', 'woothemes');
$paypal_args['quantity_2'] = '1'; $paypal_args['quantity_2'] = '1';
$paypal_args['amount_2'] = number_format($order->order_shipping, 2); $paypal_args['amount_2'] = number_format($order->get_shipping(), 2, '.', '');
endif; endif;
else : else :
@ -259,17 +259,17 @@ class woocommerce_paypal extends woocommerce_payment_gateway {
$paypal_args['item_name_'.$item_loop] = $item_name; $paypal_args['item_name_'.$item_loop] = $item_name;
$paypal_args['quantity_'.$item_loop] = $item['qty']; $paypal_args['quantity_'.$item_loop] = $item['qty'];
$paypal_args['amount_'.$item_loop] = number_format($item['cost'], 2, '.', ''); $paypal_args['amount_'.$item_loop] = $order->get_item_cost( $item, false );
endif; endif;
endforeach; endif; endforeach; endif;
// Shipping Cost // Shipping Cost
if ($order->order_shipping>0) : if ($order->get_shipping()>0) :
$item_loop++; $item_loop++;
$paypal_args['item_name_'.$item_loop] = __('Shipping cost', 'woothemes'); $paypal_args['item_name_'.$item_loop] = __('Shipping cost', 'woothemes');
$paypal_args['quantity_'.$item_loop] = '1'; $paypal_args['quantity_'.$item_loop] = '1';
$paypal_args['amount_'.$item_loop] = number_format($order->order_shipping, 2); $paypal_args['amount_'.$item_loop] = number_format($order->get_shipping(), 2, '.', '');
endif; endif;
endif; endif;

View File

@ -89,7 +89,6 @@ class woocommerce_order {
'shipping_method_title' => '', 'shipping_method_title' => '',
'payment_method' => '', 'payment_method' => '',
'payment_method_title' => '', 'payment_method_title' => '',
'order_subtotal' => '',
'order_discount' => '', 'order_discount' => '',
'cart_discount' => '', 'cart_discount' => '',
'order_tax' => '', 'order_tax' => '',
@ -219,54 +218,71 @@ class woocommerce_order {
endif; endif;
} }
/** Gets product subtotal - subtotal is shown before discounts, but with localised taxes */
function get_item_subtotal( $item ) {
$subtotal = 0;
if (!isset($item['base_cost']) || !isset($item['base_tax'])) return;
if ($this->display_cart_ex_tax || !$this->prices_include_tax) :
if ($this->prices_include_tax) $ex_tax_label = 1; else $ex_tax_label = 0;
$subtotal = woocommerce_price( $item['base_cost'] * $item['qty'], array('ex_tax_label' => $ex_tax_label ));
else :
$subtotal = woocommerce_price( ($item['base_cost'] + $item['base_tax']) * $item['qty'] );
endif;
return $subtotal;
}
/** Gets subtotal */ /** Gets subtotal - subtotal is shown before discounts, but with localised taxes */
function get_subtotal_to_display( $compound = false ) { function get_subtotal_to_display( $compound = false ) {
global $woocommerce; global $woocommerce;
$subtotal = 0; $subtotal = 0;
foreach ($this->items as $item) : if ( !$compound ) :
$subtotal += $item['base_cost'] * $item['qty']; foreach ($this->items as $item) :
endforeach; if (!isset($item['base_cost']) || !isset($item['base_tax'])) return;
// If showing compound taxes subtotal, add shipping + non-compound taxes $subtotal += $item['base_cost'] * $item['qty'];
if ($compound && is_array($this->taxes)) :
if (!$this->display_cart_ex_tax) :
$subtotal += $item['base_tax'] * $item['qty'];
endif;
endforeach;
$subtotal = woocommerce_price($subtotal);
if ($this->display_cart_ex_tax && $this->prices_include_tax) :
$subtotal .= ' <small>'.$woocommerce->countries->ex_tax_or_vat().'</small>';
endif;
else :
if ($this->prices_include_tax) return;
foreach ($this->items as $item) :
$subtotal += $item['base_cost'];
endforeach;
// Add Shipping Costs
$subtotal += $this->get_shipping(); $subtotal += $this->get_shipping();
// Remove non-compound taxes
foreach ($this->taxes as $tax) : foreach ($this->taxes as $tax) :
if (isset($tax['compound']) && $tax['compound']) continue; if (isset($tax['compound']) && $tax['compound']) continue;
$subtotal += $tax['total']; $subtotal = $subtotal + $tax['total'];
endforeach; endforeach;
$subtotal = woocommerce_price($subtotal); $subtotal = woocommerce_price($subtotal);
// If this is the cart subtotal, and we want to display prices inc tax, add it
elseif (!$this->display_totals_ex_tax && $this->prices_include_tax) :
// Add tax to subtotal
$subtotal += $this->order_tax;
$subtotal = woocommerce_price($subtotal);
if ($this->order_tax>0 && !$this->prices_include_tax) :
$subtotal .= ' <small>'.$woocommerce->countries->inc_tax_or_vat().'</small>';
endif;
else :
$subtotal = woocommerce_price($subtotal);
if ($this->order_tax>0 && $this->prices_include_tax) :
$subtotal .= ' <small>'.$woocommerce->countries->ex_tax_or_vat().'</small>';
endif;
endif; endif;
return $subtotal; return $subtotal;
@ -320,12 +336,13 @@ class woocommerce_order {
} }
/** Get totals for display in emails */ /** Get totals for display on pages and in emails */
function get_order_item_totals() { function get_order_item_totals() {
$total_rows = array(); $total_rows = array();
$total_rows[ __('Cart Subtotal:', 'woothemes') ] = $this->get_subtotal_to_display(); if ($subtotal = $this->get_subtotal_to_display())
$total_rows[ __('Cart Subtotal:', 'woothemes') ] = $subtotal;
if ($this->get_cart_discount() > 0) if ($this->get_cart_discount() > 0)
$total_rows[ __('Cart Discount:', 'woothemes') ] = woocommerce_price($this->get_cart_discount()); $total_rows[ __('Cart Discount:', 'woothemes') ] = woocommerce_price($this->get_cart_discount());
@ -344,7 +361,9 @@ class woocommerce_order {
endforeach; endforeach;
if ($has_compound_tax) : if ($has_compound_tax) :
if ($subtotal = $this->get_subtotal_to_display( true )) :
$total_rows[ __('Subtotal:', 'woothemes') ] = $subtotal;
endif;
endif; endif;
foreach ($this->taxes as $tax) : if (!$tax['compound']) continue; foreach ($this->taxes as $tax) : if (!$tax['compound']) continue;

View File

@ -500,14 +500,14 @@ class woocommerce_product {
$_tax = &new woocommerce_tax(); $_tax = &new woocommerce_tax();
$tax_rates = $_tax->get_rates( $this->tax_class ); $tax_rates = $_tax->get_shop_base_rate( $this->tax_class );
$taxes = $_tax->calc_tax( $price, $tax_rates, true ); $taxes = $_tax->calc_tax( $price, $tax_rates, true );
$tax_amount = $_tax->get_tax_total( $taxes );
if ($round) : if ($round) :
$tax_amount = $_tax->get_tax_total( $taxes );
$price = round( $price - $tax_amount, 2); $price = round( $price - $tax_amount, 2);
else : else :
$tax_amount = array_sum( $taxes );
$price = $price - $tax_amount; $price = $price - $tax_amount;
endif; endif;

View File

@ -107,7 +107,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
endforeach; endforeach;
if ($has_compound_tax) : if ($has_compound_tax && !$woocommerce->cart->prices_include_tax) :
?> ?>
<tr class="order-subtotal"> <tr class="order-subtotal">
<th><strong><?php _e('Subtotal', 'woothemes'); ?></strong></th> <th><strong><?php _e('Subtotal', 'woothemes'); ?></strong></th>

View File

@ -10,26 +10,16 @@
</tr> </tr>
</thead> </thead>
<tfoot> <tfoot>
<tr> <?php
<td colspan="2"><?php _e('Subtotal', 'woothemes'); ?></td> if ($totals = $order->get_order_item_totals()) foreach ($totals as $label => $value) :
<td><?php echo $order->get_subtotal_to_display(); ?></td> ?>
</tr> <tr>
<?php if ($order->order_shipping>0) : ?><tr> <th scope="row" colspan="2"><?php echo $label; ?></th>
<td colspan="2"><?php _e('Shipping', 'woothemes'); ?></td> <td><?php echo $value; ?></td>
<td><?php echo $order->get_shipping_to_display(); ?></small></td> </tr>
</tr><?php endif; ?> <?php
<?php if ($order->get_total_tax()>0) : ?><tr> endforeach;
<td colspan="2"><?php _e('Tax', 'woothemes'); ?></td> ?>
<td><?php echo woocommerce_price($order->get_total_tax()); ?></td>
</tr><?php endif; ?>
<?php if ($order->order_discount>0) : ?><tr class="discount">
<td colspan="2"><?php _e('Discount', 'woothemes'); ?></td>
<td>-<?php echo woocommerce_price($order->order_discount); ?></td>
</tr><?php endif; ?>
<tr>
<td colspan="2"><strong><?php _e('Grand Total', 'woothemes'); ?></strong></td>
<td><strong><?php echo woocommerce_price($order->order_total); ?></strong></td>
</tr>
</tfoot> </tfoot>
<tbody> <tbody>
<?php <?php
@ -39,7 +29,7 @@
<tr> <tr>
<td>'.$item['name'].'</td> <td>'.$item['name'].'</td>
<td>'.$item['qty'].'</td> <td>'.$item['qty'].'</td>
<td>'.woocommerce_price( $item['cost']*$item['qty'] ).'</td> <td>' . $order->get_item_subtotal($item) . '</td>
</tr>'; </tr>';
endforeach; endforeach;
endif; endif;

View File

@ -108,7 +108,7 @@
endforeach; endforeach;
if ($has_compound_tax) : if ($has_compound_tax && !$woocommerce->cart->prices_include_tax) :
?> ?>
<tr class="order-subtotal"> <tr class="order-subtotal">
<th colspan="2"><strong><?php _e('Order Subtotal', 'woothemes'); ?></strong></th> <th colspan="2"><strong><?php _e('Order Subtotal', 'woothemes'); ?></strong></th>

View File

@ -17,70 +17,16 @@ $order = &new woocommerce_order( $order_id );
</tr> </tr>
</thead> </thead>
<tfoot> <tfoot>
<tr> <?php
<th scope="row" colspan="2"><?php _e('Cart Subtotal:', 'woothemes'); ?></th> if ($totals = $order->get_order_item_totals()) foreach ($totals as $label => $value) :
<td><strong><?php echo $order->get_subtotal_to_display(); ?></strong></td> ?>
</tr> <tr>
<?php if ($order->get_cart_discount() > 0) : ?><tr> <th scope="row" colspan="2"><?php echo $label; ?></th>
<th scope="row" colspan="2"><?php _e('Cart Discount:', 'woothemes'); ?></th> <td><?php echo $value; ?></td>
<td><?php echo woocommerce_price($order->get_cart_discount()); ?></td> </tr>
</tr><?php endif; ?> <?php
<?php if ($order->get_shipping() > 0) : ?><tr> endforeach;
<th scope="row" colspan="2"><?php _e('Shipping:', 'woothemes'); ?></th> ?>
<td><?php echo $order->get_shipping_to_display(); ?></td>
</tr><?php endif; ?>
<?php if ($order->get_total_tax() > 0) : ?>
<?php if (is_array($order->taxes) && sizeof($order->taxes)>0) : $has_compound_tax = false; ?>
<?php foreach ($order->taxes as $tax) : if (isset($tax['compound']) && $tax['compound']) : $has_compound_tax = true; continue; endif; ?>
<tr>
<th scope="row" colspan="2"><?php echo $tax['label']; ?></th>
<td><?php echo woocommerce_price( $tax['total'] ); ?></td>
</tr>
<?php endforeach; ?>
<?php if ($has_compound_tax) : ?>
<tr>
<th scope="row" colspan="2"><?php _e('Subtotal:', 'woothemes'); ?></th>
<td><strong><?php echo $order->get_subtotal_to_display( true ); ?></strong></td>
</tr>
<?php foreach ($order->taxes as $tax) : if (!$tax['compound']) continue; ?>
<tr>
<th scope="row" colspan="2"><?php echo $tax['label']; ?></th>
<td><?php echo woocommerce_price( $tax['total'] ); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php else : ?>
<tr>
<th scope="row" colspan="2"><?php echo $woocommerce->countries->tax_or_vat(); ?></th>
<td><?php echo woocommerce_price($order->get_total_tax()); ?></td>
</tr>
<?php endif; ?>
<?php endif; ?>
<?php if ($order->get_order_discount() > 0) : ?><tr>
<th scope="row" colspan="2"><?php _e('Order Discount:', 'woothemes'); ?></th>
<td><?php echo woocommerce_price($order->get_order_discount()); ?></td>
</tr><?php endif; ?>
<tr>
<th scope="row" colspan="2"><?php _e('Order Total:', 'woothemes'); ?></th>
<td><strong><?php echo woocommerce_price($order->get_order_total()); ?></strong></td>
</tr>
<?php if ($order->customer_note) : ?>
<tr>
<td><?php _e('Note:', 'woothemes'); ?></td>
<td colspan="2"><?php echo wpautop(wptexturize($order->customer_note)); ?></td>
</tr>
<?php endif; ?>
</tfoot> </tfoot>
<tbody> <tbody>
<?php <?php
@ -107,19 +53,8 @@ $order = &new woocommerce_order( $order_id );
endif; endif;
echo ' </td> echo '</td><td>'.$item['qty'].'</td><td>' . $order->get_item_subtotal($item) . '</td></tr>';
<td>'.$item['qty'].'</td>
<td>';
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( $order->get_row_cost( $item, false ), array('ex_tax_label' => $ex_tax_label ));
else :
echo woocommerce_price( $order->get_row_cost( $item, true ) );
endif;
echo '</td>
</tr>';
endforeach; endforeach;
endif; endif;
?> ?>