Author - Dane Lowe

I am a freelance web developer specialising in Magento and Zend Framework development.

More Info »

Reader Comments (29)

  1. loopion
    February 23, 2011 at 4:31 am /

    Which Magento version does it apply?

    Reply
  2. Franky
    Franky
    March 17, 2011 at 6:32 am /

    Thanks for your great code. Based on your code, I added some more for sales rule not using coupon.

    <?php
    class Orchid_CouponFix_Model_Observer
    {
        public function cancel($observer)
        {
    	$event = $observer->getEvent();
          	$order = $event->getPayment()->getOrder();
            if ($order->canCancel()) {
    		if ($code = $order->getCouponCode()) {
    			$coupon = Mage::getModel('salesrule/rule')->load($code, 'coupon_code');
    			$coupon->setTimesUsed($coupon->getTimesUsed()-1);
    			$coupon->save();
    			if($customerId = $order->getCustomerId()) {
    				if ($customerCoupon = Mage::getModel('salesrule/rule_customer')->loadByCustomerRule($customerId, $coupon->getId())) {
    					$customerCoupon->setTimesUsed($customerCoupon->getTimesUsed()-1);
    					$customerCoupon->save();
    				}
    			}
    		}
    //below is added by franky
    	if ($rules = $order->getAppliedRuleIds()) {
    	foreach(explode(",", $rules) as $rule_id){
    			$rule = Mage::getModel('salesrule/rule')->load($rule_id);
    			$rule->setTimesUsed($rule->getTimesUsed()-1);
    			$rule->save();
    
    			if($customerId = $order->getCustomerId()) {
    				if ($customerCoupon = Mage::getModel('salesrule/rule_customer')->loadByCustomerRule($customerId, $rule_id)) {
    					$customerCoupon->setTimesUsed($customerCoupon->getTimesUsed()-1);
    					$customerCoupon->save();
    				}
    			}
    		}
    	}
    	}
        }
    }
    
    Reply
  3. Steve
    June 20, 2011 at 12:44 pm /

    Hi guys, this all looks great and am just about to give it a shot. Love the fact it doens’t overwrite anything etc.

    One question, could you also do the same for orders that cancel and have products in them that have only 1 left?

    If a customer goes to the cart with something we only have one left of, and cancels that order for any reason ni the checkout, that item is still marked out of stock until we run our stock updater which can be a few hours that the product is not available.

    For people who don’t update their stock daily or even longer, this could be a bigger problem.

    Thanks in advance.

    Reply
    1. Javier
      Javier
      July 21, 2011 at 2:00 am /

      Steve, which version are you using?

      Reply
  4. Steve
    July 21, 2011 at 2:42 am /

    1.4.1.1 i think

    Reply
  5. Steve
    July 21, 2011 at 2:43 am /

    1.4.1.1 im sure!

    Reply
  6. Darrell
    Darrell
    August 18, 2011 at 5:45 am /

    Anyone get this to work on 1.4.1.1? Doesn’t seem to do anything… uploaded the files, set proper permissions, no difference…

    Reply
    1. Darrell
      Darrell
      August 18, 2011 at 6:01 am /

      using paypal redirect for payment

      Reply
  7. Darrell
    Darrell
    August 23, 2011 at 4:22 pm /

    ^ anyone?

    Reply
  8. Jack
    Jack
    August 29, 2011 at 1:55 am /

    Tried it and tested. Didnt seem to make any difference on my site. 1.4.2

    Reply
  9. Daniel
    Daniel
    October 14, 2011 at 1:56 am /

    Thanks a lot for that fix. Tested it on a 1.5.0.1 installation and it worked like a charm.

    Reply
  10. Rafael Kutscha
    December 31, 2011 at 12:27 am /

    Does not seem to work with magento > 1.4.2.0 – > the tablefield “coupon_code” is now part of table “salesrule_coupon”!

    PHP-Error: Column not found: 1054 Unknown column ‘salesrule.coupon_code’ in ‘where clause’

    Reply
  11. Julio Rosier
    January 3, 2012 at 1:59 pm /

    Forgot to tell I have magneto 1.6.1

    Reply
  12. Julio Rosier
    January 3, 2012 at 2:02 pm /

    I have the following error message when changing payment method afther installing files

    Thanks

    SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘salesrule.coupon_code’ in ‘where clause’

    Trace:
    #0 /home/juliorosie/domains/mooibootje.com/public_html/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
    #1 /home/juliorosie/domains/mooibootje.com/public_html/lib/Zend/Db/Statement.php(300): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
    #2 /home/juliorosie/domains/mooibootje.com/public_html/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)

    Reply
  13. Gurdeep
    Gurdeep
    March 9, 2012 at 8:30 pm /

    Has anybody got this working in Magento CE 1.6.1?
    This problem still occurs in 1.6.1 and would like to know if anyone has had any joy getting this working?

    Thanks

    Reply
  14. Hervé
    April 21, 2012 at 3:02 am /

    Hello,

    I ‘ve also the error :
    SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘salesrule.coupon_code’ in ‘where clause’
    with a magento 1.4.1.1

    I correct it like this :
    As the field “coupon_code” is not a field of the table “salesrule_rule” but a field of “salesrule_coupon ”
    Replace :
    $coupon = Mage::getModel(‘salesrule/rule’)->load($code, ‘coupon_code’);
    By :
    $couponId = Mage::getModel(‘salesrule/coupon’)->load($code, ‘code’)->getRuleId();
    $coupon = Mage::getModel(‘salesrule/rule’)->load($couponId);

    If it could help 😉

    Reply
  15. Tom Herrick
    Tom Herrick
    July 11, 2012 at 6:25 am /

    Because our coupons are sometimes set up for single use per customer, I had to add some additional code to clear out the times_used values in salesrule_coupon_usage and salesrule_customer values as well. Here’s what I came up with…

      public function cancel($observer)
      {
        $event = $observer->getEvent();
        $order = $event->getPayment()->getOrder();
        if ($order->canCancel()) {
          if ($code = $order->getCouponCode()) {
            $coupon = mage::getModel('salesrule/coupon')->load($code, 'code');
            if ($coupon->getTimesUsed() > 0) {
              $coupon->setTimesUsed($coupon->getTimesUsed()-1);
              $coupon->save();
            }
    
            $rule = Mage::getModel('salesrule/rule')->load($coupon->getRuleId());
            error_log("\nrule times used=" . $rule->getTimesUsed(),3,"var/log/debug.log");
            if ($rule->getTimesUsed() > 0) {
              $rule->setTimesUsed($rule->getTimesUsed()-1);
              $rule->save();
            }
            if($customerId = $order->getCustomerId()) {
              if ($customerCoupon = Mage::getModel('salesrule/rule_customer')->loadByCustomerRule($customerId, $rule->getId())) {
                $couponUsage = new Varien_Object();
                Mage::getResourceModel('salesrule/coupon_usage')->loadByCustomerCoupon($couponUsage, $customerId, $coupon->getId());
    
                if ($couponUsage->getTimesUsed() > 0) {
    
                  /* I can't find any #@$!@$ interface to do anything but increment a coupon_usage record */
                  $resource = Mage::getSingleton('core/resource');
                  $writeConnection = $resource->getConnection('core_write');
                  $tableName = $resource->getTableName('salesrule_coupon_usage');
    
                  $query = "UPDATE {$tableName} SET times_used = times_used-1 " .
                    " WHERE coupon_id = {$coupon->getId()} AND customer_id = {$customerId} AND times_used > 0";
    
                  $writeConnection->query($query);
                }
                if ($customerCoupon->getTimesUsed() > 0) {
                  $customerCoupon->setTimesUsed($customerCoupon->getTimesUsed()-1);
                  $customerCoupon->save();
                }
              }
            }
          }
        }
      }
    
    Reply
  16. bolfab
    bolfab
    October 30, 2012 at 10:45 am /

    Hello friends,

    I’ve got a similar problem with a store running magento 1.6.0. Unique coupon can’t be used once again when order remain pending.
    Thought this fix would save my life but unfortunately, doesnt seem to work. Is there a way to check if the script is running when I cancel my order and do you have any idea on how to make it work properly with 1.6 ???
    If it could help, in order to be able to use the coupon another time, i have to delete lines in sql database at salesrule_coupon_usage AND salesrule_customer.
    Hope to hear from you sooon !
    Fab

    Reply
    1. Rabe'e AbdelWahab
      February 14, 2013 at 3:58 am /

      I guess this is what you are looking for, working on 1.5 because i had some problem with the code above.

          public function retrieveCoupon($observer)
          {
              $payment = $observer->getEvent()->getPayment();
              $order = $payment->getOrder();
      
              if ($code = $order->getCouponCode()) {
                  $coupon = Mage::getModel('salesrule/coupon')->load($code, 'code');
                  $coupon->setTimesUsed($coupon->getTimesUsed()-1);
                  $coupon->save();
                  
                  $write = Mage::getSingleton('core/resource')->getConnection('core_write');
                  $query = "UPDATE salesrule_coupon_usage SET times_used = times_used-1 WHERE customer_id='".$order->getCustomerId()."' AND coupon_id='".$coupon->getId()."'";
                  $result = $write->query($query);
                  
                  if($customerId = $order->getCustomerId()) {
                      if ($customerCoupon = Mage::getModel('salesrule/rule_customer')->loadByCustomerRule($customerId, $coupon->getRuleId())) {
                          $customerCoupon->setTimesUsed($customerCoupon->getTimesUsed()-1);
                          $customerCoupon->save();
                      }
                  }
              }
          }
      
      Reply
  17. Luke
    March 18, 2013 at 2:43 pm /

    This looks like exactly what I need, however it looks like it’s only compatible with 1.4, has anyone here found a solution that would work on 1.7+? We are having this issue with customers paying through paypal and it happens on a regular basis.

    Any help/guidance on this would be much appreciated.

    Reply
  18. PJ
    PJ
    June 2, 2015 at 10:35 pm /

    I have fixed the observer for Magento 1.7+. Here is the code; https://gist.github.com/peterjaap/bf9aa2086f06a1a41fa1

    Reply
  19. MANIK
    January 15, 2016 at 10:15 pm /

    Hi,

    I am also facing the same issue in ver. 1.9. Pls share the solution. I in a terrible problem.

    Thank You.

    Reply
  20. Hemden
    March 5, 2016 at 7:21 am /

    We are on Magento 1.9.2.4>

    Is this fix still necessary?

    Reply
  21. Hans Peter
    Hans Peter
    March 9, 2016 at 2:08 am /

    Has someone a working code for magento 1.9.x?
    Or did this code do the job?

    Reply

Add a Comment & Join the Discussion

Insert small snippets of code by using [code]{your_code_here}[/code]
For larger code blocks please use http://pastebin.com and paste your link.

You may also use the following HTML in your comment: <a href="" title=""> <abbr title="">
<acronym title=""> <blockquote cite=""> <cite> <em> <strike> <strong>