Read More
Read More
Menu Close

    Override Product Tier Prices in Magento 2

    Hello Friends!
    In this blog, we will learn how we can override product’s tier prices on category product page and view product page.
    In Magento 2, to override the product’s tier prices, we have to create plugins and preference. So, please follow the below steps:

    1. Declare plugins and preferences: Here, we will declare required plugins and preferences in the di.xml file inside the app/code/Vendor/CustomModule/etc/ directory.

    <?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\Catalog\Model\Product\Type\Price"  
        type="Vendor\CustomModule\Rewrite\Catalog\Model\Product\Type\Price" />
    
      <type name="Magento\Catalog\Pricing\Price\MinimalTierPriceCalculator">
            <plugin name="tier_price_info" 
              type="Vendor\CustomModule\Plugin\Catalog\Pricing\Price\MinimalTierPriceCalculator" 
              sortOrder="999" 
              disabled="false"  />
      </type>
    
      <type name="Magento\Catalog\Pricing\Price\FinalPrice">
            <plugin name="after_final_price_info" 
              type="Vendor\CustomModule\Plugin\Catalog\Pricing\Price\ChangeTierPriceInfo" 
              sortOrder="999" 
              disabled="false"  />
      </type>
    
    </config>

    2. Create preference class file Price.php for Magento\Catalog\Model\Product\Type\Price class inside the app/code/Vendor/CustomModule/Rewrite/Catalog/Model/Product/Type/ directory. In preference class, we will override ‘getExistingPrices’ method of Price Class.

    <?php
    /**
     * Vendor Desc.
     * php version 7.3.*
     *
     * @category Vendor
     * @package Vendor_CustomModule
     * @author Vendor
     * @copyright Vendor (https://example.com)
     * @license https://example.com/license.html
     */
    declare(strict_types=1);
    
    namespace Vendor\CustomModule\Rewrite\Catalog\Model\Product\Type;
    
    use Magento\Catalog\Model\Product;
    use Magento\Customer\Api\GroupManagementInterface;
    use Magento\Framework\Pricing\PriceCurrencyInterface;
    use Magento\Store\Model\Store;
    use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory;
    use Magento\Framework\App\ObjectManager;
    use Magento\Store\Api\Data\WebsiteInterface;
    use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory;
    
    /**
     * Product type price model
     */
    class Price extends \Magento\Catalog\Model\Product\Type\Price
    {
        /**
         * Product price cache tag
         */
        const CACHE_TAG = 'PRODUCT_PRICE';
    
        /**
         * @var array
         */
        protected static $attributeCache = [];
    
        /**
         * Core event manager proxy
         *
         * @var \Magento\Framework\Event\ManagerInterface
         */
        protected $_eventManager;
    
        /**
         * Customer session
         *
         * @var \Magento\Customer\Model\Session
         */
        protected $_customerSession;
    
        /**
         * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
         */
        protected $_localeDate;
    
        /**
         * Store manager
         *
         * @var \Magento\Store\Model\StoreManagerInterface
         */
        protected $_storeManager;
    
        /**
         * Rule factory
         *
         * @var \Magento\CatalogRule\Model\ResourceModel\RuleFactory
         */
        protected $_ruleFactory;
    
        /**
         * @var PriceCurrencyInterface
         */
        protected $priceCurrency;
    
        /**
         * @var GroupManagementInterface
         */
        protected $_groupManagement;
    
        /**
         * @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory
         */
        protected $tierPriceFactory;
    
        /**
         * @var \Magento\Framework\App\Config\ScopeConfigInterface
         */
        protected $config;
    
        /**
         * @var ProductTierPriceExtensionFactory
         */
        private $tierPriceExtensionFactory;
    
        /**
         * Constructor
         *
         * @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $ruleFactory
         * @param \Magento\Store\Model\StoreManagerInterface $storeManager
         * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
         * @param \Magento\Customer\Model\Session $customerSession
         * @param \Magento\Framework\Event\ManagerInterface $eventManager
         * @param PriceCurrencyInterface $priceCurrency
         * @param GroupManagementInterface $groupManagement
         * @param ProductTierPriceInterfaceFactory $tierPriceFactory
         * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
         * @param ProductTierPriceExtensionFactory|null $tierPriceExtensionFactory
         */
        public function __construct(
            \Magento\CatalogRule\Model\ResourceModel\RuleFactory $ruleFactory,
            \Magento\Store\Model\StoreManagerInterface $storeManager,
            \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
            \Magento\Customer\Model\Session $customerSession,
            \Magento\Framework\Event\ManagerInterface $eventManager,
            PriceCurrencyInterface $priceCurrency,
            GroupManagementInterface $groupManagement,
            ProductTierPriceInterfaceFactory $tierPriceFactory,
            \Magento\Framework\App\Config\ScopeConfigInterface $config,
            ProductTierPriceExtensionFactory $tierPriceExtensionFactory = null
        ) {
            parent::__construct(
                $ruleFactory,
                $storeManager,
                $localeDate,
                $customerSession,
                $eventManager,
                $priceCurrency,
                $groupManagement,
                $tierPriceFactory,
                $config,
                $tierPriceExtensionFactory
            );
        }
        
        /**
         * Gets the 'tier_price' array from the product
         *
         * @param Product $product
         * @param string $key
         * @param bool $returnRawData
         * @return array
         */
        protected function getExistingPrices($product, $key, $returnRawData = false)
        {
            $prices = $product->getData($key);
            
            if ($prices === null) {
                $attribute = $product->getResource()->getAttribute($key);
                if ($attribute) {
                    $attribute->getBackend()->afterLoad($product);
                    $prices = $product->getData($key);
                }
            }
    
            if ($prices === null || !is_array($prices)) {
                return ($returnRawData ? $prices : []);
            }
    
            if ($key == 'tier_price' && !empty($prices)) {
                $prevTier = $product->getData($key);
               
                //custom tier prices array
                $result = [
                    [
                        "website_id"=>0,
                        "customer_group_id"=>32000,
                        "qty"=>2.0000,
                        "price_value_type"=>'fixed',
                        'value'=>35.0000,
                        'store_id'=>1
                    ]
                ];
    
                $prevTiers = [];
                if (!empty($prevTier)) {
                    foreach ($prevTier as $prev) {
                        $newKey = $prev["website_id"]."-".
                            $prev["all_groups"]."-".
                            $prev["cust_group"];
                        $prevTiers[$newKey] = $prev;
                    }
                }
                if (!empty($result)) {
                    foreach ($result as $tier) {
                        $allGroup = ($tier["customer_group_id"] != "32000")? "0" : "1";
                        $genKey = $tier["website_id"]."-".$allGroup."-".
                            $tier["customer_group_id"];
                        
                        if (array_key_exists($genKey, $prevTiers)) {
                            $each = [];
                            $each["price_id"]   = $prevTiers[$genKey]["price_id"] ?? 0;
                            $each["website_id"] = $tier["website_id"]        ?? "0";
                            $each["all_groups"] = $allGroup                  ?? "0";
                            $each["cust_group"] = $tier["customer_group_id"] ?? "0";
                            $each["price_qty"]  = $tier["qty"]               ?? "0";
        
                            $each["percentage_value"]=$prevTiers[$genKey][
                                "percentage_value"] ?? null;
                            $each["price"]           = $prevTiers[$genKey]["price"]
                                ?? "0";
                            $each["website_price"] = $prevTiers[$genKey]["website_price"]
                                ?? "0";
        
                            if ($tier["price_value_type"] == "fixed") {
                                $each["percentage_value"] = null;
                                $each["price"]            = $tier["value"] ?? "0";
                                $each["website_price"]    = $tier["value"] ?? "0";
                            }
                            if ($tier["price_value_type"] == "percent") {
                                $each["percentage_value"] = $tiers["value"]      ?? "0";
                                $each["price"] = $prevTiers[$genKey]["price"] ?? "0";
                                $each["website_price"] = $prevTiers[$genKey][
                                    "website_price"] ?? "0";
                            }
                            $prices[] = $each;
                        }
                    }
                }
            }
            
            return $prices;
        }
    }

    3. Create MinimalTierPriceCalculator.php file inside the app/code/Vendor/CustomModule/Plugin/Catalog/Pricing/Price/ directory. In this file, we will create ‘aroundGetValue’ plugin method of ‘getValue’ method of Magento\Catalog\Pricing\Price\MinimalTierPriceCalculator class.

    <?php
    /**
     * Vendor Desc.
     * php version 7.3.*
     *
     * @category  Vendor
     * @package   Vendor_CustomModule
     * @author    Vendor
     * @copyright Vendor (https://example.com)
     * @license   https://example.com/license.html
     */
    namespace Venodr\CustomModule\Plugin\Catalog\Pricing\Price;
    
    use Magento\Framework\Pricing\SaleableInterface;
    
    class MinimalTierPriceCalculator
    {
        /**
         * Get raw value of "as low as" as a minimal among tier prices{@inheritdoc}
         *
         * @param \Magento\Catalog\Pricing\Price\MinimalTierPriceCalculator $subject
         * @param \Closure $proceed
         * @param SaleableInterface $saleableItem
         *
         * @return float|null
         */
        
        public function aroundGetValue(
            \Magento\Catalog\Pricing\Price\MinimalTierPriceCalculator $subject,
            \Closure $proceed,
            SaleableInterface $saleableItem
        ) {
            $tierPrices        = [];
            $productTierPrices = [];
            $productTierPrices = $saleableItem->getTierPrices();
            
            if (!empty($productTierPrices)) {
                $result = [
                    [
                        "website_id"=>0,
                        "customer_group_id"=>32000,
                        "qty"=>2.0000,
                        "price_value_type"=>'fixed',
                        'value'=>35.0000,
                        'store_id'=>1
                    ]
                ];
                if (!empty($result)) {
                    foreach ($result as $tier) {
                        $tierPrices[] = $tier["value"];
                    }
                    if (!empty($tierPrices)) {
                        return $tierPrices ? min($tierPrices) : null;
                    }
                }
            }
            
            return $proceed($saleableItem);
        }
    }

    4. Create ChangeTierPriceInfo.php file inside the app/code/Vendor/CustomModule/Plugin/Catalog/Pricing/Price/ directory. In this file, we will create ‘aroundGetValue’ plugin method of ‘getValue’ method of \Magento\Catalog\Pricing\Price\FinalPrice Class.

    <?php
    /**
     * Vendor Desc.
     * php version 7.3.*
     *
     * @category  Vendor
     * @package   Vendor_CustomModule
     * @author    Vendor
     * @copyright Vendor (https://example.com)
     * @license   https://example.com/license.html
     */
    namespace Vendor\CustomModule\Plugin\Catalog\Pricing\Price;
    
    use Magento\Framework\Session\SessionManagerInterface;
    use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory;
    use Magento\Framework\Stdlib\CookieManagerInterface;
     
    class ChangeTierPriceInfo
    {
        /**
         * @var \Magento\Catalog\Model\Product
         */
        protected $productModel;
    
        /**
         * @var \Magento\Framework\App\RequestInterface
         */
        protected $request;
    
        /**
         * Constructor
         *
         * @param \Magento\Catalog\Model\Product $productModel
         * @param \Magento\Framework\App\RequestInterface $request
         */
        public function __construct(
            \Magento\Catalog\Model\Product $productModel,
            \Magento\Framework\App\RequestInterface $request
        ) {
            $this->request      = $request;
            $this->productModel = $productModel;
        }
    
        /**
         * Get price value
         *
         * @param \Magento\Catalog\Pricing\Price\FinalPrice $subject
         * @param \Closure $proceed
         *
         * @return void
         */
        public function aroundGetValue(
            \Magento\Catalog\Pricing\Price\FinalPrice $subject,
            \Closure $proceed
        ) {
            $finalTierPrice = [];
            
            $productId = $this->request->getParam("id") ?? 0;
            $product   = $this->productModel->load($productId);
        
            $productObj = $subject->getProduct();
            $prevTier   = $productObj->getData("tier_price");
            $prevTiers = [];
    
            if (!empty($prevTier)) {
                foreach ($prevTier as $prev) {
                    $newKey = $prev["website_id"]."-".$prev["all_groups"].
                        "-".$prev["cust_group"];
                    $prevTiers[$newKey] = $prev;
                }
            }
            
            //custom tier prices array
            $result = [
                [
                    "website_id"=>0,
                    "customer_group_id"=>32000,
                    "qty"=>2.0000,
                    "price_value_type"=>'fixed',
                    'value'=>35.0000,
                    'store_id'=>1
                ]
            ];
                
            if (!empty($result)) {
                foreach ($result as $tier) {
                    $allGroup = ($tier["customer_group_id"] != "32000")? "0" : "1";
                    $genKey = $tier["website_id"]."-".$allGroup."-".
                        $tier["customer_group_id"];
                    if (array_key_exists($genKey, $prevTiers)) {
                        $each = [];
                        $each["price_id"]   = $prevTiers[$genKey]["price_id"] ?? 0;
                        $each["website_id"] = $tier["website_id"]        ?? "0";
                        $each["all_groups"] = $allGroup                  ?? "0";
                        $each["cust_group"] = $tier["customer_group_id"] ?? "0";
                        $each["price_qty"]  = $tier["qty"]               ?? "0";
    
                        $each["percentage_value"] = $prevTiers[$genKey][
                            "percentage_value"] ?? null;
                        $each["price"] = $prevTiers[$genKey]["price"] ?? "0";
                        $each["website_price"]    = $prevTiers[$genKey][
                            "website_price"] ?? "0";
    
                        if ($tier["price_value_type"] == "fixed") {
                            $each["percentage_value"] = null;
                            $each["price"]            = $tier["value"] ?? "0";
                            $each["website_price"]    = $tier["value"] ?? "0";
                        }
                        if ($tier["price_value_type"] == "percent") {
                            $each["percentage_value"] = $tiers["value"]   ?? "0";
                            $each["price"] = $prevTiers[$genKey]["price"] ?? "0";
                            $each["website_price"]    = $prevTiers[$genKey][
                                "website_price"] ?? "0";
                        }
                        $finalTierPrice[] = $each;
                    }
                }
            }
    
            //set modified tier prices array in product data
            if (!empty($productObj->getData('tier_price')) && !empty($finalTierPrice)) {
                $productObj->setData('tier_price', $finalTierPrice);
            }
            
            return $proceed();
        }
    }

    5. See the result in the following images. Here, we have created a product and set the tier price to $40 as displayed in the image. After overriding the tier price, It will display $35 as in the following image.

    Searching for an experienced
    Magento 2 Company ?
    Read More
    tier1
    Created product and set price $50
    tier2
    Added tier price
    result1
    Overridden Tier price on product page
    result2
    Overridden Tier Price on category product page

    Hope this will be helpful. Thanks 🙂

    Previous Blog: Override Product Special Price in Magento 2

    . . .
    Discuss on Helpdesk

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top