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:
parent
8db66f705f
commit
74de152535
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
Loading…
Reference in New Issue