6

I am applying custom tax for the cart item based on the product attribute value.

used below event for that.

Vendor/Module/etc/di.xml

<type name="Magento\Quote\Model\Quote\Address\Total">
        <plugin name="mbs_customtax_cart_item" type="Vendor\Module\Plugin\CustomTaxTotal" />
 </type>

Then Vendor\Module\Plugin\CustomTaxTotal.php

<?php
namespace Vendor\Module\Plugin;

class CustomTaxTotal
{

private $logger;

private $_productloader;

private $_cart;
private $customTax = null;
protected $_resource;
protected $customerSession;
protected $_taxCalculation;
protected $_scopeConfig;
public function __construct(
    \Psr\Log\LoggerInterface $logger,
    \Magento\Catalog\Model\ProductFactory $_productloader,
    \Magento\Checkout\Model\Cart $cart,
    \Magento\Framework\App\ResourceConnection $resource,
    \Magento\Customer\Model\Session $customerSession,
    \Magento\Tax\Model\Calculation $taxCalculation,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
) {
    $this->logger = $logger;
    $this->_productloader = $_productloader;
    $this->_cart = $cart;
    $this->_resource = $resource;
    $this->customerSession = $customerSession;
    $this->_taxCalculation = $taxCalculation;
    $this->_scopeConfig = $scopeConfig;
}

private function calculateCustomTaxForQuote()
{
    $taxRate = 0;
    $taxAmount = 0;
    $itemPrice = 0;
     if (is_null($this->customTax)) {
        $this->customTax = 0;            
        $connection = $this->getConnection();
        $itemsCollection = $this->_cart->getQuote()->getItemsCollection();
        $quoteId = $this->_cart->getQuote()->getId();
        foreach ($itemsCollection as $items) {
            $productId = $items->getProductId();
            $binds_select_pod = array(
                'product_id'   => $productId,
                'quote_id'    => $quoteId
            );              
            $isPodExistQry = "select * from pod_temp_cart where quote_id = :quote_id && product_id = :product_id"; 
            $results_podexist = $connection->query($isPodExistQry,$binds_select_pod);
            $isPodExistRes = $results_podexist->fetchAll();
            
            if(isset($isPodExistRes) && count($isPodExistRes) > 0){
                $imageId = $isPodExistRes[0]['image_id'];
                $itemPrice = $isPodExistRes[0]['price'];
                $imageProductId = $this->getProductIdBySku($imageId);
                $this->logger->info('--imageProductId--'.$imageProductId);
                $product = $this->_productloader->create()->load($imageProductId);
                $taxRate = $this->getRate($product);
                if($taxRate > 0){
                    $taxAmount += ($itemPrice * $taxRate)/100;
                }
            }
            if (isset($taxAmount) && $taxAmount !='' && $taxAmount != 0) {
               $this->customTax = $taxAmount;
            }
        }       
    } 
   $this->logger->info('--customTax--'.$this->customTax);
    return $this->customTax;
}
public function getRate($product){
    $productTaxClassId = $product->getTaxClassId();     
    $shippingAddress = $this->customerSession->getCustomer()->getDefaultShippingAddress();
    $countryCode =  (isset($shippingAddress['country_id']) && !empty($shippingAddress['country_id'])) ? $shippingAddress['country_id']:'GB';
    $rate = $this->_taxCalculation->getRate(
        new \Magento\Framework\DataObject(
            [
                'country_id' => $countryCode,
                'customer_class_id' => $this->_scopeConfig->getValue('tax/classes/default_customer_tax_class'),
                'product_class_id' => $productTaxClassId
            ]
        )
    );
    return $rate;
}

public function beforeAddTotalAmount(
    \Magento\Quote\Model\Quote\Address\Total $subject,
    $code,
    $amount
) {
    if ($code == 'tax') {
        $amount += $this->calculateCustomTaxForQuote();
    }
    return [$code, $amount];
}

public function beforeAddBaseTotalAmount(
    \Magento\Quote\Model\Quote\Address\Total $subject,
    $code,
    $amount
) {
    if ($code =='tax') {
        $amount += $this->calculateCustomTaxForQuote();
    }

    return [$code, $amount];
}
public function getConnection(){
    return $this->_resource->getConnection();
}
public function getProductIdBySku($sku) {
    $product = $this->_productloader->create();
    $product->load($product->getIdBySku($sku));
    $productId = $product->getId();
    return $productId;
}

}

The event is firing but the Tax is not getting applied, I am getting Message: Infinite loop detected,in exception, can not place the order

from the suggested answer I am facing different issue.

https://bitbucket.org/magstaging/taxadditionaladjustment/src/master

from the above answer i am getting the below error and i can't place the order.

Message: Infinite loop detected, review the trace for the looping path

can anyone help me on this issue please? Thank you for the support!!

4
  • Do you want to apply fixed tax amount OR need to change tax percentage rate ?
    – Pawan
    Commented Jun 10, 2020 at 1:24
  • Yes @pawan, need to apply percentage basis Commented Jun 10, 2020 at 16:41
  • It seem like you want to have a custom fee base on percentage basis NOT a tax Commented Jun 12, 2020 at 3:18
  • @TuyenNguyen, No I have to apply tax programmatically,for the specific product Commented Jun 12, 2020 at 5:23

2 Answers 2

1
+50

In the code below, I have reused your code and I have the tax adjusted in the cart as expected. I have also a possible improvement (optimisation that is to give you) but for now, I am trying to provide you the solution that reuses your code so that you can apply it very easily. If you need some optimisation tips, I can post the details later.

