1
votes

In Woocommerce I have a variable products with some variations and some variation has its own REGULAR price and SALE price.

Also I have three types of users with separated prices:

  1. Regular Customer,
  2. Wholesaler-1,
  3. Wholesaler-2.

I would like when user:

  • is logged in,
    • Customer: the sale price will be the active price but also show the regular price.
    • Wholesaler 1 and 2: the custom price will be the active price but also show the regular price.
  • is not logged in, the regular price will be the active price.

Inspired mainly by Enable Wholesale prices in Woocommerce 3 answer code, here is my code attempt:

// Add custom field to VARIATIONS option pricing
add_action( 'woocommerce_variation_options_pricing', 'w4dev_add_variation_options_pricing', 20, 3 );
function w4dev_add_variation_options_pricing( $loop, $variation_data, $post_variation )
{
    $value1  = get_post_meta( $post_variation->ID, '_wholesale_price_1', true );
    $value2  = get_post_meta( $post_variation->ID, '_wholesale_price_2', true );

    $symbol = ' (' . get_woocommerce_currency_symbol() . ')';
    $key_1 = '_wholesale_price_1[' . $loop . ']';
    $key_2 = '_wholesale_price_2[' . $loop . ']';

    
    echo '<div class="variable_wholesale-price"><p class="form-row form-row-first">
        <label>' . __( "Big Dealer Price", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_1 .'" value="' . esc_attr( $value1 ) . '" />
    </p></div>';

    echo '<div class="variable_wholesale-price"><p class="form-row form-row-first">
        <label>' . __( "Small Dealer Price", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_2 .'" value="' . esc_attr( $value2 ) . '" />
    </p></div>';
}


// Save "Wholesale Price" custom field to VARIATIONS
add_action( 'woocommerce_save_product_variation', 'w4dev_save_product_variation_wholesale_price', 20, 2 );
function w4dev_save_product_variation_wholesale_price( $variation_id, $i )
{
    if ( isset( $_POST['_wholesale_price_1'][$i] ) ) 
    {
        update_post_meta( $variation_id, '_wholesale_price_1', floatval( $_POST['_wholesale_price_1'][$i] ) );
    }
    
    if ( isset( $_POST['_wholesale_price_2'][$i] ) ) 
    {
        update_post_meta( $variation_id, '_wholesale_price_2', floatval( $_POST['_wholesale_price_2'][$i] ) );
    }
}


// Variable product price range
add_filter('woocommerce_variation_prices_price', 'w4dev_custom_variation_price', 90, 3 );
add_filter('woocommerce_variation_prices_regular_price', 'w4dev_custom_variation_price', 90, 3 );

add_filter('woocommerce_product_variation_get_regular_price', 'w4dev_custom_price', 90, 2 );
add_filter('woocommerce_product_variation_get_price', 'w4dev_custom_price', 90, 2 );;

function w4dev_custom_variation_price( $price, $variation, $product ) 
{
    if (is_user_logged_in()) 
    {
        $level = get_user_meta(get_current_user_id(), 'wholesale_level', true);
        switch ($level) 
        {
            case 1: $key = '_wholesale_price_1'; break;
            case 2: $key = '_wholesale_price_2'; break;
            default:

                if( get_post_meta( $variation->get_id(), '$key', true ) )
                $price = get_post_meta( $variation->get_id(), '$key', true );
        }
    }
    else
    {   
        return $price;
    }

    return get_post_meta($variation->get_id(), $key, true);
 }

This is showing only regular and sale price instead of users specific prices.

1
After login regular and sale prices are showing but want to show wholesale prices according to user. – mohit

1 Answers

0
votes

You need to set the customer sale price as a custom price in your case, so that means adding an additional custom field in the product… Also that means that you will not use WooCommerce Sale price and you will keep it empty on your product variations. This will allow you to display:

  • for non logged users: The default WooCommerce regular price
  • for logged in customers: A custom sale price (with the regular price strikethrough)
  • for Wholesale users: A custom wholesale price (with the regular price strikethrough)

To finish variable price range are cached so you need some additional code to make it work, without killing your website performances.

The code:

