2

I want to show price for a product(s) for different role in woocommerce. for this goal I set a meta_key with meta value of price in post meta for product through an input field. then I use following code to filter the shown price for that product for the desired role. the role is customer_2

eg: for product_A regular price is $200 for customer_2 show $150 and the product_B regular price is $350 for customer_2 show $200 and so on...

function custom_price($price, $product){
$product_co_price = get_post_meta($product->ID, '_co_price');
$user = wp_get_current_user();
if($product_co_price){
    if(in_array('customer_2', (array) $user->roles)){
        $price = $product_co_price;
    }
}
return $price;}
add_filter('woocommerce_product_get_price', 'custom_price', 10, 2);
add_filter('woocommerce_product_variation_get_price', 'custom_price', 10, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'custom_price', 10, 2 );
add_filter( 'woocommerce_product_get_sale_price', 'custom_price', 10, 2 );

'_co_price' in meta key that store meta value of price.

But nothing happen!

Vincenzo Di Gaetano
  • 3,892
  • 3
  • 13
  • 32
Web Design
  • 77
  • 2
  • 19

1 Answers1

6

There are only two small errors in your function:

In the following line you access the $product->ID property incorrectly. You should use the $product->get_id() method:

$product_co_price = get_post_meta($product->ID, '_co_price');

Furthermore, if in the get_post_meta() function you do not value the third parameter with true you will be returned an error because in the following lines you will make a comparison between the current price (string) and the price obtained from the custom meta (array). For more information:

So the correct function will be:

// shows a customized price based on the user role
add_filter( 'woocommerce_product_get_price', 'custom_price', 10, 2);
add_filter( 'woocommerce_product_variation_get_price', 'custom_price', 10, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'custom_price', 10, 2 );
add_filter( 'woocommerce_product_get_sale_price', 'custom_price', 10, 2 );
function custom_price( $price, $product ) {

    // if the user is not logged in or has a role other than "customer_2", it shows the default price of the product
    $user = wp_get_current_user();
    if ( ! in_array( 'customer_2', (array) $user->roles ) ) {
        return $price;
    }

    // gets the price to display for the user role "customer_2"
    $co_price = get_post_meta( $product->get_id(), '_co_price', true );

    // if the custom meta is not set or is empty or equal to zero it shows the default price
    if ( ! isset( $co_price ) || empty( $co_price ) || $co_price == 0 ) {
        return $price;
    // otherwise it shows the custom price
    } else {
        return $co_price;
    }

    return $price;
}

If you show the price range on the variable product page you will need to change the logic considering the custom meta product _co_price.

So you will need to use:

// shows the price range of the variable product based on the price of the custom meta "_co_price" of each single variation
add_filter( 'woocommerce_variable_price_html', 'show_price_range_based_on_custom_meta_price', 99, 2 );
function show_price_range_based_on_custom_meta_price( $price, $product ) {

    // initializes the array which will contain all variation prices
    $prices = array();

    $variation_ids = $product->get_children();
    foreach ( $variation_ids as $variation_id ) {
        $variation = wc_get_product( $variation_id );
        // gets the net default price
        $prices[] = $variation->get_price();
        // gets the price from the custom meta product
        $co_price = $variation->get_meta( '_co_price', true );
        // replaces the comma with the period to make it numeric
        $co_price = str_replace( ',', '.', $co_price );
        $prices[] = $co_price;
    }

    // removes empty values from the array
    $prices = array_filter($prices);
    // gets the minimum value from the array
    $min_price = min( $prices );
    // gets the maximum value from the array
    $max_price = max( $prices );

    if ( $min_price == $max_price ) {
        $price = wc_price( $min_price );
    } else {
        $price = wc_format_price_range( $min_price, $max_price );
    }
    
    return $price;
}

The code has been tested and works. Add it to your active theme's functions.php.

Vincenzo Di Gaetano
  • 3,892
  • 3
  • 13
  • 32