Mbs/TaxAdditionalAdjustment/etc/di.xml

  <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="Magento\Quote\Model\Quote\Address\Total">
            <plugin name="mbs_customtax_cart_item" type="Mbs\TaxAdditionalAdjustment\Plugin\CustomTaxTotal" />
        </type>     
    </config>

Mbs/TaxAdditionalAdjustment/Plugin/CustomTaxTotal.php

<?php

namespace Mbs\TaxAdditionalAdjustment\Plugin;

class CustomTaxTotal
{
    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;
    /**
     * @var \Magento\Catalog\Model\ProductFactory
     */
    private $_productloader;
    /**
     * @var \Magento\Checkout\Model\Cart
     */
    private $_cart;

    private $customTax = null;

    public function __construct(
        \Psr\Log\LoggerInterface $logger,
        \Magento\Catalog\Model\ProductFactory $_productloader,
        \Magento\Checkout\Model\Cart $cart
    ) {
        $this->logger = $logger;
        $this->_productloader = $_productloader;
        $this->_cart = $cart;
    }

    private function calculateCustomTaxForQuote()
    {
        return 6;
        if (is_null($this->customTax)) {
            $this->customTax = 0;
            /** @var Magento\Quote\Model\Quote\Address\Total */
            $this->logger->info('--total--');

            // retrieve quote items collection
            $itemsCollection = $this->_cart->getQuote()->getItemsCollection();
            $isDeliverable = [];
            foreach ($itemsCollection as $items) {
                $productId = $items->getProductId();
                $this->logger->info('--itemIds--' . $productId);
                $product = $this->_productloader->create()->load($productId);
                $deliveryProduct = $product->getIsDelivery();
                if ($deliveryProduct) {
                    $isDeliverable[] = $productId;
                }
            }
            if (count($isDeliverable) > 0) {
                $this->logger->info('--inside--');
                $this->customTax =6;
            }
        }

        return $this->customTax;
    }

    public function beforeAddTotalAmount(
        \Magento\Quote\Model\Quote\Address\Total $subject,
        $code,
        $amount
    ) {
        if ($code =='tax') {
            $amount += $this->calculateCustomTaxForQuote();
        }

        return [$code, $amount];
    }

    public function beforeAddBaseTotalAmount(
        \Magento\Quote\Model\Quote\Address\Total $subject,
        $code,
        $amount
    ) {
        if ($code =='tax') {
            $amount += $this->calculateCustomTaxForQuote();
        }

        return [$code, $amount];
    }
}

I also have a module available at https://bitbucket.org/magstaging/taxadditionaladjustment/src/master/

this module pretty much is the answer from above within a module that uses your extra table

26
  • okay thank you @Herve, let me try your answer Commented Jun 12, 2020 at 11:13
  • @jafarpinjar are you able to provide feedback? Commented Jun 14, 2020 at 5:26
  • hi @Herve, i tested this, its not working, the plugin itself not firing Commented Jun 15, 2020 at 4:58
  • Now the plugin is fired, but i am getting Message: Infinite loop detected,in exception, could not place the order Commented Jun 15, 2020 at 8:57
  • can you please update me, i will update my question here Commented Jun 15, 2020 at 9:46
0

I rewrite the collect() method. The below code works for me.

public function collect(
    \Magento\Quote\Model\Quote $quote,
    \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
    \Magento\Quote\Model\Quote\Address\Total $total
) {
    
    $this->clearValues($total);
    if (!$shippingAssignment->getItems()) {
        return $this;
    }

    $x= $quote->getItems();
    if (isset($x)) {
        foreach ($x as $item) {
            $g = $item;
            $y = $item->getSku();
            $y = $item->getProductId();
        }
    }
    
    $baseTaxDetails = $this->getQuoteTaxDetails($shippingAssignment, $total, true);
    $taxDetails = $this->getQuoteTaxDetails($shippingAssignment, $total, false);

    //Populate address and items with tax calculation results
    $itemsByType = $this->organizeItemTaxDetailsByType($taxDetails, $baseTaxDetails);
    if (isset($itemsByType[self::ITEM_TYPE_PRODUCT])) {
        $this->processProductItems($shippingAssignment, $itemsByType[self::ITEM_TYPE_PRODUCT], $total);
    }

    if (isset($itemsByType[self::ITEM_TYPE_SHIPPING])) {
        $shippingTaxDetails = $itemsByType[self::ITEM_TYPE_SHIPPING][self::ITEM_CODE_SHIPPING][self::KEY_ITEM];
        $baseShippingTaxDetails =
            $itemsByType[self::ITEM_TYPE_SHIPPING][self::ITEM_CODE_SHIPPING][self::KEY_BASE_ITEM];
        $this->processShippingTaxInfo($shippingAssignment, $total, $shippingTaxDetails, $baseShippingTaxDetails);
    }

    //Process taxable items that are not product or shipping
    $this->processExtraTaxables($total, $itemsByType);

   $total->setTaxAmount(2000);
   $total->setGrandTotal($total->getBaseGrandTotal()+2000);
   
    //Save applied taxes for each item and the quote in aggregation
    $this->processAppliedTaxes($total, $shippingAssignment, $itemsByType);

    if ($this->includeExtraTax()) {
        $total->addTotalAmount('extra_tax', $total->getExtraTaxAmount());
        $total->addBaseTotalAmount('extra_tax', $total->getBaseExtraTaxAmount());
    }

    return $this;
}

  

preference class

    <preference for="Magento\Tax\Model\Sales\Total\Quote\Tax" type="BA\Vertex\Rewrite\Magento\Tax\Model\Sales\Total\Quote\Tax"/>

enter image description here

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.