// Add custom fields to variations option pricing
add_action( 'woocommerce_variation_options_pricing', 'add_variation_wholesale_options_pricing', 20, 3 );
function add_variation_wholesale_options_pricing( $loop, $variation_data, $post_variation )
{
    $value1  = get_post_meta( $post_variation->ID, '_wholesale_price_1', true );
    $value2  = get_post_meta( $post_variation->ID, '_wholesale_price_2', true );
    $value3  = get_post_meta( $post_variation->ID, '_customer_price', true );

    $symbol = ' (' . get_woocommerce_currency_symbol() . ')';

    $key_1 = '_wholesale_price_1[' . $loop . ']';
    $key_2 = '_wholesale_price_2[' . $loop . ']';
    $key_3 = '_customer_price[' . $loop . ']';

    // Customer price (will be the sale price)
    echo '<div class="variable_customer-price"><p class="form-row form-row-first">
        <label>' . __( "Customer Price", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_3 .'" value="' . esc_attr( $valu3 ) . '" />
    </p></div>';

    // Wholesale 1 price
    echo '<div class="variable_wholesale-price"><p class="form-row form-row-first">
        <label>' . __( "Big Dealer Price", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_1 .'" value="' . esc_attr( $value1 ) . '" />
    </p></div>';

    // Wholesale 2 price
    echo '<div class="variable_wholesale-price"><p class="form-row form-row-first">
        <label>' . __( "Small Dealer Price", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_2 .'" value="' . esc_attr( $value2 ) . '" />
    </p></div>';
}


// Save variations wholesale prices custom fields values
add_action( 'woocommerce_save_product_variation', 'save_product_variation_wholesale_price', 20, 2 );
function save_product_variation_wholesale_price( $variation_id, $i )
{
    if ( isset( $_POST['_wholesale_price_1'][$i] ) )
    {
        update_post_meta( $variation_id, '_wholesale_price_1', floatval( $_POST['_wholesale_price_1'][$i] ) );
    }

    if ( isset( $_POST['_wholesale_price_2'][$i] ) )
    {
        update_post_meta( $variation_id, '_wholesale_price_2', floatval( $_POST['_wholesale_price_2'][$i] ) );
    }

    if ( isset( $_POST['_customer_price'][$i] ) )
    {
        update_post_meta( $variation_id, '_customer_price', floatval( $_POST['_customer_price'][$i] ) );
    }
}

// Variable product price ramge
add_filter('woocommerce_variation_prices_price', 'wholesale_variation_price', 900, 2 );
add_filter('woocommerce_variation_prices_sale_price', 'wholesale_variation_price', 900, 2 );

// Product variations (of a variable product)
add_filter('woocommerce_product_variation_get_price', 'wholesale_variation_price', 900, 2 );
add_filter('woocommerce_product_variation_get_sale_price', 'wholesale_variation_price', 900, 2 );
function wholesale_variation_price( $price, $object )
{
    if ( is_user_logged_in() ) {
        $level = (int) get_user_meta( get_current_user_id(), 'wholesale_level', true );
        // For Wholesale user levels 1 and 2
        if( in_array($level, [1, 2]) ) {
            $new_price = (float) get_post_meta( $object->get_id(), '_wholesale_price_' . $level, true );
            $price     = empty($new_price) ? $price : $new_price;
        }
        // For customers
        else {
            $new_price = (float) get_post_meta( $object->get_id(), '_customer_price', true );
            $price     = empty($new_price) ? $price : $new_price;
        }
    }
    return $price;
}

// Handling custom variable price range caching
add_filter( 'woocommerce_get_variation_prices_hash', 'wholesale_variation_performances_caching_prices', 99, 1 );
function wholesale_variation_performances_caching_prices( $hash ) {
    if ( is_user_logged_in() ) {
        $level = (int) get_user_meta( get_current_user_id(), 'wholesale_level', true );
        // For Wholesale user levels 1 and 2
        if( in_array($level, [1, 2]) ) {
            $hash[] = 'level_' . $level;
        }
        // For customers
        else {
            $hash[] = 'level_0'; // Set the user level to zero here
        }
    }
    return $hash;
}

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

related: