Shipping calculation in backend should be based on line items

Fixes #10718
This commit is contained in:
Mike Jolley 2016-04-18 12:56:59 +01:00
parent 8fe7f46855
commit 70d334395d
1 changed files with 55 additions and 31 deletions

View File

@ -1494,6 +1494,7 @@ class WC_AJAX {
$order = wc_get_order( $order_id );
$taxes = array();
$shipping_taxes = array();
$order_item_tax_classes = array();
// Default to base
if ( 'base' === $tax_based_on || empty( $country ) ) {
@ -1526,13 +1527,13 @@ class WC_AJAX {
// Get items and fees taxes
if ( isset( $items['order_item_id'] ) ) {
$line_total = $line_subtotal = $order_item_tax_class = array();
$line_total = $line_subtotal = array();
foreach ( $items['order_item_id'] as $item_id ) {
$item_id = absint( $item_id );
$line_total[ $item_id ] = isset( $items['line_total'][ $item_id ] ) ? wc_format_decimal( $items['line_total'][ $item_id ] ) : 0;
$line_subtotal[ $item_id ] = isset( $items['line_subtotal'][ $item_id ] ) ? wc_format_decimal( $items['line_subtotal'][ $item_id ] ) : $line_total[ $item_id ];
$order_item_tax_class[ $item_id ] = isset( $items['order_item_tax_class'][ $item_id ] ) ? sanitize_text_field( $items['order_item_tax_class'][ $item_id ] ) : '';
$order_item_tax_classes[ $item_id ] = isset( $items['order_item_tax_class'][ $item_id ] ) ? sanitize_text_field( $items['order_item_tax_class'][ $item_id ] ) : '';
$product_id = $order->get_item_meta( $item_id, '_product_id', true );
// Get product details
@ -1543,13 +1544,13 @@ class WC_AJAX {
$item_tax_status = 'taxable';
}
if ( '0' !== $order_item_tax_class[ $item_id ] && 'taxable' === $item_tax_status ) {
if ( '0' !== $order_item_tax_classes[ $item_id ] && 'taxable' === $item_tax_status ) {
$tax_rates = WC_Tax::find_rates( array(
'country' => $country,
'state' => $state,
'postcode' => $postcode,
'city' => $city,
'tax_class' => $order_item_tax_class[ $item_id ]
'tax_class' => $order_item_tax_classes[ $item_id ]
) );
$line_taxes = WC_Tax::calc_tax( $line_total[ $item_id ], $tax_rates, false );
@ -1576,21 +1577,44 @@ class WC_AJAX {
// Get shipping taxes
if ( isset( $items['shipping_method_id'] ) ) {
$matched_tax_rates = array();
$order_item_tax_classes = array_unique( array_values( $order_item_tax_classes ) );
$tax_rates = WC_Tax::find_rates( array(
// If multiple classes are found, use the first one. Don't bother with standard rate, we can get that later.
if ( sizeof( $order_item_tax_classes ) > 1 && ! in_array( '', $order_item_tax_classes ) ) {
$tax_classes = WC_Tax::get_tax_classes();
foreach ( $tax_classes as $tax_class ) {
$tax_class = sanitize_title( $tax_class );
if ( in_array( $tax_class, $order_item_tax_classes ) ) {
$matched_tax_rates = WC_Tax::find_shipping_rates( array(
'country' => $country,
'state' => $state,
'postcode' => $postcode,
'city' => $city,
'tax_class' => ''
'tax_class' => $tax_class,
) );
break;
}
}
// If a single tax class is found, use it
} elseif ( sizeof( $order_item_tax_classes ) === 1 ) {
$matched_tax_rates = WC_Tax::find_shipping_rates( array(
'country' => $country,
'state' => $state,
'postcode' => $postcode,
'city' => $city,
'tax_class' => $order_item_tax_classes[0]
) );
}
if ( $tax_rates ) {
foreach ( $tax_rates as $key => $rate ) {
if ( isset( $rate['shipping'] ) && 'yes' == $rate['shipping'] ) {
$matched_tax_rates[ $key ] = $rate;
}
}
// Get standard rate if no taxes were found
if ( ! sizeof( $matched_tax_rates ) ) {
$matched_tax_rates = WC_Tax::find_shipping_rates( array(
'country' => $country,
'state' => $state,
'postcode' => $postcode,
'city' => $city
) );
}
$shipping_cost = $shipping_taxes = array();