0

I have an extension_attribute named extra_fee showing in the cart and the value of this attribute is also being added to the cart total (see screenshot). My problem is, this attribute is required to be included in the checkout tax calculation and I am after some advice on how to do this, please.

What I am trying to achieve is for the tax row in the screenshot to also include the extra_fee value * the customer tax rate. In the screenshot this would be 20 * 0.2 = 4.00. Then 4 should be added to the Tax row and the Order Total row.

Does the extension attribute need to be added to one of the Tax API data interfaces? If so, which one?

Please let me know if any more information is required to help provide a solution for this problem.

Update

On the back of Prachi's suggestion I have manually calculated the tax within the observer using the base_subtotal and tax_amount values in the database.

I'm sure this could be improved by using a built in Magento class to get the tax data from the quote, as I can see this data is stored in the applied_taxes field. Please suggest any improvements where necessary, thanks.

use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer;
use \Psr\Log\LoggerInterface;

class ChangeTaxTotal implements ObserverInterface
{

    /**
     * @var LoggerInterface
     */
    protected $logger;

    public function __construct(
        LoggerInterface $loggerInterface
    )
    {
        $this->logger = $loggerInterface;
    }

    public function execute(Observer $observer)
    {
        /** @var Magento\Quote\Model\Quote\Address\Total */
        $total = $observer->getData('total');
        $quote = $observer->getData('quote');
        $shippingAssignment = $observer->getData('shipping_assignment');
        $extraFee = $quote->getExtraFee();

        //make sure tax value exist
        if (count($total->getAppliedTaxes()) > 0) {

            // NEXT STEPS
            // 1 .get tax rate for customer / country
            $taxRate = $this->getQuoteTaxRate($total);
            // 2. calcuate tax on fast turn around option
            $extraFeeTax = $this->getQuoteExtraFeeTax($extraFee, $taxRate);
            // 3. add exrtrafee tax to quote totals
            $total->addTotalAmount('tax', $extraFeeTax);
            $total->addBaseTotalAmount('tax', $extraFeeTax);
            $total->setGrandTotal($total->getGrandTotal() + $extraFeeTax);
            $total->setBaseGrandTotal($total->getBaseGrandTotal() + $extraFeeTax);

        }

        return $this;
    }

    /**
     * get tax rate for customer
     * 
     * @return float
     */
    private function getQuoteTaxRate($total)
    {
        return intval(($total->getTotalAmount('tax') / $total->getBaseSubtotal()) * 100);
    }

    /**
     * get tax amount for extra fee cost
     * 
     * @param float $extraFeeAmount
     * @param int $taxRate
     * 
     * @return float
     */
    private function getQuoteExtraFeeTax($extraFeeAmount, $taxRate)
    {
        return floatval($extraFeeAmount * ($taxRate / 100));
    }
}

enter image description here

0

To add additional amount to tax you will need to create an observer to sales_quote_address_collect_totals_after event in any custom module.

app\code\Vendor\Module\etc\events.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_quote_address_collect_totals_after">
        <observer name="changeTaxTotal" instance="Vendor\Module\Observer\ChangeTaxTotal"/>
    </event>
</config>

Vendor\Module\Observer\ChangeTaxTotal.php

<?php
namespace Vendor\Module\Observer;

use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer;

class ChangeTaxTotal implements ObserverInterface
{
    public function execute(Observer $observer)
    {
        $quote = $observer->getEvent()->getQuote();
        $extraFee = $quote->getExtensionAttributes()->getExtraFee();
        /** @var Magento\Quote\Model\Quote\Address\Total */
        $total = $observer->getData('total');

        //make sure tax value exist
        if (count($total->getAppliedTaxes()) > 0) {
            // This will add $extraFee amount in existing caluculated tax value
            $total->addTotalAmount('tax', $extraFee);
        }

        return $this;
   }
}
  • Thank you for your response Prachi. But your suggestion adds a specific value to the tax_amount field in the database. There are two problems with this: 1. The cart total is not updated. 2. The extra_fee amount is not a static value, it changes. Just to be clear the tax calculation needs to include the value of the extra_fee attribute. e.g. if the extra_fee value was £50.00 then the additional tax for UK would be £10.00. (the tax amount differs for each EU country). – Andy T May 15 at 13:12
  • 1) I am sorry if I took it wrong, but you said that the extra fee is getting added to cart total and just need to add it in tax so I provided the solution for tax only. 2) The extra fee here is dynamic only which we are fetching from quote extension attributes '$quote->getExtensionAttributes()->getExtraFee()' as you mentioned it is an extension attribute. If you wish you can apply your custom logic here for getting the extra_fee on the basis of country – Prachi Saxena May 16 at 4:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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