0

I want to override validate() function of this file

vendor/magento/module-sales-rule/Model/Rule/Condition/Address.php

in my custom module file

app/code/Companyname/Subtotalwithdiscount/Model/Rule/Condition/Address.php

I am able to override all other function using Preference, also overridden validate function is been called on product details page but not getting called on one step checkout page.

Below is the code of custom - module

<?php

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);
    }
}
7
  • you should be able to override it. Are you sure the original method is called somewhere?
    – Marius
    Sep 3, 2019 at 5:09
  • Yes @Marius, Actually I have created a Free Shipping rule when price is > 25, on one step checkout page this validate() is been called. According to logic this validate() should be called from custom module file but it is getting called from vendor file.
    – Arjun
    Sep 3, 2019 at 5:32
  • maybe you should add the code you wrote to the question
    – Marius
    Sep 3, 2019 at 5:43
  • okay, I am adding it, thanks for great advice, it will help people understand more clearly the issue.
    – Arjun
    Sep 3, 2019 at 5:47
  • @Marius Did you get any idea of what could be the reason of validate() not getting called?
    – Arjun
    Sep 4, 2019 at 12:45

2 Answers 2

0

I think your validate method is probably working within the scope of your module and maybe the values you are concerned about are coming from a model within module-quote instead of the module-sales-rule.

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

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

Seems like those values are coming from the TotalsCollector model from module-quote and not from your overridden validate method.

Have you looked at the collect method @line 67 in the vendor/magento/module-sales-rule/Model/Quote/Discount.php?

Have you looked at the collectAddressTotals method @line 247 in the vendor/magento/module-quote/Model/Quote/TotalsCollector.php?

Hope this information helps you solve your puzzle!

0

Kindly check your module sequence in /etc/module.xml

Your custom module should be added in sequence node

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Companyname_Subtotalwithdiscount" >
        <sequence>
            <module name="Magento_Checkout"/> 
        </sequence>
    </module>
</config>

Please try this and let me know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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