Skip to content

Latest commit

 

History

History

CatalogRuleApi

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Create Catalog Price Rule in REST API In Magento 2

Magento 2 Catalog Price Rule is not exposed as a REST API End Point. Catalog Price Rule API feature is an important feature for those who work in Creating Mobile App and Third Party Integration. Though this feature is not available we can extend magento core with our custom code to expose this API End Point. Lets see how to achieve this with our custom code.

Goal

Step By Step Tutorials

  • app/code/Bdcrops/CatalogRuleApi/registration.php

    Source
    <?php
        \Magento\Framework\Component\ComponentRegistrar::register(
            \Magento\Framework\Component\ComponentRegistrar::MODULE,
            'Bdcrops_CatalogRuleApi',
            __DIR__
        );
    
  • app/code/Bdcrops/CatalogRuleApi/etc/module.xml

    Source
    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Bdcrops_CatalogRuleApi" setup_version="1.0.0"/>
    </config>
    
    
  • app/code/Bdcrops/CatalogRuleApi/etc/webapi.xml

    Source
    ```
    <?xml version="1.0"?>
    <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
        <route url="/V1/catalogRules/:ruleId" method="GET">
            <service class="Magento\CatalogRule\Api\CatalogRuleRepositoryInterface" method="get"/>
            <resources>
                <resource ref="anonymous" />
            </resources>
        </route>
    	<route url="/V1/catalogRules/search" method="GET">
            <service class="Bdcrops\CatalogRuleApi\Api\CatalogRuleRepositoryInterface" method="getList"/>
            <resources>
                <resource ref="anonymous" />
            </resources>
        </route>
        <route url="/V1/catalogRules/:ruleId" method="DELETE">
            <service class="Magento\CatalogRule\Api\CatalogRuleRepositoryInterface" method="deleteById"/>
            <resources>
                <resource ref="anonymous" />
            </resources>
        </route>
        <route url="/V1/catalogRules/:ruleId" method="PUT">
            <service class="Magento\CatalogRule\Api\CatalogRuleRepositoryInterface" method="save"/>
            <resources>
                <resource ref="anonymous" />
            </resources>
        </route>
        <route url="/V1/catalogRules" method="POST">
            <service class="Magento\CatalogRule\Api\CatalogRuleRepositoryInterface" method="save"/>
            <resources>
                <resource ref="anonymous" />
            </resources>
        </route>
    </routes>
    ```
    </details>
    

    we need to create an webapi.xml file to define the REST API End Points.

    The Core Magento 2 CatalogRule module already contains the necessary code for carrying out the API Operation in the below files, only drawback is those methods were not exposed as webapi end points. Lets define the REST API route path as “catalogRules”.

    Though the main methods are all available in magento core, the “getList” method is not available by default and we will implement it separately. For this demo i am skipping the ACL Part and defining the “resource ref” as anonymous

    Magento 2 Core Files Reference:- Magento\CatalogRule\Api\interface\CatalogRuleRepositoryInterface

    Magento\CatalogRule\Model\Rule.php

  • app/code/Bdcrops/CatalogRuleApi/Api/CatalogRuleRepositoryInterface.php

    Source
    <?php
    namespace Bdcrops\CatalogRuleApi\Api;
    
    use \Magento\Framework\Api\SearchCriteriaInterface;
    
    interface CatalogRuleRepositoryInterface {
        /**
         * Get rules
         * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
         * @return \Magento\Framework\Api\SearchResultsInterface
         */
         public function getList(
           \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria);
    
    }
    
    
  • app/code/Bdcrops/CatalogRuleApi/etc/di.xml

    Source
    <?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="Bdcrops\CatalogRuleApi\Api\CatalogRuleRepositoryInterface"
    	            type="Bdcrops\CatalogRuleApi\Model\CatalogRuleManagement" />
        <preference for="Magento\CatalogRule\Api\CatalogRuleRepositoryInterface"
                	type="Magento\CatalogRule\Model\CatalogRuleRepository" />
    
    </config>
    
  • Result

