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! ?
I have 2 questions.
1. what if we want to validate multi conditional (if-and-if), should we do loop validate method?
2. if we have ‘multiselect’ on ValueElementType, how to validate it too?
thanks
For your customization requirement, you can contact on support@magecomp.com
Very good article. Thanks for sharing.
Why do we have to define form_name in di.xml ? It works without defining it in di.xml.
According to Magento standard we need to specify it.
Buenas tardes, como implementaría esto pero para el rule catalogo de magento?
Para la regla del catálogo, debe personalizar aún más el código. Para obtener más información, puede contactar en support@magecomp.com
After using this code, I am getting infinite loop error while firing setPaymentMethod using graphql query in adobe commerce.
Kindly check, does the code conflict with another things into the system or not.