Search code examples
phpwordpresswoocommerceproductwoocommerce-bookings

Conditionally alter specific product price in Woocommerce


I would like to alter a specific product in Woocommerce, adding programmatically to its original an amount of $10, EXCEPT in those cases:

  • On specific product pages that are bookable products for hire (Woocommerce Bookings) that belongs to a certain Category "C".
  • If any cart item belongs to that category "C".

I was using this answer code to one of my questions until now. But I should need to display this specific product altered price everywhere except on that product pages that are bookable products, in front end.

I have also this code that displays the Force Sells price beside the titles. This should still show the specific product original price on that product pages that are bookable products in the Force Sells section:

function wc_forcesells_product_price( $name, $product ) {
    // Only in single product pages
    if( ! is_product() ) return $name;

    // The product name + the product formatted price
    return $name . ' (' . wc_price( wc_get_price_to_display( $product ) ) . ')';
}
add_filter( 'woocommerce_product_title', 'wc_forcesells_product_price', 20, 2 );

Reference for above: Add price beside Woocommerce Force Sells.


Solution

  • Updated to handle multiple product Ids if necessary

    Try the following that will display for a specific product ID a custom price everywhere except:

    • On booking products to hire pages
    • When a product category is in cart

    The code will also change this custom product price in cart items except when a specific product category is in cart items.

    You will have to set in those functions:

    • This specific product ID
    • The booking products IDs to hire
    • The Additional price amount
    • The product category (Id slug or name)

    The code:

    // Change product ID 87 price everywhere on front end EXCEPT:
    // - On booking products to hire pages
    // - When a product category is in cart
    add_filter( 'woocommerce_get_price_html', 'product_id_87_displayed_price', 10, 2 );
    function product_id_87_displayed_price( $price_html, $product ) {
        // Only for product ID 87
        if( in_array( $product->get_id(), array( 87, 2799 ) ) ){ 
            return $price_html; // Exit
    
        // HERE set booking products IDs to hire in the array
        $product_ids_to_hire = array( 53, 738 );
    
        // HERE set your product category term ID, slug or name
        $product_category = 'hoodies';
    
        // HERE set the price additional amount
        $addp = 10;
    
        // EXCEPT on booking products to hire pages
        if( is_single($product_ids_to_hire) ) return $price_html; // Exit
    
        // Checking for the product category in cart items loop
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            if ( has_term( $product_category, 'product_cat', $cart_item['product_id'] ) )
                 return $price_html; // Product category found ==> Exit
        }
    
        if ( '' !== $product->get_price() && ! $product->is_on_sale() ) {
            $price_html = wc_price( wc_get_price_to_display( $product ) + $addp ) . $product->get_price_suffix();
        }
        return $price_html;
    }
    
    // Add custom calculated price to cart item data for product ID 87
    add_filter( 'woocommerce_add_cart_item_data', 'add_cart_simple_product_custom_price', 20, 2 );
    function add_cart_simple_product_custom_price( $cart_item_data, $product_id ){
        // Only for product ID 87
        if( ! in_array( $product->get_id(), array( 87 ) ) ) 
            return $cart_item_data; // Exit
    
        // HERE set the price additional amount
        $addp = 10;
    
        $product = wc_get_product($product_id); // The WC_Product Object
        $price   = (float) $product->get_price(); // The product price
    
        // Set the custom amount in cart object
        $cart_item_data['new_price'] = $price + $addp;
    
        return $cart_item_data;
    }
    
    // Set custom calculated price to cart for product ID 87
    add_action( 'woocommerce_before_calculate_totals', 'set_cart_simple_product_custom_price', 20, 1 );
    function set_cart_simple_product_custom_price( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        // HERE set your product category term ID, slug or name
        $product_category = 'hoodies';
    
        // 1st cart items Loop: checking for the product category
        foreach ( $cart->get_cart() as $cart_item ) {
            if ( has_term( $product_category, 'product_cat', $cart_item['product_id'] ) )
                return; // Product category found ==> We EXIT from this function
        }
    
        // 2nd Loop: Changing cart item prices (Product category not found)
        foreach ( $cart->get_cart() as $cart_item ) {
            if( isset($cart_item['new_price']))
                $cart_item['data']->set_price( $cart_item['new_price'] );
        }
    }
    

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

    It should also work with your wc_forcesells_product_price() function.