3

I need to add a dynamic condition to the catalog price rules.

For example:

  • Special Price From Date equals or greater than TODAY

enter image description here

I think it is not a big deal once figure out the right files to be edited, I just need a couple of hint ...

UPDATE:

I managed to save the value {TODAY}.

enter image description here

The only change required is the edit to the following function in Mage_Rule_Model_Condition_Abstract

  public function getValue()
    {
        if ($this->getInputType() == 'date' && !$this->getIsValueParsed() && $this->getData('value') == '{TODAY}') {
            $this->setIsValueParsed(true);
        }

        if ($this->getInputType() == 'date' && !$this->getIsValueParsed() && $this->getData('value') != '{TODAY}') {
            // date format intentionally hard-coded
            $this->setValue(
                Mage::app()->getLocale()->date($this->getData('value'),
                    Varien_Date::DATE_INTERNAL_FORMAT, null, false)->toString(Varien_Date::DATE_INTERNAL_FORMAT)
            );
            $this->setIsValueParsed(true);
        }
        return $this->getData('value');
    }

So the next step is to find the place where the value is used in the rule processing.

UPDATE-2

I have managed to make the value dynamic during the validation

It looks that the condition is evaluated in Mage_Rule_Model_Condition_Abstract::validateAttribute($validatedValue)

  • $validatedValue is the product attribute value that we want to evaluate.

In the same class we can change the following method in order to use our custom variable {TODAY} for the validation.

public function getValueParsed()
{
    if (!$this->hasValueParsed()) {
        $value = $this->getData('value');

        if ($value == '{TODAY}') {
            $value = Mage::app()->getLocale()->date(Mage::getModel('core/date')->date(),
                Varien_Date::DATE_INTERNAL_FORMAT, null, false)->toString(Varien_Date::DATE_INTERNAL_FORMAT);

        } else if ($this->isArrayOperatorType() && is_string($value)) {
            $value = preg_split('#\s*[,;]\s*#', $value, null, PREG_SPLIT_NO_EMPTY);
        }

        $this->setValueParsed($value);
    }
    return $this->getData('value_parsed');
}

UPDATE-3

The modification to this function looks the last effort (Modifications done in Update-2 should not be necessary)

Mage_Rule_Model_Condition_Product_Abstract

public function validate(Varien_Object $object)
{
    $attrCode = $this->getAttribute();

    if ('category_ids' == $attrCode) {
        return $this->validateAttribute($object->getAvailableInCategories());
    } elseif (! isset($this->_entityAttributeValues[$object->getId()])) {
        if (!$object->getResource()) {
            return false;
        }
        $attr = $object->getResource()->getAttribute($attrCode);

        if ($attr && $attr->getBackendType() == 'datetime' &&  $this->getValue() == '{TODAY}') {
            $today = Mage::getModel('core/date')->date();
            $today = Mage::app()->getLocale()->date($today,
                Varien_Date::DATE_INTERNAL_FORMAT, null, false)->toString(Varien_Date::DATE_INTERNAL_FORMAT);
            $this->setValue($today);
        }

        if ($attr && $attr->getBackendType() == 'datetime' && !is_int($this->getValue()) && $this->getValue() != '{TODAY}') {
            $this->setValue(strtotime($this->getValue()));
            $value = strtotime($object->getData($attrCode));
            return $this->validateAttribute($value);
        }

        if ($attr && $attr->getFrontendInput() == 'multiselect') {
            $value = $object->getData($attrCode);
            $value = strlen($value) ? explode(',', $value) : array();
            return $this->validateAttribute($value);
        }

        return parent::validate($object);
    } else {
        $result = false; // any valid value will set it to TRUE
        // remember old attribute state
        $oldAttrValue = $object->hasData($attrCode) ? $object->getData($attrCode) : null;

        foreach ($this->_entityAttributeValues[$object->getId()] as $storeId => $value) {
            $attr = $object->getResource()->getAttribute($attrCode);
            if ($attr && $attr->getBackendType() == 'datetime') {
                $value = strtotime($value);
            } else if ($attr && $attr->getFrontendInput() == 'multiselect') {
                $value = strlen($value) ? explode(',', $value) : array();
            }

            $object->setData($attrCode, $value);
            $result |= parent::validate($object);

            if ($result) {
                break;
            }
        }

        if (is_null($oldAttrValue)) {
            $object->unsetData($attrCode);
        } else {
            $object->setData($attrCode, $oldAttrValue);
        }

        return (bool) $result;
    }
}

UPDATE-4

There is still one issue: The second time I save the rule the {TODAY} variable is changed into a date (this is caused by some JS but I'm not able to understand witch one )

1
  • 1
    Did you find the issue here? Maybe you want to copy all the updates to an answer and mark it as solutionß – Fabian Blechschmidt Apr 3 '14 at 22:22
0

Not sure if this is strictly allowed or not but since these rules are generating a database query you could insert the database function for the current date (based on database server time) eg: if you're using a mySQL database you could insert CURDATE()

I'm a Magento Noob so please let me know if this is wrong in any way - I tested this on my Magento install and it seemed to work :)

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