Search code examples
phpwordpresswoocommercecarthook-woocommerce

Add or remove a free product based on WooCommerce cart total and month range


I am on a project, which needs to add to cart a free item on particular promotional month. Therefore, I need to make the product value 0.00 and add it automatically to cart in a particular promotional month. So far, I have added the product automatically when the add to cart total reaches certain amount

/*
 * Automatically adding the product to the cart when cart total amount reach to $500.
 */

function aapc_add_product_to_cart() {
    global $woocommerce;
    
    $cart_total = 500;  

    if ( $woocommerce->cart->total >= $cart_total ) {
        if ( ! is_admin() ) {
            $free_product_id = 12989;  // Product Id of the free product which will get added to cart
            $found      = false;

            //check if product already in cart
            if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
                foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
                    $_product = $values['data'];
                    if ( $_product->get_id() == $free_product_id )
                        $found = true;                  
                }
                // if product not found, add it
                if ( ! $found )
                    WC()->cart->add_to_cart( $free_product_id );
            } else {
                // if no products in cart, add it
                WC()->cart->add_to_cart( $free_product_id );
            }        
        }
    }        
}

add_action( 'template_redirect', 'aapc_add_product_to_cart' );
...

Solution

  • Try the following instead (that handle dynamic changes in cart page and also a month range).

    Note: the total amount for the threshold can be only the cart items total.

    The code:

    function is_free_product_allowed_for_month() {
        // Define allowed months in the array (values from 1 to 12)
        $allowed_months   = array('3', '7', '8');
    
        return in_array( date('n'), $allowed_months );
    }
    
    
    add_action( 'woocommerce_before_calculate_totals', 'add_remove_free_product' );
    function add_remove_free_product( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        // Check if we are in an allowed month
        if ( ! is_free_product_allowed_for_month() )
            return;
    
        $free_product_id  = 339; // ID of the free product
        $threshold_amount = 200; // The threshold amount for cart subtotal
        $cart_items_total = 0; // Initializing
    
        // Loop through cart items
        foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
            // Check if the free product is in cart
            if ( in_array( $free_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
                $cart_item['data']->set_price(0); // Set price to Zero
                $free_item_key = $cart_item_key;
    
            }
            // Get cart subtotal incl. tax from items (with discounts if any)
            $cart_items_total += $cart_item['line_total'] + $cart_item['line_tax'];
        }
    
        // If Cart total is up to the defined amount and if the free products is not in cart, we add it.
        if ( $cart_items_total >= $threshold_amount && ! isset($free_item_key) ) {
            $cart->add_to_cart( $free_product_id );
        }
        // If cart total is below the defined amount and free product is in cart, we remove it.
        elseif ( $cart_items_total < $threshold_amount && isset($free_item_key) ) {
            $cart->remove_cart_item( $free_item_key );
        }
    }
    
    
    // For minicart displayed free product price
    add_filter( 'woocommerce_cart_item_price', 'free_product_cart_item_price', 10, 3 );
    function free_product_cart_item_price( $price_html, $cart_item, $cart_item_key ) {
        // Check if we are in an allowed month
        if ( ! is_free_product_allowed_for_month() )
            return $price_html;
    
        $free_product_id  = 339; // ID of the free product
    
        if ( in_array( $free_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
            return wc_price( 0 );
        }
        return $price_html;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). It should work.

    Related: Add or remove specific cart Item based on WooCommerce cart total