Use tax location from order while computing tax in discount.

We were not passing tax location while computing discount in orders, hence it was defaulting to shop's base address resulting in incorrect tax calculation.

This commit refactors `get_rates` method into another method that allows getting rates from location directly.
This commit is contained in:
vedanshujain 2020-07-09 01:42:12 +05:30
parent 8db66f705f
commit 74de152535
2 changed files with 27 additions and 4 deletions

View File

@ -1270,6 +1270,8 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
*/ */
protected function set_item_discount_amounts( $discounts ) { protected function set_item_discount_amounts( $discounts ) {
$item_discounts = $discounts->get_discounts_by_item(); $item_discounts = $discounts->get_discounts_by_item();
$tax_location = $this->get_tax_location();
$tax_location = array( $tax_location['country'], $tax_location['state'], $tax_location['postcode'], $tax_location['city'] );
if ( $item_discounts ) { if ( $item_discounts ) {
foreach ( $item_discounts as $item_id => $amount ) { foreach ( $item_discounts as $item_id => $amount ) {
@ -1277,7 +1279,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
// If the prices include tax, discounts should be taken off the tax inclusive prices like in the cart. // If the prices include tax, discounts should be taken off the tax inclusive prices like in the cart.
if ( $this->get_prices_include_tax() && wc_tax_enabled() && 'taxable' === $item->get_tax_status() ) { if ( $this->get_prices_include_tax() && wc_tax_enabled() && 'taxable' === $item->get_tax_status() ) {
$taxes = WC_Tax::calc_tax( $amount, WC_Tax::get_rates( $item->get_tax_class() ), true ); $taxes = WC_Tax::calc_tax( $amount, WC_Tax::get_rates_from_location( $item->get_tax_class(), $tax_location ), true );
// Use unrounded taxes so totals will be re-calculated accurately, like in cart. // Use unrounded taxes so totals will be re-calculated accurately, like in cart.
$amount = $amount - array_sum( $taxes ); $amount = $amount - array_sum( $taxes );
@ -1299,6 +1301,13 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$coupon_code_to_id = wc_list_pluck( $coupons, 'get_id', 'get_code' ); $coupon_code_to_id = wc_list_pluck( $coupons, 'get_id', 'get_code' );
$all_discounts = $discounts->get_discounts(); $all_discounts = $discounts->get_discounts();
$coupon_discounts = $discounts->get_discounts_by_coupon(); $coupon_discounts = $discounts->get_discounts_by_coupon();
$tax_location = $this->get_tax_location();
$tax_location = array(
$tax_location['country'],
$tax_location['state'],
$tax_location['postcode'],
$tax_location['city'],
);
if ( $coupon_discounts ) { if ( $coupon_discounts ) {
foreach ( $coupon_discounts as $coupon_code => $amount ) { foreach ( $coupon_discounts as $coupon_code => $amount ) {
@ -1321,7 +1330,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
continue; continue;
} }
$taxes = array_sum( WC_Tax::calc_tax( $item_discount_amount, WC_Tax::get_rates( $item->get_tax_class() ), $this->get_prices_include_tax() ) ); $taxes = array_sum( WC_Tax::calc_tax( $item_discount_amount, WC_Tax::get_rates_from_location( $item->get_tax_class(), $tax_location ), $this->get_prices_include_tax() ) );
if ( 'yes' !== get_option( 'woocommerce_tax_round_at_subtotal' ) ) { if ( 'yes' !== get_option( 'woocommerce_tax_round_at_subtotal' ) ) {
$taxes = wc_round_tax_total( $taxes ); $taxes = wc_round_tax_total( $taxes );
} }

View File

@ -405,7 +405,7 @@ class WC_Tax {
$criteria_string = implode( ' AND ', $criteria ); $criteria_string = implode( ' AND ', $criteria );
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$found_rates = $wpdb->get_results( $found_rates = $wpdb->get_results(
" "
SELECT tax_rates.*, COUNT( locations.location_id ) as postcode_count, COUNT( locations2.location_id ) as city_count SELECT tax_rates.*, COUNT( locations.location_id ) as postcode_count, COUNT( locations2.location_id ) as city_count
@ -479,8 +479,22 @@ class WC_Tax {
* @return array * @return array
*/ */
public static function get_rates( $tax_class = '', $customer = null ) { public static function get_rates( $tax_class = '', $customer = null ) {
$tax_class = sanitize_title( $tax_class );
$location = self::get_tax_location( $tax_class, $customer );
return self::get_rates_from_location( $tax_class, $location, $customer );
}
/**
* Get's an arrau of matching rates from location and tax class. $customer parameter is used to preserve backward compatibility for filter.
*
* @param string $tax_class Tax class to get rates for.
* @param array $location Location to compute rates for. Should be in form: array( country, state, postcode, city).
* @param object $customer Only used to maintain backward compatibility for filter `woocommerce-matched_rates`.
*
* @return mixed|void
*/
public static function get_rates_from_location( $tax_class, $location, $customer = null ) {
$tax_class = sanitize_title( $tax_class ); $tax_class = sanitize_title( $tax_class );
$location = self::get_tax_location( $tax_class, $customer );
$matched_tax_rates = array(); $matched_tax_rates = array();
if ( count( $location ) === 4 ) { if ( count( $location ) === 4 ) {