0

Need to add new condition in validate() function of module-sales-rule/Model/Rule/Condition/Address.php by overriding this class in custom module.

This function is called on checkout page in frontend when cart price rule is applied via 'Free Shipping'

I have tried using both preference & plugin but both not working

Please advice, It will be really grateful as I am in a bad situation

namespace Companyname\Subtotalwithdiscount\Model\Rule\Condition;

class Address extends \Magento\SalesRule\Model\Rule\Condition\Address
{

    public function loadAttributeOptions()
    { 
        $attributes = [
            'base_subtotal' => __('Subtotal'),
            'base_subtotal_with_discount' => __('Subtotal with discount'),
            'total_qty' => __('Total Items Quantity'),
            'weight' => __('Total Weight'),
            'shipping_method' => __('Shipping Method'),
            'postcode' => __('Shipping Postcode'),
            'region' => __('Shipping Region'),
            'region_id' => __('Shipping State/Province'),
            'country_id' => __('Shipping Country'),
        ];

        $this->setAttributeOption($attributes);

        return $this;
    }

    /**
     * Get attribute element
     *
     * @return $this
     */
    public function getAttributeElement()
    {
        $element = parent::getAttributeElement();
        $element->setShowAsText(true);
        return $element;
    }

    /**
     * Get input type
     *
     * @return string
     */
    public function getInputType()
    {
        switch ($this->getAttribute()) {
            case 'base_subtotal':
            case 'base_subtotal_with_discount':
            case 'weight':
            case 'total_qty':
                return 'numeric';

            case 'shipping_method':
            case 'payment_method':
            case 'country_id':
            case 'region_id':
                return 'select';
        }
        return 'string';
    }

    /**
     * Get value element type
     *
     * @return string
     */
    public function getValueElementType()
    {
        switch ($this->getAttribute()) {
            case 'shipping_method':
            case 'payment_method':
            case 'country_id':
            case 'region_id':
                return 'select';
        }
        return 'text';
    }

    /**
     * Get value select options
     *
     * @return array|mixed
     */
    public function getValueSelectOptions()
    { 
        if (!$this->hasData('value_select_options')) {
            switch ($this->getAttribute()) {
                case 'country_id':
                    $options = $this->_directoryCountry->toOptionArray();
                    break;

                case 'region_id':
                    $options = $this->_directoryAllregion->toOptionArray();
                    break;

                case 'shipping_method':
                    $options = $this->_shippingAllmethods->toOptionArray();
                    break;

                case 'payment_method':
                    $options = $this->_paymentAllmethods->toOptionArray();
                    break;

                default:
                    $options = [];
            }
            $this->setData('value_select_options', $options);
        }
        return $this->getData('value_select_options');
    }

    /**
     * Validate Address Rule Condition
     *
     * @param \Magento\Framework\Model\AbstractModel $model
     * @return bool
     */
    public function validate(\Magento\Framework\Model\AbstractModel $model)
    { 
        $address = $model;
        if (!$address instanceof \Magento\Quote\Model\Quote\Address) {
            if ($model->getQuote()->isVirtual()) {
                $address = $model->getQuote()->getBillingAddress();
            } else {
                $address = $model->getQuote()->getShippingAddress();
            }
        }

        if ('payment_method' == $this->getAttribute() && !$address->hasPaymentMethod()) {
            $address->setPaymentMethod($model->getQuote()->getPayment()->getMethod());
        }

        // This below code is getting called from vendor file instead of this overridden file

        $baseTotalWithDiscount = $address->getBaseSubtotal() + $address->getDiscountAmount();
        $address->setBaseSubtotalWithDiscount($baseTotalWithDiscount);

        return parent::validate($address);
    }
}
  • when cart price rule is applied via 'Free Shipping' means cart rule apply free Shipping? – Amit Bera Sep 4 at 9:02
  • Yes, I have set condition in cart price rule to give users free shipping when price > 25 – Arjun Sep 4 at 9:05
  • this magento default feature. Is this not working? – Amit Bera Sep 4 at 9:07
  • It is working, but my issue is I added new option 'Subtotal with discount' by overriding file as in my question, now when I go to checkout page the validate() function should be called from new file. But it is getting called from vendor file, except validate() all functions are working fine. – Arjun Sep 4 at 9:14
0

As you are using return parent::validate($address); that means you have the calling the parent class method \Magento\SalesRule\Model\Rule\Condition\Address::validate since Companyname\Subtotalwithdiscount\Model\Rule\Condition\Address's parent class is \Magento\SalesRule\Model\Rule\Condition\Address .

So, you have to change the return of this method

return \Magento\Rule\Model\Condition\AbstractCondition::validate($address);

From

return parent::validate($address);

  • I changed the return in the override file Companyname\Subtotalwithdiscount\Model\Rule\Condition\Address but the issue is as it doesn't enter the validate() function so making a change in return does not make any change. – Arjun Sep 4 at 9:38
  • have u try to print log inside Companyname\Subtotalwithdiscount\Model\Rule\Condition\Address::validate? – Amit Bera Sep 4 at 9:41
  • Yes, it works perfectly when I try to add product to cart, but when I go to checkout there it gets called fom vendor & log doesn't get printed. – Arjun Sep 4 at 9:50
  • That means that time call \Magento\SalesRule\Model\Rule\Condition\Address::validate calling? – Amit Bera Sep 4 at 10:17
  • In short, the validate() function is called twice once on product detail page when I add product to cart at that time it is working perfectly from Companyname\Subtotalwithdiscount\Model\Rule\Condition file, second time this validate() is called on checkout page which should ideally get called from override file but not getting called, it is getting called from vendor file – Arjun Sep 4 at 10:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.