3

Since the order method getFullTaxInfo() is not available in Magento 2, how does one get the tax percent used on the order shipping amount for an order?

I see the item is in sales_order_tax_item table (where taxable_item_type = shipping), but I don't see any method in the Order or OrderInterface for fetching the tax details, except what is already in the Order table columns (tax amount, etc.). Weirdly enough this table also does not contain an order_id column, so there's no direct back-reference.

I know you can calculate the percentage manually but I think it's best to avoid it.

I see a promising method

\Magento\Sales\Model\ResourceModel\Order\Tax::getTaxItemsByOrderId($orderId)

but I have no idea how to properly use it.

1 Answer 1

7

I figured it out... Here's an example.

<?php
namespace Vendor\Module\Helper;

use \Magento\Framework\App\Helper\Context;
use \Magento\Sales\Api\Data\OrderInterface;
use \Magento\Sales\Model\ResourceModel\Order\Tax\Item;

class APIHelper extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * @var \Magento\Sales\Model\ResourceModel\Order\Tax\Item
     */
    protected $taxItem;

    public function __construct(
        Context $context,
        Item $taxItem
    ) {
        parent::__construct($context);
        $this->taxItem = $taxItem;
    }

    public function someMethod(OrderInterface $order)
    {
        $tax_items = $this->taxItem->getTaxItemsByOrderId($order->getId());
        var_dump($tax_items);
    }
}

Returns an array in format:

array (size=2)
  0 => 
    array (size=10)
      'tax_id' => string '9' (length=1)
      'tax_percent' => string '22.0000' (length=7)
      'item_id' => null
      'taxable_item_type' => string 'shipping' (length=8)
      'associated_item_id' => null
      'real_amount' => string '1.1000' (length=6)
      'real_base_amount' => string '1.1000' (length=6)
      'code' => string 'Slovenia (standard)' (length=19)
      'title' => string 'Slovenia (standard)' (length=19)
      'order_id' => string '22' (length=2)
  1 => 
    array (size=10)
      'tax_id' => string '9' (length=1)
      'tax_percent' => string '22.0000' (length=7)
      'item_id' => string '35' (length=2)
      'taxable_item_type' => string 'product' (length=7)
      'associated_item_id' => null
      'real_amount' => string '9.9000' (length=6)
      'real_base_amount' => string '9.9000' (length=6)
      'code' => string 'Slovenia (standard)' (length=19)
      'title' => string 'Slovenia (standard)' (length=19)
      'order_id' => string '22' (length=2)

So just iterate through and test if taxable_item_type equals to 'shipping':

    if (is_array($tax_items)) {
        foreach ($tax_items as $item) {
            if ($item['taxable_item_type'] === 'shipping') {
                // You got it
            }
        }
    }

I also had to recompile DI with setup:di:compile in CLI.

1
  • Great answer. Just one thing to look out for. Return will be an empty array if no tax was charged e.g. international order that doesn't attract local taxes. In that case there are no tax items for the order. Commented Jan 12 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.