5

When you create a coupon code in Magento 1 or Magento 2 (a "Shopping Cart Price Rule"), you can set date range where the coupon is valid from/to. This information is stored in the salesrule table, and Magento appears to respect it. (i.e. if the end date has passed, Magento won't let you apply the coupon code)

However, Magento stores the actual codes for an individual sales rule in the salesrule_coupon table. This table includes a field named expiration_date which seems like it would be a way to set expiration dates on specific coupon codes with a sales rule. However, Magento does not (seem to?) respect this field.

Does anyone know what this field is for? Does it work and I'm just doing it wrong? Is it tracking something else? etc.

2
  • 2
    I checked Magento EE, seem that it's related to module vendor/magento/module-reminder. Commented Jul 20, 2016 at 5:15
  • I am facing the same issue any luck? Commented Aug 24, 2020 at 14:04

4 Answers 4

1

I know this post is old, but may have a short term solution for M1 and could possibly be very similar for M2. I hate copying core code to the local scope but since this is a short term solution on M1, I think it should be perfectly suitable:

  1. Copy app/core/Mage/SalesRule/Model/Validator.php to app/local/Mage/SalesRule/Model/Validator.php

  2. Update the method _canProcessRule($rule, $address) (see comment: Modified - coupon expiry check start):


    /**
     * Check if rule can be applied for specific address/quote/customer
     *
     * @param   Mage_SalesRule_Model_Rule $rule
     * @param   Mage_Sales_Model_Quote_Address $address
     * @return  bool
     */
    protected function _canProcessRule($rule, $address)
    {
        if ($rule->hasIsValidForAddress($address) && !$address->isObjectNew()) {
            return $rule->getIsValidForAddress($address);
        }

        /**
         * check per coupon usage limit
         */
        if ($rule->getCouponType() != Mage_SalesRule_Model_Rule::COUPON_TYPE_NO_COUPON) {
            $couponCode = $address->getQuote()->getCouponCode();
            if (strlen($couponCode)) {
                $coupon = Mage::getModel('salesrule/coupon');
                $coupon->load($couponCode, 'code');
                if ($coupon->getId()) {
                    // check entire usage limit
                    if ($coupon->getUsageLimit() && $coupon->getTimesUsed() >= $coupon->getUsageLimit()) {
                        $rule->setIsValidForAddress($address, false);
                        return false;
                    }
                    // check per customer usage limit
                    $customerId = $address->getQuote()->getCustomerId();
                    if ($customerId && $coupon->getUsagePerCustomer()) {
                        $couponUsage = new Varien_Object();
                        Mage::getResourceModel('salesrule/coupon_usage')->loadByCustomerCoupon(
                            $couponUsage,
                            $customerId,
                            $coupon->getId()
                        );
                        if ($couponUsage->getCouponId() &&
                            $couponUsage->getTimesUsed() >= $coupon->getUsagePerCustomer()
                        ) {
                            $rule->setIsValidForAddress($address, false);
                            return false;
                        }
                    }

                    /**
                     * Modified - coupon expiry check start
                     */
                    
                    // Validate individual coupon expiry date
                    // Currently does not exist in M1 or M2
                    $tz = Mage::getStoreConfig('general/locale/timezone');

                    $dateNow = new DateTime('now', new DateTimeZone($tz));
                    $dateCouponExpiry = new DateTime($coupon->getExpirationDate(), new DateTimeZone($tz));

                    if ($dateCouponExpiry <= $dateNow) {
                        $rule->setIsValidForAddress($address, false);
                        return false;
                    }

                    /**
                     * Modified - coupon expiry check end
                     */
                }
            }
        }

        /**
         * check per rule usage limit
         */
        $ruleId = $rule->getId();
        if ($ruleId && $rule->getUsesPerCustomer()) {
            $customerId     = $address->getQuote()->getCustomerId();
            $ruleCustomer   = Mage::getModel('salesrule/rule_customer');
            $ruleCustomer->loadByCustomerRule($customerId, $ruleId);
            if ($ruleCustomer->getId()) {
                if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) {
                    $rule->setIsValidForAddress($address, false);
                    return false;
                }
            }
        }
        $rule->afterLoad();
        /**
         * quote does not meet rule's conditions
         */
        if (!$rule->validate($address)) {
            $rule->setIsValidForAddress($address, false);
            return false;
        }
        /**
         * passed all validations, remember to be valid
         */
        $rule->setIsValidForAddress($address, true);
        return true;
    }

I will eventually be doing the same on M2 but if anyone wants to attempt, it should be as simple as creating a DI for <preference for="Magento\SalesRule\Model\Utility" type="Your\Module\Model\SalesRule\Utility" /> and implementing the similar logic in the method canProcessRule($rule, $address)

0

Based on the comments above, it seems like this field may be used for an Enterprise Edition feature.

2
  • any solution for the same? Commented Aug 24, 2020 at 14:03
  • I have tried changing the expiration_date to past date. The coupon is still applying. what you have used to set the expiration date of the coupons?
    – amitshree
    Commented Jul 28, 2021 at 8:05
0

So far, it is also used in Community Edition. If you change expiration_date field to 0000-00-00 00:00:00 or to other past date in the table, the coupon code would not work even if from_date and to_date are valid.

2
  • have you found any solution? Commented Aug 24, 2020 at 14:04
  • I have tried changing the date to past date but coupon is still applying. Any solution?
    – amitshree
    Commented Jul 28, 2021 at 8:03
0

Based on comments above, For magento 2.4 the function is canProcessRule from SalesRule/Model/Utility.php

 if ($coupon->getId()) {
                // check entire usage limit
                if ($coupon->getUsageLimit() && $coupon->getTimesUsed() >= $coupon->getUsageLimit()) {
                    $rule->setIsValidForAddress($address, false);
                    return false;
                }
                // check per customer usage limit
                $customerId = $address->getQuote()->getCustomerId();
                if ($customerId && $coupon->getUsagePerCustomer()) {
                    $couponUsage = $this->objectFactory->create();
                    $this->usageFactory->create()->loadByCustomerCoupon(
                        $couponUsage,
                        $customerId,
                        $coupon->getId()
                    );
                    if ($couponUsage->getCouponId() &&
                        $couponUsage->getTimesUsed() >= $coupon->getUsagePerCustomer()
                    ) {
                        $rule->setIsValidForAddress($address, false);
                        return false;
                    }
                }
                
                // ADDED EXPIRY CHECK
                $dateCouponExpiry = strtotime($coupon->getExpirationDate());
                if ($dateCouponExpiry <= time()) {
                    $rule->setIsValidForAddress($address, false);
                    return false;
                }
            }

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.