2

I have a Magento 2.4.3 store.

By default I want product's price and Customizable Options to be displayed without tax.

Product's price is displayed correctly, without tax.

Customizable Options however are displayed including tax. How do I display Customizable Options without tax?

Here is how Customizable Options look like in the admin panel: enter image description here

This is how the Customizable Options are displayed now: enter image description here

And this is how I want them to be displayed: enter image description here

Thank you!

1
  • did you find a solution to this one? could you share it?
    – zekia
    Jul 14, 2023 at 7:01

1 Answer 1

1

Ok I figured this one out and posting in case I forget in future, but also to assist with anyone else who was looking for a solution to this problem :) So I basically resolved this using a custom totals collector, as follows:

Step 1

Create app/code/Vendor/Module/etc/sales.xml file and reference a new collector class as follows for example:

<?xml version="1.0"?>

<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="tax_subtotal" instance="Vendor\Module\Model\Sales\Total\Quote\Subtotal" sort_order="600"/>
        </group>
    </section>
</config>

Step 2

Create your custom class PHP file app/code/Vendor/Module/Model/Sales/Total/Quote/Subtotal.php with something like the following:

<?php

namespace Vendor\Module\Model\Sales\Total\Quote;

use Magento\Customer\Api\Data\AddressInterfaceFactory as CustomerAddressFactory;
use Magento\Customer\Api\Data\RegionInterfaceFactory as CustomerAddressRegionFactory;
use Magento\Tax\Helper\Data as TaxHelper;
use Magento\Tax\Api\Data\QuoteDetailsInterfaceFactory;
use Magento\Tax\Api\Data\QuoteDetailsItemInterfaceFactory;
use Magento\Tax\Model\Sales\Total\Quote\Tax;
use Magento\Tax\Model\Config;
use Magento\Tax\Api\TaxCalculationInterface;
use Magento\Tax\Api\Data\TaxClassKeyInterfaceFactory;
use Magento\Framework\Serialize\Serializer\Json;

class Subtotal extends Tax
{
    public function __construct(
        Config $taxConfig,
        TaxCalculationInterface $taxCalculationService,
        QuoteDetailsInterfaceFactory $quoteDetailsDataObjectFactory,
        QuoteDetailsItemInterfaceFactory $quoteDetailsItemDataObjectFactory,
        TaxClassKeyInterfaceFactory $taxClassKeyDataObjectFactory,
        CustomerAddressFactory $customerAddressFactory,
        CustomerAddressRegionFactory $customerAddressRegionFactory,
        TaxHelper $taxData,
        Json $serializer
    ) {

        parent::__construct(
            $taxConfig,
            $taxCalculationService,
            $quoteDetailsDataObjectFactory,
            $quoteDetailsItemDataObjectFactory,
            $taxClassKeyDataObjectFactory,
            $customerAddressFactory,
            $customerAddressRegionFactory,
            $taxData,
            $serializer
        );
    }

    /**
     * Calculate tax on product items. The result will be used to determine shipping
     * and discount later.
     *
     * @param \Magento\Quote\Model\Quote $quote
     * @param ShippingAssignmentInterface $shippingAssignment
     * @param Address\Total $total
     * @return $this
     */
    public function collect(
        \Magento\Quote\Model\Quote $quote,
        \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
        \Magento\Quote\Model\Quote\Address\Total $total
    ) {
        // return if no items in quote
        if (!$quote->getItems()) {
            return $this;
        }

        // set some default values
        $subtotal = 0;
        $tax = 0;
        $quoteId = $quote->getId();

        foreach ($quote->getItems() as $quoteItem) {
            $productId = $quoteItem->getProductId();

            // if current item requires VAT relief
              // update row totals for item (remove VAT)
              $this->setRowExclTax($quoteItem);
                
              // add to cart subtotal
              $subtotal += $quoteItem->getBaseRowTotalInclTax();

              // add to cart tax
              $tax += $quoteItem->getBaseTaxAmount();
        }

        // Update the cart totals for subtotal, total Inc/Ex tax etc 
        $this->updateCartTotals($total, $subtotal, $tax);      

        return $this;
    }

   // Sets the item row calculations and removes Tax
    private function setRowExclTax($quoteItem) 
    {
        // calculate the subtotal for each item row
        $rowTotal = ($quoteItem->getPrice() * $quoteItem->getQty());

        // Calculate item row totals
        $quoteItem->setPrice($quoteItem->getPrice());
        $quoteItem->setBasePrice($quoteItem->getBasePrice());
        $quoteItem->setPriceInclTax($quoteItem->getPrice());
        $quoteItem->setBasePriceInclTax($quoteItem->getBasePrice());
        $quoteItem->setRowTotal($rowTotal);
        $quoteItem->setBaseRowTotal($rowTotal);
        $quoteItem->setRowTotalInclTax($rowTotal);
        $quoteItem->setBaseRowTotalInclTax($rowTotal);

        // Remove Tax
        $quoteItem->setTaxAmount(0);
        $quoteItem->setBaseTaxAmount(0);
        $quoteItem->setTaxPercent(0);
    }

    // updates totals such as subtotal, price Incl/Excl Tax etc. 
    private function updateCartTotals($total, $subtotal, $tax)
    {
        $total->setTotalAmount('subtotal', $subtotal);
        $total->setBaseTotalAmount('subtotal', $subtotal);
        $total->setSubtotalInclTax($subtotal);
        $total->setBaseSubtotalInclTax($subtotal);

        // Remove Tax 
        $total->setTotalAmount('tax', $tax);
        $total->setBaseTotalAmount('tax', $tax);

        // Set the grand total Inc Tax total
        $total->setGrandTotal($subtotal);
    }
}

And that was pretty much it :) everything now works as planned when removing VAT from specific items. Hopefully this will help someone else when they need it.

You can see

2
  • thank you but this is not what i need. i want the price to be displayed for each option but have it without tax
    – Melody
    Jul 26, 2022 at 9:28
  • Please check now.
    – Rohit
    Jul 26, 2022 at 9:43

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.