11

I want to add custom tax amount to checkout cart programmatically.

Here is the example.

Cart Old Tax = 4.21

Custom Tax = 2

New Tax = 4.21 + 2 = 6

Check the screenshot below.

enter image description here

I need this done programmatically.

5
  • Where your custom amount come from? Jan 10, 2017 at 9:31
  • @ToanNguyen that I fetch from the session, My point is how can add that value to tax. Jan 10, 2017 at 9:52
  • @DhirenVasoya, below solution i tried,this is showing cart but not calculating.. May 14, 2019 at 16:41
  • @DhirenVasoya - did you get the solution to this problem ? Jul 17, 2019 at 13:33
  • @DhirenVasoya, did you get solution for this/ Jun 8, 2020 at 11:06

3 Answers 3

5

You can observe to the event sales_quote_address_collect_totals_after and achieve it. For this, you need to setup a module and configure an event. Let's say our module is MStack_Exchange.

File : app\code\MStack\Exchange\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="MStack\Exchange\Observer\ChangeTaxTotal"/>
    </event>
</config>

File : app\code\MStack\Exchange\Observer\ChangeTaxTotal.php

<?php
namespace MStack\Exchange\Observer;

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

class ChangeTaxTotal implements ObserverInterface
{
    public $additionalTaxAmt = 2;

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

        //make sure tax value exist
        if (count($total->getAppliedTaxes()) > 0) {
            $total->addTotalAmount('tax', $this->additionalTaxAmt);
        }

        return $this;
    }
}

The important call here is : $total->addTotalAmount('tax', $this->additionalTaxAmt);. This will add 2 with the existing tax amount and I think that is what you need in your case. So what you need to do is, replace $this->additionalTaxAmt with your tax buffer value.

The event sales_quote_address_collect_totals_after fires just after total calculations had been happend and hence thus become perfect place to play around.

If you are curious to know where this total calculations are happening, then you need to look into Magento\Quote\Model\Quote\TotalsCollector::collect() and Magento\Quote\Model\Quote\TotalsCollector::collectAddressTotals() methods.

7
  • Let me check this. Feb 11, 2017 at 3:04
  • @Rajeev, can we add custom tax for individual product when added to cart? here is my question,magento.stackexchange.com/questions/274520/… May 14, 2019 at 11:04
  • Thanks @Rajeev to save my day Nov 14, 2019 at 13:19
  • Hi @rajeev , I want to clear all taxes programmatically before adding custom tax and also want to add title of tax.Can you please let me know how to achieve it?
    – akgola
    Aug 25, 2020 at 4:27
  • @akgola Hi, I am not sure which version you are referring to and feel your question is broad and cannot answer in a comment. Better ask a new question with details in the platform so that the community will help you to accomplish your need Aug 25, 2020 at 5:08
3

@Dhiren Vasoya

Use these lines as well.

$total->addBaseTotalAmount('tax', $this->additionalTaxAmt);
$total->setGrandTotal((float)$total->getGrandTotal() + $this->additionalTaxAmt);
$total->setBaseGrandTotal((float)$total->getBaseGrandTotal() + $this->additionalTaxAmt);
1
  • this tax is not getting added in invoice section.
    – akgola
    May 12, 2021 at 14:30
0

I have created a db table to collect Tax for each product item and Applied on Cart page, So it can save into quote table Create sales.xml file in app/code/VENDOR_NAME/MODULE_NAME/etc/sales.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
    <section name="quote">
        <group name="totals">
            <item name="customtax" instance="VENDOR_NAME/MODULE_NAME\Model\Total\Quote\CustomTax" sort_order="500"/>
        </group>
    </section>
</config>

Now Create a mode file CustomTax.php at app/code/VENDOR_NAME/MODULE_NAME\Model\Total\Quote\CustomTax.php

    <?php 
    namespace VENDOR_NAME\MODULE_NAME\Model\Total\Quote;
    use Exception;
    use Magento\Customer\Model\Session as CustomerSession;
    use Magento\Framework\Pricing\PriceCurrencyInterface;
    use Magento\Quote\Api\Data\ShippingAssignmentInterface;
    use Magento\Quote\Model\Quote;
    use Magento\Quote\Model\Quote\Address;
    use Magento\Quote\Model\Quote\Address\Total;
    use Magento\Quote\Model\Quote\Address\Total\AbstractTotal;
    use Magento\Tax\Model\Calculation;
    
    class CustomTax extends AbstractTotal
    {
        public function __construct(
            \Magento\Framework\App\ResourceConnection $resource,
            PriceCurrencyInterface $priceCurrency,
            Calculation $calculation,
            CustomerSession $customerSession
           
        ) {
            $this->priceCurrency = $priceCurrency;
            $this->calculation = $calculation;
            $this->customerSession = $customerSession;
            $this->connection = $resource->getConnection();
        }
    
        /**
         * Collect extra fee totals
         *
         * @param Quote $quote
         * @param ShippingAssignmentInterface $shippingAssignment
         * @param Total $total
         *
         * @return $this
         * @throws Exception
         */
        public function collect(
            Quote $quote,
            ShippingAssignmentInterface $shippingAssignment,
            Total $total
        ) {
            parent::collect($quote, $shippingAssignment, $total);
            $totalTax = $this->getProductInfor($quote);
            $total->setTaxAmount($totalTax); //set tax amount here
            $total->setGrandTotal($total->getBaseGrandTotal()+$totalTax); 
            return $this;
        }
    
        public function getProductInfor( $quote){
            if($quote->getItemsQty()>=0){
                $items = $quote->getAllItems();
                $taxPercent =0;
                foreach($items as $item){
                    $qty = $item->getQty();
                    $sku = $item->getSku();
                    $select = $this->connection->select()
                    ->from(
                        ['c' => 'custom_product_tax'], //table Name here
                        ['tax']                        //column tax
                    )
                    ->where(
                        "c.sku = :sku"
                    );
                $bind = ['sku'=>$sku];
                $records = $this->connection->fetchAll($select, $bind);
                $tax = $records[0]['tax'];  
                if(!empty($tax)){    
                    $taxPercent += ($tax/100)*$item->getBaseRowTotal();
                }
                }
                return $taxPercent;
            }
        }
    }

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.