Select Page

How to add custom sales rule conditions in Magento 2

Shweta Singh
Published: May 20, 2022

Hello Friends!!

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

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

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

Screenshot-2022-05-14T123156.401

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

Searching for an experienced
Magento 2 Company ?
Read 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="Webkul\OrderApproval\Observer\CustomerGroupsObserver" />
</event>

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

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'=> \Webkul\OrderApproval\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="Webkul\OrderApproval\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”.

class CustomerGroups extends \Magento\Rule\Model\Condition\AbstractCondition
{
    /**
     * @var \Magento\Customer\Model\ResourceModel\Group\CollectionFactory
     */
    protected $groupCollectionFactory;
    /**
     * @var \Webkul\OrderApproval\Helper\Data
     */
    protected $helper;
    /**
     * Constructor initialise
     *
     * @param \Magento\Rule\Model\Condition\Context $context
     * @param \Magento\Customer\Model\ResourceModel\Group\CollectionFactory $groupCollectionFactory
     * @param \Webkul\OrderApproval\Helper\Data $helper
     * @param array $data
     */
    public function __construct(
        \Magento\Rule\Model\Condition\Context $context,
        \Magento\Customer\Model\ResourceModel\Group\CollectionFactory $groupCollectionFactory,
        \Webkul\OrderApproval\Helper\Data $helper,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->_groupCollectionFactory = $groupCollectionFactory;
        $this->helper = $helper;
    }
    /**
     * 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->helper->getCurrentCustomerGroup();
        $conditions = $this->helper->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);
    }
}

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

Screenshot-2022-05-14T123125.551

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! 🙂

Source: webkul.com