WooCommerce change Tax Class programmatically when Recalculating an existing Order

The question:

I’m hoping someone can’t point me to what I am overlooking.

CIRCUMSTANCE:

We have some unique business logic whereby a custom user meta field affects the appropriate tax class. We have three customer “types” (which is this user meta field, say 'type_one', 'type_two', 'type_three') with three corresponding custom Tax Classes ('class_one', 'class_two', 'class_three').

When we calculate taxes on a Cart, we run a filter on woocommerce_product_get_tax_class and re-assign the Tax Class based on looking up this user meta. It works perfectly for our needs. Sort of (but not exactly, of course) like this:

function reassign_tax_class( $tax_class, $product ) {
    $user = wp_get_current_user();
    if(get_user_meta( $user->ID, '_our_custom_field', true)=='type_one'){
        $tax_class = 'class_one';
    }
    return $tax_class;
}
add_filter( 'woocommerce_product_get_tax_class', 'reassign_tax_class', 1, 2 );

PROBLEM:

We have frequent need to use the Recalculate button on the edit Order page in WP Admin. I cannot find where I can filter or hook the tax class assignment on an order item. It seems to be in the calculate_taxes() method in the class-wc-order-item.php class (line 220: https://github.com/woocommerce/woocommerce/blob/trunk/includes/class-wc-order-item.php#L220 )–and surely enough if insert line 221 there like $calculate_tax_for['tax_class'] = 'class_one' it does exactly what I am looking to do.

Is there a way I can do this without hacking core?

Thanks vastly for any help. I’m at a complete loss and against a clock.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Posting the solution that worked for me in case it helps anyone in the future (Credit to Rup & WooCommerce Community Slack)

I was filtering the tax class getter on the cart side and that was doing what I needed, so I was focused on figuring out how to also filter the tax class getter on the order side. Devinsays on Community Slack recommended the obvious-in-hindsight solution of filtering also the setter on the cart side and then the order side just works without any filter. In other words, when I re-assign the tax class for the calculation on the cart side, actively set it on order creation. Then it will be attached to the order item for the recalculate later. Something like this:

function also_reassign_the_setter($item, $cart_item_key, $values, $order){
    //some custom logic
    $item->set_tax_class('class_one');
}
add_action('woocommerce_checkout_create_order_line_item', 'also_reassign_the_setter', 20, 4);


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment