Search code examples
phpwordpresswoocommerceorders

WooCommerce: Get order totals only from items with reduced tax rate


I want to export only the totals from items with a reduced tax rate.

For example, I have 2 items with a reduced tax rate and one with the normal tax rate:

  • Item A: 100€ - 5,00€ reduced tax - 105,00€ total
  • Item B: 50€ - 2,50€ reduced tax - 52,50€ total
  • Item C: 100€ - 19,00€ normal tax - 119,00€ total

I now want the totals from Item A and B. In this case a combined value of 157,50€.

I found a code snippet to get the total tax amounts with class:

// Get the WC_Order instance Object from the Order ID (if needed)
$order = wc_get_order($order_id);

// Output the tax rows in a table
echo '<table>';
foreach ( $order->get_tax_totals() as $rate_code => $tax ) {
    $tax_rate_id  = $tax->rate_id;
    $tax_label    = $tax->label;
    $tax_amount   = $tax->amount;
    $tax_f_amount = $tax->formatted_amount;
    $compound     = $tax->is_compound;
    echo '<tr><td>' . $tax_label  . ': </td><td>' . $tax_f_amount . '</td></tr>';
}
echo '</table>';

But that code gives me all tax classes. Is there any way to get only one?

Here's what I'm doing right now (excerpt):

$custom_order_total_tax         = $custom_order_data['total_tax'];
$custom_order_total             = $custom_order_data['total'];      
$custom_order_subtotal          = $order->get_subtotal();

There is nothing I could use in the $order variable.

I guess I need to go through all items of the order. But how could I select these items by tax rate?

I found something here:

// Get and Loop Over Order Items
foreach ( $order->get_items() as $item_id => $item ) {
   $product_id = $item->get_product_id();
   $variation_id = $item->get_variation_id();
   $product = $item->get_product();
   $name = $item->get_name();
   $quantity = $item->get_quantity();
   $subtotal = $item->get_subtotal();
   $total = $item->get_total();
   $tax = $item->get_subtotal_tax();
   $taxclass = $item->get_tax_class();
   $taxstat = $item->get_tax_status();
   $allmeta = $item->get_meta_data();
   $somemeta = $item->get_meta( '_whatever', true );
   $type = $item->get_type();
}

But the tax rate is not part of it. So I guess I need a second array?


Solution

  • To get the tax class of the order items look here:

    Then you can create a custom function that sums the totals of the order items based on a specified tax class.

    There are two parameters of the function:

    • $order_id: the id of the order from which you want to get the totals
    • $tax_class: the tax class to use as a filter (by default "reduced-rate" is set)

    So:

    // gets the total of the order items by tax class
    function get_total_order_items_by_tax_class( $order_id, $tax_class = 'reduced-rate' ) {
        $order = wc_get_order( $order_id );
        // initializes the total of the order items
        $total = 0;
        foreach( $order->get_items() as $item_id => $order_item ) {
            // if the product tax class is equal to "$tax_class"
            if ( $tax_class == $order_item['tax_class'] ) {
                // sum the total
                $total += $order_item['total'];
            }
        }
        return $total;
    }
    

    USAGE

    If you want to get the sum of the totals of the order items with the order id 60 according to the reduced-rate tax class you can do it as follows:

    $total = get_total_order_items_by_tax_class( 60 );
    

    If you want to filter products based on the standard tax class you can use:

    $total = get_total_order_items_by_tax_class( 60, '' );
    

    Because the standard tax class slug is empty.

    The code has been tested and works.