At this point now we can execute the below REST API methods V1/catalogRules/:ruleId GET, DELETE, POST, PUT. But the problem here is the GET Method returns data without website_ids and customer_group_ids as show in the below screenshot.

  • app/code/Bdcrops/CatalogRuleApi/etc/extension_attributes.xml

    Source
    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
        <extension_attributes for="Magento\CatalogRule\Api\Data\RuleInterface">
            <attribute code="website_ids" type="int[]"/>
            <attribute code="customer_group_ids" type="int[]"/>
        </extension_attributes>
    </config>
    
    
  • app/code/Bdcrops/CatalogRuleApi/Api/Data/RuleExtensionInterface.php

    Source
    <?php
    
    namespace Bdcrops\CatalogRuleApi\Api\Data;
    
    interface RuleExtensionInterface {
        /**
         * @return \Magento\CatalogRule\Api\Data\RuleExtensionInterface
         */
        public function getWebsiteIds();
       /**
        * @param \Magento\CatalogRule\Api\Data\RuleExtensionInterface[]
        * @return $this
        */
       public function setWebsiteIds();
      /**
        * @return \Magento\CatalogRule\Api\Data\RuleExtensionInterface
        */
        public function getCustomerGroupIds();
       /**
        * @param \Magento\CatalogRule\Api\Data\RuleExtensionInterface[]
        * @return $this
        */
    	public function setCustomerGroupIds();
    
    }
    
    
  • app/code/Bdcrops/CatalogRuleApi/etc/di.xml

    Source
    <?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="Bdcrops\CatalogRuleApi\Api\CatalogRuleRepositoryInterface"
                type="Bdcrops\CatalogRuleApi\Model\CatalogRuleManagement" />
      <preference for="Magento\CatalogRule\Api\CatalogRuleRepositoryInterface"
              	type="Magento\CatalogRule\Model\CatalogRuleRepository" />
    <!-- Plugin to Hook the Get Method -->
      <type name="Magento\CatalogRule\Api\CatalogRuleRepositoryInterface">
          <plugin name="bdcrops_add_websitecustomerids_extension_attribute" type="Bdcrops\CatalogRuleApi\Plugin\CatalogRuleRepositoryPlugin" />
      </type>
    </config>
    
    
  • app/code/Bdcrops/CatalogRuleApi/Plugin/CatalogRuleRepositoryPlugin.php

    Source
    <?php
    
    namespace Bdcrops\CatalogRuleApi\Plugin;
    
    use Magento\CatalogRule\Api\Data\RuleExtensionFactory;
    use Magento\CatalogRule\Api\Data\RuleExtensionInterface;
    use Magento\CatalogRule\Api\Data\RuleInterface;
    use Magento\CatalogRule\Api\CatalogRuleRepositoryInterface;
    /**
     * Class CatalogRuleRepositoryPlugin
     */
    class CatalogRuleRepositoryPlugin {
        /**
         * Rule Extension Attributes Factory
         *
         * @var RuleExtensionFactory
         */
        protected $extensionFactory;
    
        /**
         * CatalogRuleRepositoryPlugin constructor
         *
         * @param RuleExtensionFactory $extensionFactory
         */
        public function __construct(RuleExtensionFactory $extensionFactory) {
            $this->extensionFactory = $extensionFactory;
        }
    
        /**
         * Add "customer_group_ids" and "website_ids" extension attributes to catalog rule object to make it accessible in API data
         *
         * @param CatalogRuleRepositoryInterface $subject
         * @param RuleInterface $rule
         *
         * @return RuleInterface
         */
        public function afterGet(CatalogRuleRepositoryInterface $subject, RuleInterface $rule)
        {
            $websiteIds  = $rule->getData('website_ids');
            $customerGroupIds = $rule->getCustomerGroupIds();
            $extensionAttributes = $rule->getExtensionAttributes();
            $extensionAttributes = $extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();
            $extensionAttributes->setWebsiteIds($websiteIds);
            $extensionAttributes->setCustomerGroupIds($customerGroupIds);
            $rule->setExtensionAttributes($extensionAttributes);
    
            return $rule;
        }
    
    	/**
         * Add "customer_group_ids" and "website_ids" extension attributes to catalog rule object to make it accessible in API data
         *
         * @param CatalogRuleRepositoryInterface $subject
         * @param RuleInterface $rule
         *
         * @return array
         */
    	public function beforeSave(
        CatalogRuleRepositoryInterface $subject, RuleInterface $rule) {
    
    
    		$extensionAttributes = $rule->getExtensionAttributes() ?: $this->extensionFactory->create();
            if ($extensionAttributes !== null && $extensionAttributes->getWebsiteIds() !== null) {
                $rule->setWebsiteIds($extensionAttributes->getWebsiteIds());
            }
    		if ($extensionAttributes !== null && $extensionAttributes->getCustomerGroupIds() !== null) {
                $rule->setCustomerGroupIds($extensionAttributes->getCustomerGroupIds());
            }
            return [$rule];
        }
    }
    
    
  • app/code/Bdcrops/CatalogRuleApi/Model/CatalogRuleManagement.php

    Source
    ```
    <?php
    
    namespace Bdcrops\CatalogRuleApi\Model;
    
    use \Magento\CatalogRule\Model\RuleFactory;
    use \Bdcrops\CatalogRuleApi\Api\CatalogRuleRepositoryInterface;
    
    class CatalogRuleManagement implements CatalogRuleRepositoryInterface {
        /**
         * @var RuleFactory
         */
        protected $_catalogRuleFactory;
    
        /**
         * @var \Magento\Framework\Api\SearchResultsInterface
         */
        protected $searchResultsFactory;
        /**
         * @var array
         */
        private $rules = [];
    
        /**
         * @param RuleFactory $catalogRuleFactory
         * @param \Magento\Framework\Api\SearchResultsInterface $searchResultsFactory
         * @param DataObjectHelper $dataObjectHelper
         * @param DataObjectProcessor $dataObjectProcessor
         */
        public function __construct(
            RuleFactory $catalogRuleFactory,
            \Magento\Framework\Api\SearchResultsInterface $searchResultsFactory,
            \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
            \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
        ) {
    
             $this->_catalogRuleFactory = $catalogRuleFactory;
             $this->searchResultsFactory = $searchResultsFactory;
             $this->dataObjectHelper = $dataObjectHelper;
             $this->dataObjectProcessor = $dataObjectProcessor;
          }
    
        /**
         * @api
         * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
         * @return \Magento\Framework\Api\SearchResultsInterface
         */
        public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
        {
    
            $searchResults = $this->searchResultsFactory; //->create();
            $searchResults->setSearchCriteria($searchCriteria);
    
            $catalogRule = $this->_catalogRuleFactory->create();
            $catalogRuleCollection = $catalogRule->getCollection();
    
            foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
                $fields = [];
                $conditions = [];
                foreach ($filterGroup->getFilters() as $filter) {
                    $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
                    $fields[] = $filter->getField();
                    $conditions[] = [$condition => $filter->getValue()];
                }
                if ($fields) {
                    $catalogRuleCollection->addFieldToFilter($fields, $conditions);
                }
            }
    
            $searchResults->setTotalCount($catalogRuleCollection->getSize());
            $catalogRuleCollection->setCurPage($searchCriteria->getCurrentPage());
            $catalogRuleCollection->setPageSize($searchCriteria->getPageSize());
    
            foreach($catalogRuleCollection as $ruleModel)
            {
    
                $catalogRuleData = $this->_catalogRuleFactory->create();
                $this->rules[] = $ruleModel->getData();
            }
    
            $this->searchResultsFactory->setItems($this->rules);
            return $this->searchResultsFactory;
    
        }
    }
    
    ```
    

Ref