HIDE PRODUCT PRICING AND ADD TO CART BUTTON FOR SPECIFIC CUSTOMERS GROUP

In our previous blog named How to allow add to cart button to logged in customers only we described how to make ADD TO CART visible only for logged in customers. In this article, we go further and will make a module so that we can hide the price and Add to cart button for Specific customer groups.

Here we are going to fulfill these two purposes

  1. Hide product pricing on the front-end for customers until they are logged in.
  2. Hide product pricing and add to cart button for customers of specific customer groups.

As we know, until a customer logs in, Magento treats that customer as “NOT LOGGED IN” so we can achieve this from a specific customers group, so we don’t need to take separate actions.

Let’s start by creating a module, in this module, we will create an admin part where we can select the customer group for whom we want to hide ADD TO CART button and Price.

So, let’s start by creating an admin part.

Step 1: Create registration.php under app/code/Bizspice/HideProductattr

<?php
  \Magento\Framework\Component\ComponentRegistrar::register(  
  \Magento\Framework\Component\ComponentRegistrar::MODULE,
 'Bizspice_HideProductattr',
 __DIR__
 ); 

Step 2: Create module.xml under app/code/Bizspice/HideProductattr/etc

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> <module name="Bizspice_HideProductattr" setup_version="1.0.0">
   <sequence>
      <module name="Magento_Sales"/>
   </sequence>
 </module>
</config> 


Step 3: 
Create system.xml for creating admin setting inside app/code/Bizspice/HideProductattr/etc/adminhtml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
	<system>
		<section id="catalog">
			<group id="available" translate="label" type="text" sortOrder="991" showInDefault="1" showInWebsite="1" showInStore="1">
				<label>Product Available</label>
				<field id="hide_add_to_cart" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
						<label>Hide Add To Cart</label>
						<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
					</field>
					<field id="hide_add_to_cart_groups" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
						<label>Hide from Groups</label>
						<source_model>Bizspice\HideProductattr\Model\Config\Source\Customer\Group</source_model>
						<depends>
							<field id="hide_add_to_cart">1</field>
						</depends>
					</field>
					<field id="hide_price" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
						<label>Hide price</label>
						<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
					</field>
					<field id="hide_price_groups" translate="label" type="multiselect" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
						<label>Hide from Groups</label>
						<source_model>Bizspice\HideProductattr\Model\Config\Source\Customer\Group</source_model>
						<depends>
							<field id="hide_price">1</field>
						</depends>
					</field>
				</group>
			</section>
		</system>
	</config> 

Here we have created two multiselect fields for selecting customer group, one for hiding the Add to cart button and another for the Price button.

Step 4: Create config.xml for the field we have created in system.xml for enable/disable

Create in app/code/Bizspice/HideProductattr/etc

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
	<default>
		<catalog>
			<available>
				<hide_add_to_cart>1</hide_add_to_cart>
				<hide_add_to_cart_groups>0</hide_add_to_cart_groups>
				<hide_price>1</hide_price>
				<hide_price_groups>0</hide_price_groups>
			</available>
		</catalog>
	</default>
</config>

Step 5: Now create the source model for the customer group we have mentioned in system.xml, so that the multiselect field of the customer group can load customer group

For this create

Group.php in

app/code/Bizspice\HideProductattr\Model\Config\Source\Customer

<?php
namespace BizspiceHideProductattrModelConfigSourceCustomer;
use MagentoFrameworkOptionArrayInterface;
use MagentoCustomerModelResourceModelGroupCollectionFactory;
class Group implements ArrayInterface
{
	protected $_options;
	protected $_collectionFactory;
	public function __construct(CollectionFactory $collectionFactory)
	{
		$this->_collectionFactory = $collectionFactory;
	}

	public function toOptionArray()
	{
		if (null === $this->_options) {
			$groups = $this->_collectionFactory->create();
			$this->_options = $groups->toOptionArray();
		}

		return $this->_options;
	}
}

Now when you go to Catalog tab inside Store > Configuration you will find something like this

From here, we can select the customer group for which we want to hide the Add to Cart and Price buttons.

Now, as our admin work is done, we will work for Frontend.

Step 6: Now, we can achieve this through events so that whenever our product collection loads or our product load on the product page, or whenever we add the product to the cart, we will check which customer group we have to restrict.

So, create events.xml in app/code/Bizspice/HideProductattr/etc/frontend

<?xml version="1.0"?>
 <config
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
	<event name="catalog_product_is_salable_after">
		<observer name="product_hide_add_price" instance="Bizspice\HideProductattr\Observer\SalableObserver" />
	</event>
	<event name="sales_quote_product_add_after">
		<observer name="product_hide_add_price" instance="Bizspice\HideProductattr\Observer\QuoteObserver" />
	</event>
	<event name="catalog_product_collection_load_after">
		<observer name="product_hide_add_price" instance="Bizspice\HideProductattr\Observer\CollectionObserver" />
	</event>
	<event name="catalog_product_load_after">
		<observer name="product_hide_add_price" instance="Bizspice\HideProductattr\Observer\ProductObserver" />
	</event>
</config> 

Here we have created four observers for four different events.

