I am trying to overriding vendor/magento/module-tax/Model/Calculation.php class in custom module by using preference and pass the class \Magento\Checkout\Model\Cart in __construct function.

I have tried it by below code:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Tax\Model\Calculation" type="Vendor\Customtax\Model\Calculation" />

and below is my Calculation.php file

 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
namespace Vendorname\CustomTax\Model;

 class Calculation extends \Magento\Tax\Model\Calculation

 public function getRateRequest(
        $shippingAddress = null,
        $billingAddress = null,
        $customerTaxClass = null,
        $store = null,
        $customerId = null
    ) {

          --- here is my Logic----


Now I want to pass the class \Magento\Checkout\Model\Cart $cart in construct method.

Please suggest me how to override construct method.When Trying To override Function it is not working well and throw the error.

1 Answer 1


First of all I want to say that your approach might not be the best one. I don't have all the facts and I don't know what your requirement is, but I have a feeling that making the tax calculator depend on your cart class may not be the best idea. Maybe your should explain the problem you are trying to solve instead of how you are trying to solve it. Maybe there is another way to do it instead of rewriting the class and adding a new dependency to it.
But in case you want to go on with this approach, here is how you can add the Cart class as a new dependency to your class.

add this member to your class

 * @var \Magento\Checkout\Model\Cart
protected $cart;

Make your class constructor look like this

public function __construct(
    \Magento\Framework\Model\Context $context,
    \Magento\Framework\Registry $registry,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
    \Magento\Tax\Model\Config $taxConfig,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Customer\Model\Session $customerSession,
    \Magento\Customer\Model\CustomerFactory $customerFactory,
    \Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory $classesFactory,
    \Magento\Tax\Model\ResourceModel\Calculation $resource,
    \Magento\Customer\Api\AccountManagementInterface $customerAccountManagement,
    \Magento\Customer\Api\GroupManagementInterface $customerGroupManagement,
    \Magento\Customer\Api\GroupRepositoryInterface $customerGroupRepository,
    \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
    \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
    \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
    \Magento\Framework\Api\FilterBuilder $filterBuilder,
    \Magento\Tax\Api\TaxClassRepositoryInterface $taxClassRepository,
    \Magento\Checkout\Model\Cart $cart,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {
     $this->cart = $cart;

Now you can use $this->cart everywhere in your class.

Some explanation of what the code above means.
Your new class constructor has the same parameters as the parent class constructor with one addition \Magento\Checkout\Model\Cart $cart.
You can add this new parameter anywhere in the list, the order is not important, but it has to be above the optional parameters. I added it right between the required parent method parameters and the optional parameters. I find it easier to keep track of them (there was also at one point a static code test that complained if you do it differently, but this does not affect the proper functioning of your code).

When your class gets instantiated, the factory that does this (object manager) reads the signature of your constructor method, and gets the required dependencies from the DIC (dependency injection container) if they exist, if not it instantiates them and passes them as parameters to your constructor.
calling parent::__construct with the original class parameters will ensure that the original dependencies are attached to your class also.

  • Hi @marius, thanks for your quick response and deeply explanation.Code is working perfectly now.Our requirement is change the "tax calculation based on" change when shipping method updated on checkout page.
    – akgola
    Aug 26, 2020 at 8:50
  • Hi @marius, I am getting error“infinite loop detected review the trace for the looping path”.please help me . magento.stackexchange.com/q/320984/24878
    – akgola
    Aug 27, 2020 at 15:59
  • Hi @akgola, have you found a solution? facing the same Aug 29, 2022 at 11:10

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.