#StackBounty: #magento2 #checkout #tax #plugin Custom Tax Calculation infinite loop issue in Magento2

Bounty: 100

I am calculating custom Tax for the cart item, Used the following code.

Vendor/Module/etc/di.xml

<type name="MagentoQuoteModelQuoteAddressTotal">
    <plugin name="mbs_customtax_cart_item" type="VendorModulePluginCustomTaxTotal" />
</type>

Vendor/Module/Plugin/CustomTaxTotal.php

<?php

namespace VendorModulePlugin;

class CustomTaxTotal
{

private $logger;   
private $_productloader;  
private $_cart;
private $customTax = null;   
private $cartItemLoader;

public function __construct(
    PsrLogLoggerInterface $logger,
    VendorModuleModelProductCartItemLoader $cartItemLoader
) {
    $this->logger = $logger;
    $this->cartItemLoader = $cartItemLoader;
}

private function calculateCustomTaxForQuote()
{
    if (is_null($this->customTax)) {
        $this->logger->info('--total--');
        $this->customTax = $this->cartItemLoader->getCartItemWithTaxRates();
    }

    return $this->customTax;
}

public function beforeAddTotalAmount(
    MagentoQuoteModelQuoteAddressTotal $subject,
    $code,
    $amount
) {
    if ($code =='tax') {
        $amount += $this->calculateCustomTaxForQuote();
    }

    return [$code, $amount];
}

public function beforeAddBaseTotalAmount(
    MagentoQuoteModelQuoteAddressTotal $subject,
    $code,
    $amount
) {
    if ($code =='tax') {
        $amount += $this->calculateCustomTaxForQuote();
    }

    return [$code, $amount];
  }
 }

VendorModuleModelProductCartItemLoader.php

<?php
namespace VendorModuleModel;

class ProductCartItemLoader
{
 private $productFactory;

private $cart;

private $customerSession;

private $taxCalculation;

private $scopeConfig;

private $collectionFactory;

private $dataObjectFactory;

public function __construct(
    MagentoCatalogModelProductFactory $productFactory,
    MagentoCheckoutModelCart $cart,
    MagentoCustomerModelSession $customerSession,
    MagentoTaxModelCalculation $taxCalculation,
    MagentoFrameworkAppConfigScopeConfigInterface $scopeConfig,
    MagentoFrameworkDataCollectionFactory $collectionFactory,
    MagentoFrameworkDataObjectFactory $dataObjectFactory
) {
    $this->productFactory = $productFactory;
    $this->cart = $cart;
    $this->customerSession = $customerSession;
    $this->taxCalculation = $taxCalculation;
    $this->scopeConfig = $scopeConfig;
    $this->collectionFactory = $collectionFactory;
    $this->dataObjectFactory = $dataObjectFactory;
}

public function getCartItemWithTaxRates()
{
    $itemsCollection = $this->cart->getQuote()->getItemsCollection();
    $productCollection = $this->getProductWithExternalData($itemsCollection);

    $taxAmount = 0;
    foreach ($itemsCollection as $item) {
        $product = $productCollection->getItemByColumnValue('entity_id', $item->getProductId());

        if ($product and $product->getData('pod_image_id')!='') {
            $taxRate = $this->getRate($product);

            if ($taxRate > 0) {
                $taxAmount += ($product->getData('pod_price') * $taxRate)/100;
            }
        }
    }

    return $taxAmount;
}

private 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 MagentoFrameworkDataObject(
            [
                'country_id' => $countryCode,
                'customer_class_id' => $this->scopeConfig->getValue('tax/classes/default_customer_tax_class'),
                'product_class_id' => $productTaxClassId
            ]
        )
    );

    return $rate;
}


private function getProductWithExternalData($itemsCollection):MagentoFrameworkDataCollection
{
    $parsedCollection = $this->collectionFactory->create();

    if ($this->cart->getQuote()->getId()) {
        $productIds = [];
        foreach ($itemsCollection as $item) {
            $productIds[] = $item->getProductId();
        }

        $productCollection = $this->productFactory->create()->getCollection()
            ->addFieldToSelect('tax_class_id')
            ->addIdFilter($productIds);

        $productCollection->getSelect()->joinLeft(
            ['pod' => $productCollection->getSelect()->getConnection()->getTableName('pod_temp_cart')],
            'e.entity_id=pod.product_id and pod.quote_id=' . $this->cart->getQuote()->getId(),
            ['pod.image_id as pod_image_id', 'pod.price as pod_price']
        );

        $result = $productCollection->getSelect()->getConnection()->fetchAll($productCollection->getSelect());

        if (!empty($result)) {
            foreach ($result as $item) {
                $data = $this->dataObjectFactory->create();
                $data->setData($item);
                $parsedCollection->addItem($data);
            }
        }
    }

    return $parsedCollection;
   }
}

From the Above code I am getting the Correct Tax amount but once i click Place order getting the below error due to this unable to place the order.

Infinite loop detected,in exception file.

Please someone update me the working solution for this. Thanks


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.