Back to Top

Add custom sales rule conditions in Magento 2

Updated 27 April 2023

Hello Friends!!

In today’s blog, we will add custom sales rule conditions in the configuration of the custom module.

Sales Rule conditions – It allows us to create dynamic conditions for the shopping carts.

Example – I am going to create conditions for the customer groups as It’s showing in the below images.

Screenshot-2022-05-25T102550.759

First of all, we will create an observer that will add our condition.

Searching for an experienced
Magento 2 Company ?
Find out More

So we need to create an “events.xml” file inside the etc folder and add the below code into the file.

<event name="salesrule_rule_condition_combine">
        <observer name="customer_groups" instance="Vendor\Module\Observer\CustomerGroupsObserver" />
</event>

Now, we will create “CustomerGroupsObserver.php” inside the observer folder.

namespace Vendor\Module\Observer;

/**
 * Observer for CustomerGroups
 */
class CustomerGroupsObserver implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * Execute observer.
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return $this
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $additional = $observer->getAdditional();
        $conditions = (array) $additional->getConditions();

        $conditions = array_merge_recursive($conditions, [
            $this->getCustomerGroupsCondition()
        ]);

        $additional->setConditions($conditions);
        return $this;
    }

    /**
     * Get condition for customer groups.
     *
     * @return array
     */
    private function getCustomerGroupsCondition()
    {
        return [
            'label'=> __('Customer groups'),
            'value'=> \Vendor\Module\Model\Rule\Condition\CustomerGroups::class
        ];
    }
}

Now, we can move on to the logic part which is responsible for our condition.

We need to add the below code into the di.xml.

<type name="Vendor\Module\Model\Rule\Condition\CustomerGroups">
        <arguments>
            <argument name="data" xsi:type="array">
                <item name="form_name" xsi:type="string">sales_rule_form</item>
            </argument>
        </arguments>
</type>

At Last, We will create one more file named “CustomerGroups.php”.

namespace Vendor\Module\Model\Rule\Condition;

/**
 * Customer Groups model
 */
class CustomerGroups extends \Magento\Rule\Model\Condition\AbstractCondition
{
    /**
     * @var \Magento\Customer\Model\ResourceModel\Group\CollectionFactory
     */
    protected $groupCollectionFactory;

    /**
     * Constructor initialise
     *
     * @param \Magento\Rule\Model\Condition\Context $context
     * @param \Magento\Customer\Model\ResourceModel\Group\CollectionFactory $groupCollectionFactory
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Framework\Json\Helper\Data $jsonHelper
     * @param array $data
     */
    public function __construct(
        \Magento\Rule\Model\Condition\Context $context,
        \Magento\Customer\Model\ResourceModel\Group\CollectionFactory $groupCollectionFactory,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Json\Helper\Data $jsonHelper,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->_groupCollectionFactory = $groupCollectionFactory;
        $this->scopeConfig = $scopeConfig;
        $this->_json = $jsonHelper;
    }

    /**
     * Load attribute options
     *
     * @return $this
     */
    public function loadAttributeOptions()
    {
        $this->setAttributeOption([
            'customer_groups' => __('Customer groups')
        ]);
        return $this;
    }

    /**
     * Get input type
     *
     * @return string
     */
    public function getInputType()
    {
        return 'multiselect';
    }

    /**
     * Get value element type
     *
     * @return string
     */
    public function getValueElementType()
    {
        return 'multiselect';
    }

    /**
     * Get value select options
     *
     * @return array|mixed
     */
    public function getValueSelectOptions()
    {
        if (!$this->hasData('value_select_options')) {
            $this->setData(
                'value_select_options',
                $this->_groupCollectionFactory->create()
                ->addFieldToFilter('customer_group_id', ['neq' => 0])
                ->loadData()->toOptionArray()
            );
        }
        return $this->getData('value_select_options');
    }

    /**
     * Validate Customer Group Rule Condition
     *
     * @param \Magento\Framework\Model\AbstractModel $model
     * @return bool
     */
    public function validate(\Magento\Framework\Model\AbstractModel $model)
    {
        $currentCustomerGroup = $this->getCurrentCustomerGroup();
        $conditions = $this->getOrderApprovalConditions();
        
        foreach ($conditions['conditions'] as $key => $value) {
            if (is_string($key)) {
                $stringKeys = $key;
                $attribute  = $conditions['conditions'][$stringKeys]['attribute'];
                if ($attribute == 'customer_groups') {
                    $attributeValue  = $conditions['conditions'][$stringKeys]['value'];
                }
            }
        }
        $validateGroups = 0;
        if (in_array($currentCustomerGroup, $attributeValue)) {
            $validateGroups = 1;
        }
        $model->setData('customer_groups', $validateGroups);
        return parent::validate($model);
    }

    /**
     * Get current Customer group
     *
     * @return string
     */
    public function getCurrentCustomerGroup()
    {
        if ($this->customerSession->isLoggedIn()) {
            $customerGroup = $this->customerSession->getCustomer()->getGroupId();
            return $customerGroup;
        }
    }
    
   /**
     * Get order approval conditions
     *
     * @return array|boolean
     */
    public function getOrderApprovalConditions()
    {
        $conditions =  $this->scopeConfig->getValue(
            "order_approval/settings/condition",
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );
        
        if ($conditions) {
            return $this->_json->jsonDecode($conditions);
        }

        return false;
    }
}

After this, Clear the cache and check. The condition will be added successfully which looks like the below-added image.

Screenshot-2022-05-25T102529.129

That’s all about the custom sales rule condition. Hope this will be helpful.

If you have any questions please comment below, and we will try to respond to you. Thanks! 🙂

. . .

Leave a Comment

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


2 comments

  • riddhi
    • Ritika Singh (Moderator)
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home