3

I am trying to automatically apply coupons in my WooCommerce store based on product ID and quantity conditions. My end goal is for a particular coupon to apply automatically when TWO (2) of the desired products are added to the cart, and for another coupon to app,y automatically whenever THREE (3) of the desired products are added to the cart. A single quantity of the product should have no discount. The following is the CORRECTED version of the code, which now works:

add_action( 'woocommerce_before_cart', 'conditional_auto_add_coupons' );
function conditional_auto_add_coupons() {

if ( !WC()->cart->is_empty() ){

    // Define HERE your Targeted Product ID and coupons codes
    $target_pid = 103;
    $coupon1 = 'soccer-sibling-2';
    $coupon2 = 'soccer-sibling-3';

    // First cart loop: Counting number of subactegory items in cart
    foreach ( WC()->cart->get_cart() as $cart_item ){
        if( $target_pid == $cart_item['data']->id ){
            // Removes any coupons in the cart already
            WC()->cart->remove_coupons();
            if( 2 == WC()->cart->get_cart_contents_count() && !WC()->cart->has_discount( $coupon1 ) ){
                WC()->cart->remove_coupons();
                WC()->cart->add_discount( $coupon1 );
                wc_add_notice( __( 'The multiple sibling discount has been applied.', 'theme_domain' ), 'success' );
            } elseif( 3 == WC()->cart->get_cart_contents_count() && !WC()->cart->has_discount( $coupon2 ) ){
               WC()->cart->remove_coupons();
                WC()->cart->add_discount( $coupon2 );
                wc_add_notice( __( 'The multiple sibling discount has been applied.', 'theme_domain' ), 'success' );
            }
            // Recalculates Cart Totals to show correct price
            WC()->cart->calculate_totals();
        }
     }
  }
}
GDailey
  • 71
  • 11
  • What error message are you getting? – Obsidian Age Jan 24 '17 at 01:36
  • Well, I noticed there was a syntax error in my pasted code. Corrected that. The error I get when I debug is "Notice: Trying to get property of non-object in /home/...functions.php on line 333". The line in question is the conditional 'if ($_product->id == $product_id )' – GDailey Jan 24 '17 at 04:42

2 Answers2

2

Theres is a lot of errors in your code and it's a little obsolete too... I have rewrite everithing in your function and hooked it in another hook.

Here is your revisited code:

add_action( 'woocommerce_before_cart', 'conditional_auto_add_coupons' );
function conditional_auto_add_coupons() {

    if ( !WC()->cart->is_empty() ){

        // Define HERE your Targeted Product ID and coupons codes
        $target_pid = 103;
        $coupon1 = 'soccer-sibling-2';
        $coupon2 = 'soccer-sibling-3';

        // First cart loop: Counting number of subactegory items in cart
        foreach ( WC()->cart->get_cart() as $cart_item ){
            if( $target_pid == $cart_item['data']->id ){
                if( 2 == WC()->cart->get_cart_contents_count() && !WC()->cart->has_discount( $coupon1 ) ){
                    WC()->cart->add_discount( $coupon1 );
                    wc_add_notice( __( 'A quantity discount of <strong>5%</strong> has been added.', 'theme_domain' ), 'success' );
                } elseif( 3 == WC()->cart->get_cart_contents_count() && !WC()->cart->has_discount( $coupon2 ) ){
                    WC()->cart->add_discount( $coupon2 );
                    wc_add_notice( __( 'A quantity discount of <strong>10%</strong> has been added.', 'theme_domain' ), 'success' );
                }
            }
        }
    }
}

This code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This should work and will not make your website crash, but I haven't really test it, as this is very particular.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Your code worked well. I added two small lines to it to correct one problem: whenever I changed the quantity from the cart, it would apply the second discount but not remove the first. If I reduced the quantity to ONE, then it would keep whatever discounts were applied. I added to lines to your code to remove discounts added BEFORE applying the desired auto-coupon, and then another to recalculate totals so the correct amount displayed on the cart page. I've added your code with my additions to the original post. Thanks! – GDailey Jan 24 '17 at 19:28
0

Coming back here a few years later: I found a loophole that caused an issue. Because the function was counting the total cart contents, rather than just the quantity of the product the coupon is applied to, customers could exploit this to add non-coupon related products to get the additional coupons for the discounted product. The following code closes the loophole by checking the quantity of just the product in question:

add_action( 'woocommerce_before_cart',    'conditional_auto_add_coupons_tourney' );
function conditional_auto_add_coupons_tourney() {

if ( !WC()->cart->is_empty() ){

    // Define HERE your Targeted Product ID and coupons codes
    $target_pid = 96;
    $coupon1 = 'multiple-25';
    $coupon2 = 'multiple-50';
    
    // UPDATE: switched WC()->cart->get_cart_contents_count() for $quantity on 236 and 240

    // First cart loop: Counting number of subcategory items in cart
    foreach ( WC()->cart->get_cart() as $cart_item ){
        if( $target_pid == $cart_item['product_id'] ){
          WC()->cart->remove_coupons();
          $quantity = $cart_item['quantity']; // Added to find quantity of specific product
            if( 5 <= $quantity && !WC()->cart->has_discount( $coupon2 ) ){
               WC()->cart->remove_coupons();
                WC()->cart->add_discount( $coupon2 );
                wc_add_notice( __( 'The multiple team discount has been applied.', 'theme_domain' ), 'success' );
            } elseif( 2 <= $quantity && !WC()->cart->has_discount( $coupon1 ) ){
                WC()->cart->remove_coupons();
                WC()->cart->add_discount( $coupon1 );
                wc_add_notice( __( 'The multiple team discount has been applied.', 'theme_domain' ), 'success' );
            } 
    WC()->cart->calculate_totals();
        }
    }
}

}

GDailey
  • 71
  • 11