Step 7: Let’s create some functions which we are going to use in our all observers. As we need these in all four observers, we will create a helper and access them in all observers, thus reducing the repetition of code.

Create Data.php in app/code/Bizspice/HideProductattr/Helper

<?php
namespace BizspiceHideProductattrHelper;
use MagentoStoreModelScopeInterface;
use MagentoFrameworkAppHelperAbstractHelper;
use MagentoFrameworkAppHelperContext;
use MagentoCustomerModelSession;
class Data extends AbstractHelper
{
	const XML_CONFIG_HIDE_ADD_TO_CART = 'catalog/available/hide_add_to_cart';
	const XML_CONFIG_HIDE_ADD_TO_CART_GROUPS = 'catalog/available/hide_add_to_cart_groups';
	const XML_CONFIG_HIDE_PRICE = 'catalog/available/hide_price';
	const XML_CONFIG_HIDE_PRICE_GROUPS = 'catalog/available/hide_price_groups';
	protected $_session;
/** 
  * Initialize Helper 
  * 
  * @param Context $context 
  * @param Session $session 
  */
	public function __construct(Context $context, Session $session)
	{
		$this->_session = $session;
		parent::__construct($context);
	}
/** 
 * Check Whether The Customer Allows Add To Cart 
 *
 * @return bool 
 */
	public function isAvailableAddToCart()
	{
		if ($this->_getConfig(self::XML_CONFIG_HIDE_ADD_TO_CART)) {
			return !in_array($this->_session->getCustomerGroupId() , explode(',', $this->_getConfig(self::XML_CONFIG_HIDE_ADD_TO_CART_GROUPS)));
		}
		return true;
	}
	/**
  * Check Whether The Customer Allows Price
  *
  * @return bool 
  */
	public function isAvailablePrice()
	{
		if ($this->_getConfig(self::XML_CONFIG_HIDE_PRICE)) {
			return !in_array($this->_session->getCustomerGroupId() , explode(',', $this->_getConfig(self::XML_CONFIG_HIDE_PRICE_GROUPS)));
		}
		return true;
	}
	/** 
  * Retrieve Store Configuration Data
  * 
  * @param string $path 
  * @return string|null 
  */
	protected function _getConfig($path)
	{
		return $this->scopeConfig->getValue($path, ScopeInterface::SCOPE_STORE);
	}
}

Step 8: Create observers now

  1. CollectionObserver.php in app/code/Bizspice/HideProductattr/Observer
<?php
 namespace BizspiceHideProductattrObserver;
 use MagentoFrameworkEventObserver; 
 use MagentoFrameworkEventObserverInterface;
 use BizspiceHideProductattrHelperData as ProductHelper;
 class CollectionObserver implements ObserverInterface
 {
 protected $_helper;
 public function __construct(ProductHelper $helper) {
 $this->_helper = $helper;
 }
 public function execute(Observer $observer) {
 if (!$this->_helper->isAvailablePrice()) {
 $collection = $observer->getEvent()->getCollection();
 foreach($collection as $product) {
   $product->setCanShowPrice(false);
 }
 }
 } 
}

2. ProductObserver.php in app/code/Bizspice/HideProductattr/Observer

<?php
 namespace BizspiceHideProductattrObserver;
 use MagentoFrameworkEventObserver;
 use MagentoFrameworkEventObserverInterface;
 use BizspiceHideProductattrHelperData as ProductHelper;
 class ProductObserver implements ObserverInterface
 {
 protected $_helper;
 public function __construct(ProductHelper $helper) {
 $this->_helper = $helper;
 }
 public function execute(Observer $observer) {
 if (!$this->_helper->isAvailablePrice()) {
 $product = $observer->getEvent()->getProduct();
 $product->setCanShowPrice(false); 
} 
}
 }

3. ProductObserver.php in app/code/Bizspice/HideProductattr/Observer

<?php namespace BizspiceHideProductattrObserver;
use MagentoFrameworkEventObserver;
use MagentoFrameworkEventObserverInterface;
use BizspiceHideProductattrHelperData as ProductHelper;
use MagentoFrameworkExceptionLocalizedException;
class QuoteObserver implements ObserverInterface
{
protected $_helper;
public function __construct(ProductHelper $helper) {
$this->_helper = $helper;
 }
public function execute(Observer $observer) {
 if (!$this->_helper->isAvailableAddToCart()) {
 throw new LocalizedException(__('You can not add products to cart.')); 
}
 }
 }

4. SalableObserver.php in app/code/Bizspice/HideProductattr/Observer

<?php
 namespace BizspiceHideProductattrObserver;
 use MagentoFrameworkEventObserver;
 use MagentoFrameworkEventObserverInterface;
 use BizspiceHideProductattrHelperData as ProductHelper;
 class SalableObserver implements ObserverInterface
 {
 protected $_helper;
 public function __construct(ProductHelper $helper) {
 $this->_helper = $helper;
 }
 public function execute(Observer $observer) {
 if (!$this->_helper->isAvailableAddToCart()) {
 $salable = $observer->getEvent()->getSalable();
 $salable->setIsSalable(false);
 }
 }
 }

Done, now you can hide the Add to cart and Price buttons for the customer groups you choose in the admin.