Search code examples
phpwordpresswoocommercecart

Set cart item product generated sale price only for specific products in Woocommerce


Following Set only specific products sale price programmatically in WooCommerce 3, the related cart items price are not updated with the product's generated sale price.

How can I get the generated sale price for specific products, in the related cart items?

Any help is appreciated.


Solution

  • To get the right generated sale price in cart item for specific product IDs try the following:

    // HERE below in the array set your specific product IDs
    function specific_product_ids(){
        return array(37, 41); //  <===  <===  <===  <===  Your Product IDs
    }
    
    // Generating dynamically the product "regular price"
    add_filter( 'woocommerce_product_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
    add_filter( 'woocommerce_product_variation_get_regular_price', 'custom_dynamic_regular_price', 10, 2 );
    function custom_dynamic_regular_price( $regular_price, $product ) {
        if( ( empty($regular_price) || $regular_price == 0 ) && in_array($product->get_id(), specific_product_ids() ) )
            return $product->get_price();
        else
            return $regular_price;
    }
    
    
    // Generating dynamically the product "sale price"
    add_filter( 'woocommerce_product_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
    add_filter( 'woocommerce_product_variation_get_sale_price', 'custom_dynamic_sale_price', 10, 2 );
    function custom_dynamic_sale_price( $sale_price, $product ) {
        $rate = 0.8;
        if( ( empty($regular_price) || $regular_price == 0 ) && in_array($product->get_id(), specific_product_ids() ) )
            return $product->get_regular_price() * $rate;
        else
            return $sale_price;
    };
    
    // Displayed formatted regular price + sale price
    add_filter( 'woocommerce_get_price_html', 'custom_dynamic_sale_price_html', 20, 2 );
    function custom_dynamic_sale_price_html( $price_html, $product ) {
        if( $product->is_type('variable') ) return $price_html;
    
        if( in_array($product->get_id(), specific_product_ids() ) ) {
            $price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), wc_get_price_to_display(  $product, array( 'price' => $product->get_sale_price() ) ) ) . $product->get_price_suffix();
        }
        return $price_html;
    }
    
    // Set cart item generated "sale price" for specific product IDs
    add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 10, 1 );
    function set_cart_item_sale_price( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        // Iterate through each cart item
        foreach( $cart->get_cart() as $cart_item ) {
            if( in_array($cart_item['data']->get_id(), specific_product_ids() ) ) {
                $price = $cart_item['data']->get_sale_price(); // get sale price
                $cart_item['data']->set_price( $price ); // Set the sale price
            }
        }
    }
    

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