Do you often work with pricing rules in Magento 2? For example, you need to implement the complex rules when a customer gets the discount which depends on the customer’s previous order total amount.

While everything is clear enough with the rules in Magento, there is no default functionality in Magento 2 that can help set up complex pricing rules for the customer entity. Say, in Magento 2, you can set the rules which depend on the customer’s’ gender, a country which the customer is from, and the other parameters. But if we talk about complex pricing rules, we should use additional modules for Magento 2 to set them.

However, even in this case, not every module can cope with this task by default. Today we’ll show how we solved this problem, and you’ll learn the useful method of how to implement pricing rules in Magento 2 using the Amasty_RulesPro module.

Task: Create Pricing Rules in Magento 2

Our task was to apply the pricing rule to all clients which belong to one company. A company is a custom entity which the client connected with by the company_id custom attribute. For these purposes, we used Amasty_RulesPro module.

Amasty_RulesPro module for Magento 2 extends Magento SalesRule functionality, in particular, it allows you to use any customer entity’s attributes. However, you can face the problem with the attributes that are not static. Let’s consider the reason and solution for this problem.

The Reason for Non-Static Attributes Error in Amasty_RulesPro

Condition validation is implemented invalidate() method, of Amasty\RulesPro\Model\Rule\Condition\customer. You can implement this method as follows:

public function validate(\Magento\Framework\Model\AbstractModel $model)
    {
        $customer = $model;
        if (!$customer instanceof \Magento\Customer\Model\Customer) {
            $customer = $model->getQuote()->getCustomer();
            $attr = $this->getAttribute();

            $allAttr = $customer->__toArray();

            if ($attr == 'membership_days') {
                //$customer->setData($attr, $this->getMembership($customer->getCreatedAt()));
                $allAttr[$attr] = $this->getMembership($customer->getCreatedAt());
            }
            if ($attr != 'entity_id' && !array_key_exists($attr, $allAttr)){
                $address = $model->getQuote()->getBillingAddress();
                $allAttr[$attr] = $address->getData($attr);
            }
            $customer = $this->_objectManager->create('Magento\Customer\Model\Customer')->setData($allAttr);
        }
        return parent::validate($customer);
    }

In case the transferred model is not a \Magento\Customer\Model\Customer subclassing, this entity is got from the Quote object. But in Magento 2, getCustomer() method of \Magento\Quote\Model\Quote class returns the entity of \Magento\Customer\Model\Data\Customer type. This entity stores non-static attributes not in _data, but _data[‘custom_attributes’] that causes the logical error in validation, so the rule doesn’t work. Let’s look at the solution to this problem.

How to Create Custom Rules in Magento 2 Using Amasty_RulesPro

In order to cope with this task, we should develop a plugin for the Amasty\RulesPro\Model\Rule\Condition\customer entity.

So, we determine the plugin in di.xml file.

<type name="Amasty\RulesPro\Model\Rule\Condition\Customer">
        <plugin name="customer-validation" type="Web4pro\Corporate\Plugin\Customer" sortOrder="10"/>
    </type>

The plugin’s implementation is the following:

class Customer {

    protected $_customer;

    public function __construct(\Magento\Customer\Model\Customer $customer){
        $this->_customer = clone $customer;
    }

public function beforeValidate($conditionModel, $model){
        $customer = $model;
        if (!($customer instanceof \Magento\Customer\Model\Customer)) {
            $customer = $model->getQuote()->getCustomer();
            $attr = $conditionModel->getAttribute();

            $allAttr = $customer->__toArray();

            if ($attr == 'membership_days') {
                $allAttr[$attr] = $conditionModel->getMembership($customer->getCreatedAt());
            }
            if ($attr != 'entity_id' && !array_key_exists($attr, $allAttr)){
                $address = $model->getQuote()->getBillingAddress();
                $allAttr[$attr] = $address->getData($attr);
            }
            foreach($customer->getCustomAttributes() as $key=>$attribute){
                $allAttr[$key] = $attribute->getValue();
            }

            $customer = $this->_customer->unsetData()->addData($allAttr);
            return array($customer);
        }
       return array($model);
    }
}

This plugin implements a beforeValidate() method with two parameters: $conditionModel and $model. If the $model is not an entity of \Magento\Customer\Model\Customer type, it will be replaced by the \Magento\Customer\Model\Customer type with all attributes’ values which the entity should have for the particular custom shopping cart. Plugin method returns it to validate() method of the class for validation. As we can’t transfer ObjectManager to the plugin constructor, we transfer it to the entity of ObjectManager type. We clone it, clean up, and write all data of the current customer for the particular shopping cart.

Summary

As you can see, there are no limitations for web development on Magento. We work with Magento 2 and helped lots of our clients with Magento 2 Development. If you are looking for the best solutions for your store functionality our WEB4PRO team is ready to give you a hand.

Have luck and create complex pricing rules in Magento 2!

5.00 / 5.0
Article rating (0 Reviews)
Do you find this article useful? Please, let us know your opinion and rate the post!
Not badGoodVery GoodGreatAwesome