Search code examples
phpwordpresswoocommercecartvolume

Disable Add to cart button when cart calculated volume limit is reached in woocommerce


Is there a technical way to disable the add to cart button in woocommerce when the combined values of a custom field reach a specified value.

I am using the code below to calculate the total value of the custom field _item_volume and want to disable the add to cart button function when the value reaches 68.

add_action('woocommerce_before_calculate_totals', 'display_custom_notice', 50, 1);
function display_custom_notice( $cart ) {
    if ( is_admin() && !defined('DOING_AJAX') )
        return;
    $total_volume = 0;

    // Loop through cart items and calculate total volume
    foreach( WC()->cart->get_cart() as $cart_item ){
        $product_volume = (float) get_post_meta( $cart_item['product_id'], 
    '_item_volume', true );
        $total_volume  += $product_volume * $cart_item['quantity'];
    }
    if( $total_volume > 68 && $total_volume != 0 ){
        // Display a custom notice
        wc_add_notice( __("Note: Your order total volume has reached 68 m3", 
    "woocommerce"), 'notice' );
    }
}

Solution

  • Try the following:

    // Utility function
    function get_total_volume(){
        $total_volume = 0;
    
        // Loop through cart items and calculate total volume
        foreach( WC()->cart->get_cart() as $cart_item ){
            $product_volume = (float) get_post_meta( $cart_item['product_id'], '_item_volume', true );
            $total_volume  += $product_volume * $cart_item['quantity'];
        }
        return $total_volume;
    }
    
    // Replacing the button add to cart by a link to the product in Shop and archives pages
    add_filter( 'woocommerce_loop_add_to_cart_link', 'replace_loop_add_to_cart_button', 10, 2 );
    function replace_loop_add_to_cart_button( $button, $product  ) {
    
        if( get_total_volume() > 68 ){
            $button_text = __( "View product", "woocommerce" );
            $button = '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
        }
    
        return $button;
    }
    
    add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_button', 1 );
    function remove_add_to_cart_button() {
        // Only when total volume is up to 68
        if( get_total_volume() <= 68 ) return;
    
        global $product;
    
        // For variable product types (keeping attribute select fields)
        if( $product->is_type( 'variable' ) ) {
            remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
            add_action( 'woocommerce_single_product_summary', 'innactive_add_to_cart_button', 20 );
        }
        // For all other product types
        else {
            remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
            add_action( 'woocommerce_single_product_summary', 'innactive_add_to_cart_button', 30 );
        }
    }
    
    
    
    // Utility function: displays a custom innactive add to cart button replacement
    function innactive_add_to_cart_button(){
        global $product;
    
        $style = 'style="color:#fff;cursor:not-allowed;background-color:#999;"';
    
        echo '<a class="button" '.$style.'>' . __ ( 'Max volume reached', 'woocommerce' ) . '</a>';
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.