Support » Plugin: WooCommerce » Current Release 3.4.5 BREAKS Coupons

  • Resolved walkinverse

    (@walkinverse)


    The most current woocommerce updates broke the coupons. Do not upgrade until they fix this. To replicate the error place two items in the cart. One that is on sale and one that is not, and then set your coupon not to include sales items. Woo will not allow you to use the coupon with the item that is not on sale. Instead, it will remove the coupon and state the coupon cannot be used on a sale item even when one of the items in the cart is not a sale item. I rolled back the plugin to 3.44, and the error goes away. If I update back to 3.4.5, it breaks. I tested this on three sites with the same issue on all with the new version of woo.

Viewing 15 replies - 1 through 15 (of 19 total)
  • Plugin Support Rynald0s

    (@rynald0s)

    Automattic Happiness Engineer

    hi, @walkinverse!

    We’ve corrected the sale coupon restriction logic, which you’ll find the PRs for here https://github.com/woocommerce/woocommerce/pull/21219

    What you are experiencing here is not a bug. If you do, however, feel that this is, then you’re welcome to open a new Github bug report here: https://github.com/woocommerce/woocommerce/issues/new/choose

    Cheers!

    Plugin Support Rynald0s

    (@rynald0s)

    Automattic Happiness Engineer

    Howdy!

    I’ve also had a closer look at this:

    It is not possible to restrict to a product anymore. There can’t be typed into the fields when creating a coupon

    .. and it isn’t something I could replicate this on a clean v3.4.5 install with no other plugins, and only using Storefront v2.3.3 theme

    Please open your console as per: https://codex.wordpress.org/Using_Your_Browser_to_Diagnose_JavaScript_Errors

    .. and look for any Javascript errors when trying to add products in those fields

    Once that’s done, paste the results back here so we can take a closer look, thanks!

    Cheers!

    @rynald0s I am curious, how is it suppose to work? If a customer wants to buy two items. One item is on sale, and one item is not, and they add both to the cart shouldn’t the one that is not on sale take the discount when you set the coupon to only be able to be used on items that are not on sale?

    Shouldn’t the nonsale item get the 20% discount? Currently, if any item that is on sale in the cart with a non-sale item, the coupon is automatically removed and cannot be used.

    How can I test this fix? Will an update be available as 3.4.6?

    Thank you for your response.

    • This reply was modified 7 months, 3 weeks ago by  walkinverse.

    @rynald0s One more note here is a video screencast of the what is happening. It looks like it should not behave this way.

    https://www.dropbox.com/s/vikywyz8945z804/Recording%20%2332.mp4?dl=0

    You said you fixed this: Coupon validation changes #21219 But it is not fixed as you cannot apply a coupon to this change. Please watch the screencast. What am I missing?

    • This reply was modified 7 months, 3 weeks ago by  walkinverse.

    @rynald0s The issue is with the foreach as you are not checking the next. As soon as you see an item on sale you are exiting the code (BREAK). That is a bug in the logic. What needs to happen is to check all the items in the cart before breaking out because you never get to the second item if the first hit in the loop is flagged as a sale item. Hence, this is a bug.

    /**
    	 * Ensure coupon is valid for sale items in the list is valid or throw exception.
    	 *
    	 * @since  3.2.0
    	 * @throws Exception Error message.
    	 * @param  WC_Coupon $coupon Coupon data.
    	 * @return bool
    	 */
    	protected function validate_coupon_sale_items( $coupon ) {
    		if ( $coupon->get_exclude_sale_items() && 'fixed_product' !== $coupon->get_discount_type() ) {
    			$valid = true;
    
    			foreach ( $this->get_items_to_validate() as $item ) {
    				<strong>if ( $item->product && $item->product->is_on_sale() )</strong> {
    					$valid = false;
    					break;
    				}
    			}
    
    			if ( ! $valid ) {
    				throw new Exception( __( 'Sorry, this coupon is not valid for sale items.', 'woocommerce' ), 110 );
    			}
    		}
    
    		return true;
    	}
    • This reply was modified 7 months, 3 weeks ago by  walkinverse.
    Plugin Support Rynald0s

    (@rynald0s)

    Automattic Happiness Engineer

    Hi, @walkinverse!

    Ah, you’re right!

    Also, thanks a bunch for digging into this further and finding the root

    I’ll go ahead and open a bug report in Github, where I’ll add this information πŸ™‚

    Please hang tight for the link where you can follow along

    Cheers!

    @rynald0s No worries πŸ™‚

    I actually fired up a docker instance and started to var_dump and print_r to trace it and make sure I wasn’t missing something. It is definitely in the foreach. It is exiting without first checking all the items in the cart.

    Thank you again and you are more than welcome!

    Plugin Support Rynald0s

    (@rynald0s)

    Automattic Happiness Engineer

    Hi, @walkinverse!

    You can follow along here: https://github.com/woocommerce/woocommerce/issues/21226

    Thanks again for bringing this to our attention!

    I’m going to mark this thread as “resolved” in favor of the open GH issue ^

    You’re welcome to add to the issue there if need be πŸ™‚

    Have a fantastic day further!

    @rynald0s Thank you so much. This might help with the fix. Have not tested thoroughly, but run it a few time on the test site.

    
    $total_items = count($this->get_items_to_validate());
    $item_count = 1;
    foreach ( $this->get_items_to_validate() as $item ) {
    	if ( $item->product && $item->product->is_on_sale() ) {
    		if($item_count > $total_items) {
    			$valid = false;
    			break;
    		}
    	}
    	$item_count++;
    }
    
    • This reply was modified 7 months, 3 weeks ago by  walkinverse.
    • This reply was modified 7 months, 3 weeks ago by  walkinverse.
    Plugin Author Claudiu Lodromanean

    (@claudiulodro)

    Hi @walkinverse,

    The new behavior is actually the correct behavior.

    The fact that percent discount and fixed cart coupons were allowed with mixed sale/non-sale items in the cart was a bug in the previous version of WooCommerce. You can see that the description of the checkbox to restrict coupons when items are on sale says: “Per-cart coupons will only work if there are items in the cart that are not on sale.”, and this matches the current behavior.

    Hope this clears things up.

    Thanks.

    @claudiulodro The item in the cart is a sale item (coupon should not work for that one) and a non sale item (the coupon should work for that one). It is NOT a fix cart coupon but a percent coupon. It is broken. Watch the video. Before the 3.4.5 update, everything works. 3.4.5 breaks, 3.4.4 works. This was not set to fixed cart. The coupon should take for the non sale item. The sale item the coupon should not work. So that is not right. If you give someone a coupon for 10% off on a non sale item and they add both a non sale item and the same item, the coupon should work on the cart for the non sale item only and not apply to the sale item. As of 3.4.5 it breaks and the coupon does not allow anything to pass through. You foreach loop disregards once it hits a sale item and breaks and flags the variable to escape. That is not correct. That is not the correct behavior. Watch the video and you will see what I am referring to. It is broken. Again, watch the video. Two items are added. 1 was on sale, 1 is not. The customer adds a coupon that is set to X % off and to ignore sale items. The coupon shoudl only work for the item that is not on sale. but your logic ignores all regardless. THIS IS NOT CORRECT.

    Plugin Author Claudiu Lodromanean

    (@claudiulodro)

    My apologies. It does seem that the percentage discount coupon has not been a fixed cart discount since WC 3.0 (it should now be a per product discount). The logic will be updated in the next WC version to allow mixed sale/non-sale items with percentage discount coupons. Thanks.

    @claudiulodro IN case I am not making sense, the issue with the coupon is that you can add a non-sale item and a sale item. You have a coupon set to percentage and to ignore on sale items and only allow it to be used with 1 item in the cart. In 3.4.4 no issue, everything works are expected. 3.4.5 it does not. Currently (3.4.5) if you try to apply the coupon it kicks out and will not work on the non-sale item. If you remove the sale item and try again the coupon works. You add the sale item back to the cart with the non- sale item it throws an error saying coupon cannot be used, which is incorrect. Please see the video. 3.4.4 is normal behavior, 3.4.5 is not.

    https://www.dropbox.com/s/vikywyz8945z804/Recording%20%2332.mp4?dl=0

    In the foreach loop it does not consider all the items in the cart. It kicks out as soon as it sees an item flagged as on sale. It should first make sure that one of the items are valid for coupon use.

    Function: protected function validate_coupon_sale_items( $coupon )

    Look at the foreach loop in this code and you will see the logic that is causing it. If you first got the count then had a tracking count that each time you hit a sale item increment by 1. Then at the end of the foreach if those numbers do not match then that means one item was valid for coupon use. If both numbers matched the that implies all items are on sale items.

    Example:

    $total_items = count(items);
    $onsale_item = 0;
    
    foreach(items as $item)
      if($item->onsale)
          $onsale_item++;
    
    if($onsale_item != $total_items)
      coupon can be used
    else
      all items in the cart are on sale.

    I hope this helps. Thank you again.

    • This reply was modified 7 months, 3 weeks ago by  walkinverse.

    This is a serious issue for any webshop. Why will this first be addressed in the next update, and when is that update happening?

    You can revert back to 3.4.4 in the meantime.

Viewing 15 replies - 1 through 15 (of 19 total)
  • The topic ‘Current Release 3.4.5 BREAKS Coupons’ is closed to new replies.