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.
Hope this will be helpful. Thanks 🙂
Previous Blog: Override Product Special Price in Magento 2
Be the first to comment.