General

How to Create Custom Sales Rule Condition in Magento 2

Many times while selling products online you have to enable your shipping service for limited areas only. Due to Higher shipping/export rates, banned products, strict customs laws or tough cash handling this all results in admin to restrict order shipping to limited areas. Luckily, using Magento 2 you can create shopping cart rules that allow you to check for dynamic conditions

However, if you want to create your custom shopping cart rules that trigger specific code in reaction to that event. To do the same you have to create your custom extension to fulfil your business needs as we never recommended to modify core files. Let’s take an example of settings up custom sales rules for the city field of the shopping cart page. You can also create custom shopping cart rules for different events.

To do the same first, we need to create “events.xml” file inside etc folder and add paste below code in that file.

app\code\Vendor\Extension\etc\events.xml

<?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="salesrule_rule_condition_combine">

    <observer name="customer_rule" 
instance="Vendor\Extension\Observer\Shippingcityconditionobserver" />
    </event>
</config>

Now, we create “Shippingcityconditionobserver.php” inside observer folder.

app\code\Vendor\Extension\Observer\Shippingcityconditionobserver.php

<?php
namespace Vendor\Extension\Observer;

class Shippingcityconditionobserver implements \Magento\Framework\Event\ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $additional = $observer->getAdditional();
        $conditions = (array) $additional->getConditions();

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

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

    private function getCustomerFirstOrderCondition()
    {
        return [
            'label'=> __('Shipping city'),
            'value'=> \Vendor\Extension\Model\Rule\Condition\Shippingcity::class
        ];
    }
}

Create one more file “di.xml” file at the following path.

app\code\Vendor\Extension\etc\di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

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

Lastly, create one more file named “Shippingcity.php” at this location.

app\code\Vendor\Extension\Model\Rule\Condition\Shippingcity.php

<?php
namespace Vendor\Extension\Model\Rule\Condition;
class Shippingcity extends \Magento\Rule\Model\Condition\AbstractCondition
{

    protected $_checkoutSession;

    public function __construct(
        \Magento\Rule\Model\Condition\Context $context,
        \Magento\Checkout\Model\Session $checkoutSession,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->_checkoutSession = $checkoutSession;
    }

public function loadAttributeOptions()
    {
        $this->setAttributeOption([
            'shipping_city' => __('Shipping city')
        ]);
        return $this;
    }

    public function getInputType()
    {
       return 'select';  // input type for admin condition
    }

    public function getValueElementType()
    {
        return 'text';
    }

    public function validate(\Magento\Framework\Model\AbstractModel $model)
    {
        $city = $this->_checkoutSession->getQuote()->getShippingAddress()->getCity();
        $model->setData('shipping_city', $city);  // validation value
        return parent::validate($model);
    }
}

Simply clear the cache and you will find an option in admin backend. You can also play with the above code to create different kinds of custom shipping rules.

Lastly, if you found this blog helpful, don’t forget to share it with your colleagues and Magento Friends and Let us know if you are facing any issue while implementing this code.

Happy Coding! ?

 

Click to rate this post!
[Total: 19 Average: 4]
Dhiren Vasoya

Dhiren Vasoya is a Director and Co-founder at MageComp, Passionate 🎖️ Certified Magento Developer👨‍💻. He has more than 9 years of experience in Magento Development and completed 850+ projects to solve the most important E-commerce challenges. He is fond❤️ of coding and if he is not busy developing then you can find him at the cricket ground, hitting boundaries.🏏

View Comments

Recent Posts

Magento 2: Add Quantity Increment and Decrement on Category Page

Hello Magento Friends, In this blog, we will discuss about adding quantity increment and decrement…

17 mins ago

How to Integrate ChatGPT with Laravel Application?

In this guide, we'll explore how to integrate ChatGPT, an AI-powered chatbot, with a Laravel…

3 days ago

What are Net Sales? How to Calculate Your Net Sales?

In the world of business, understanding financial metrics is crucial for making informed decisions and…

5 days ago

Magento 2 Extensions Digest April 2024 (New Release & Updates)

Welcome to the MageComp Monthly Digest, where we bring you the latest updates, releases, and…

5 days ago

The ABCs of Geofencing: Definition, Features and Uses

In this era, businesses are always on the lookout for ways to engage with their…

6 days ago

How to Delete Product Variant in a Shopify Remix App using GraphQL Mutations?

Managing a Shopify store efficiently involves keeping your product catalog organized. This includes removing outdated…

7 days ago