skip to Main Content

I’m currently building a custom form. In this form I want to display the country select which is already present at the checkout.

This is my tax settings list:

enter image description here

This is my code:

<select class="country-select">
    <?php
    foreach ( WC_Tax::get_rates() as $rate ) {
        echo '<option value="' . $rate->tax_rate . '">' . $rate->country . '</option>';
    }
    ?>
</select>

I’m expecting following options:

<option value="19">Deutschland</option>
<option value="20">Österreich</option>

The problem is that I don’t get any results back from the get_rates() function. I’ve found no function which can return me the correct rates. Do you have any idea how I can get this done?

2

Answers


  1. If you’ve got tax rates configured, it’s possible that they don’t cover whatever user you’re logged in as.

    Try feeding the $tax_class, and $customer arguments to your WC_Tax::get_rates method! Specifically a customer and tax class that the Deutschland and/or Österreich rates from your example apply to!

    Review the actual function definition here:

    <?php
    
    // class-wc-tax.php
    
    class WC_Tax {
    // ...
        /**
         * Get's an array of matching rates for a tax class.
         *
         * @param string $tax_class Tax class to get rates for.
         * @param object $customer Override the customer object to get their location.
         * @return  array
         */
        public static function get_rates( $tax_class = '', $customer = null ) {
            $tax_class         = sanitize_title( $tax_class );
            $location          = self::get_tax_location( $tax_class, $customer );
            $matched_tax_rates = array();
    
            if ( count( $location ) === 4 ) {
                list( $country, $state, $postcode, $city ) = $location;
    
                $matched_tax_rates = self::find_rates(
                    array(
                        'country'   => $country,
                        'state'     => $state,
                        'postcode'  => $postcode,
                        'city'      => $city,
                        'tax_class' => $tax_class,
                    )
                );
            }
    
            return apply_filters( 'woocommerce_matched_rates', $matched_tax_rates, $tax_class );
        }
    }
    
    Login or Signup to reply.
  2. TL;DR

    $all_tax_rates = [];
    $tax_classes = WC_Tax::get_tax_classes(); // Retrieve all tax classes.
    if ( !in_array( '', $tax_classes ) ) { // Make sure "Standard rate" (empty class name) is present.
        array_unshift( $tax_classes, '' );
    }
    foreach ( $tax_classes as $tax_class ) { // For each tax class, get all rates.
        $taxes = WC_Tax::get_rates_for_tax_class( $tax_class );
        $all_tax_rates = array_merge( $all_tax_rates, $taxes );
    }
    

    Explanation:

    As far as I know, you can only get a list of all tax rates given a specific tax_class, which is used to filter woocommerce_tax_rates table by tax_rate_class column (well, we can always query the database directly, but I’m assuming you want to solve the problem using functions provided by WooCommerce). Also, “Standard rates” have no tax_class, ie. tax_rate_class column is an empty string.

    So if you want to get all tax rates per class, you need to use WC_Tax::get_rates_for_tax_class( $tax_class ). But if you really want all tax rates regardless of class, you need to get all tax classes first, then get all tax rates per class.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search